Verilog语言中的赋值问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Verilog语言中的赋值问题相关的知识,希望对你有一定的参考价值。

在a变量的上升沿到来之后,再等待b的下降沿,然后才可以对c赋值
这段程序应该怎么来写
在a的上升沿到来之后,等待b的下降沿,此时a可以已经重新恢复到低电平了
二楼你那个是错的把

不知道你是要做验证还是设计,如果是验证的话,不要求可综合,可以简单写成:
always@ (posedge a)
begin
@ (negedge b)
c<=...;
end
如果要想可综合的话,需要用状态机类似的概念,
即设一个标志位,当a上升沿来是,把它赋值为1,
当它为1且b下降沿来时,给c赋值,并将它赋值回0:
并且,如果a,b不是时钟的话,不推荐使用posedge的写法
采用下面的方法比较好:

reg a_dly,b_dly; //a,b的1始终delay信号
wire a_pos,b_pos; //a,b的上升沿抓取信号
assign a_pos = a & !a_dly;
assign b_pos = b & !b_dly;
reg flag;//标志位

always@(posedge clk or posedge rst)
begin
if(rst) begin
a_pos <= 1'b0;
b_pos <= 1'b0;
end
else begin
a_pos <= a;
b_pos <= b;
end
end

always@(posedge clk or posedge rst)
begin
if(rst)
flag <= 1'b0;
else if(a_pos)
flag <= 1'b1;
else if(b_pos)
flag <= 1'b0;
end

always@(posedge clk)
begin
if(flag & b_pos)
c<=....
end
把flag赋值回为0很重要,不然逻辑有问题。

用3段状态机写就是
parameter IDLE = 2'h0;
parameter WAIT_B_POS = 2'h1;
parameter GET_C = 2'h2;

reg [1:0] cs; //current state
reg [1:0] ns; //next state

//1段 状态转换
always@(posedge clk or posedge rst)
begin
if(rst)
cs <= IDLE;
else
cs <= ns;
end
//2段 状态迁移
always@(a_pos or b_pos or cs or ns)
begin
ns = XX; //设置ns为xx
case(cs)
IDLE: begin
if(a_pos) ns = WAIT_B_POS;//用阻塞赋值
else ns = IDLE;
end
WAIT_B_POS:begin
if(b_pos) ns = GET_C;
else ns = WAIT_B_POS;
end
GET_C:begin
ns = IDLE;
end
default:;
endcase
end
//3段 赋值
always@(posedge clk or posedge rst)
begin
if(rst)
c<=1'b0;
else begin
if(ns == GET_C)
c <= .....;
end
end

用状态机写的好处就是不用加标志位了,但是个人觉得没有必要这样写。

能力有限,错误请指正
参考技术A always @ (posedge b or negedge reset)
begin
if(!reset)
c < = 1'b0;
else if(a)
c <= d; //
else
c <= c;
end

a的上升沿到来之后,还需要等待b的下降沿,应该指的是在a为高期间,且b下降沿到来时,对c进行操作。因为在等待b的下降沿到来这个过程中,a不可能一直处于上升沿
参考技术B always @ (posedge a or negedge b)
begin
if(!b)
c < = 1'b0;
else
c <= d;
end
参考技术C 方法1:
@ (posedge a)

@ (negedge b)
c..


方法2:
reg a_reg;
reg b_reg;
reg en;
wire a_pulse = a & ~a_reg;
wire b_pulse = ~b & b_reg;
wire c_en = en & b_pulse;

always @(posedge clk) begin
a_reg <= a;
b_reg <= b;
end

always @(posedge clk) begin
if(a_pulse)
en <= 1'b1;
else if(b_pulse)
en <= 1'b0;
else
en <= en;
end

always @(posedge clk) begin
if(c_en)
c...

个人觉得 ls说的不错 不过方法1中,由于lz没有说明是不是需要综合的情况下 在测试中(即理想情况下)可以直接用信号的上升沿作为判断条件
另外如果需要综合的情况 不必要状态机 回路复杂化 只需要采样就ok了 望赐教
参考技术D 怎么会有这种赋值,有什么用?

verilog设计中,当对同一个被赋值目标同时进行2次或多次赋值时,怎样来决定被赋值目标的有效值?

理论上讲for语句应该不能在除了always块之外的地方使用,所以你这个问题根本就不成立
就算是能在initial中使用的话,也应该是同时赋值的。initial块中的所有变量,只要没有加延时都应该是同时赋值的,initial语句块中的所有数据都会在仿真开始的一瞬间同时赋值
参考技术A 同时进行两次赋值,肯定是非阻塞赋值。并行多次赋值可能会出现X状态。本回答被提问者采纳

以上是关于Verilog语言中的赋值问题的主要内容,如果未能解决你的问题,请参考以下文章

verilog 语言中 大小比较用啥标识符?

verilog中寄存器的初始值问题,

Verilog 如何用持续赋值语句实现2选1多路选择器

在systemverilog的task中只能用阻塞赋值么

verilog语句执行顺序的疑问?

verilog 中啥语句并行运行啥时候顺序运行!搞不懂 请教高手!