请教两个写verilog代码的基本问题(已解决,谢谢)
问题一
如果case有很多种可能性,比如,WRITE_0,WRITE_1,WRITE_2,WRITE_3,WRITE_4,WRITE_5,WRITE_6,等等
在1,2,3,4周期写数据,其他情况默认不变,default应该怎么写?
case (fsm)
WRITE_0:
wdata_d [7:0] <= #1 i_data;
WRITE_1:
wdata_d [15:8] <= #1 i_data;
WRITE_2:
wdata_d [23:16] <= #1 i_data;
WRITE_3:
wdata_d [31:24] <= #1 i_data;
default:
endcase
问题二
输出信号o_data
如果是reg,怎么赋值
假如,output reg[7:0] o_data;
always @(*) o_data<= 0'b1;
如果不是reg,怎么赋值
假如,output reg[7:0] o_data;
assign o_data = 0'b1;
上面的写法对么?有什么区别么?
default: ;
这样写就好了。
输出也是case()输出就好了。跟上面的case()类似。
嗯,对于时序逻辑这个应该没有什么影响吧,
可以帮我回答 问题二 不?
问题2 好像不对吧。
如果是reg,必须是always @(posedge/negedge clk) o_data<= 0'b1;有时钟它才叫寄存器。
如果不是reg,你这样写没有报错吗?assign不可以给reg变量赋值。改成wire型的就好了。
假如,output reg[7:0] o_data;
always @(*) o_data<= 0'b1;
如果不是reg
假如,output [7:0] o_data;
assign o_data = 0'b1;
不好意思,copy错了,第二个没有reg, 我说就是没有reg, 所以用assign 赋值,这两种综合有区别么?另外,第一个always @(*) 没有报错,这个语法不对么?
wire类型的信号不用另外声明出来吧
比如reg型 output reg 『』data;
wire型 output 『』data;
可以不用声明,默认就是wire类型。
这样写always @(*) o_data<= 0'b1 与 assign o_data = 0'b1 效果是一样的,但是两个都是组合逻辑。但是如果说组合逻辑的话,这一句always @(*) o_data<= 0'b1 中<=应该改为=,这样写语法没有问题,不会报错,但是不规范。
严格来说,组合逻辑与时序逻辑不能用reg不reg来区分。组合逻辑你可以简单地理解为没有时钟的逻辑,时序逻辑则是有时钟的。
你的本意是有要综合成时序逻辑是吧,修改方法就是我前面提到的 always @(posedge/negedge clk) o_data<= 0'b1。这样才会综合出DFF来。
如理解有误,欢迎拍砖。
给你一个不用reg的解答
wire [31:0] wdata_d;
assign wdata_d [7:0] = #1 (fsm == WRITE_0) ? i_data:default;
assign wdata_d [15:8] = #1 (fsm == WRITE_1) ? i_data:default;
assign wdata_d [23:16] = #1 (fsm == WRITE_2) ? i_data:default;
assign wdata_d [31:24] = #1 (fsm == WRITE_3) ? i_data:default;
状态机里面越简单越好。组合逻辑要么直接赋值,要么用异步做。
assign wdata_d [31:24] = #1 (fsm == WRITE_3) ? i_data:default;
竟然有这种写法,呵呵,少见少见,但是这对于综合来说,效果一样的吧,因为后面有个default,是不是说也会生成一个latch啊。
你没给我default值,我也不好瞎猜。如果为了综合,通常给个'hz,或者'h0就可以了,除非你有特定值。
延时写错了,应该是 assign #1 wdata_d [31:24] = (fsm == WRITE_3) ? i_data:default;
这样有个坏处,会吃掉小于#1的毛刺
我要表达的效果是不满足条件的时候,变量的值不变,所以你这样写可能就不行了。
那就保留原来的case. default:; 或者根本不写。
