Hem*_*ava 0 verilog register-transfer-level system-verilog
从很多天开始编写verilog代码,我遇到的一个问题是"我们可以在生成块中编写生成块"吗?我正在写一个像这样的RTL:
Where 'n' is a parameter.
reg [DATA_WIDTH:0] flops [n-1:0];
generate
if (n > 0) begin
always @(posedge clk) begin
if (en) begin
flops[0] <= mem[addr];
end
end
generate
genvar i;
for (i = 1; i <= n ; i = i + 1) begin
always @(posedge clk) begin
flops[i] <= flops[i-1];
end
end
endgenerate
always @(flops[n - 1])
douta = flops[n - 1];
else
always @(posedge clk) begin
if (en) begin
primary_output = mem[addr];
end
end
end
endgenerate
Run Code Online (Sandbox Code Playgroud)
在编译上面的代码时,我得到:
ERROR: syntax error near generate (VERI-1137)
Run Code Online (Sandbox Code Playgroud)
不知道为什么.此RTL的目的是在设计的输出端创建"n"触发器的管道.
让我们说n是2,然后电路应该变成:
flop1-> flop2-> primary output of design
Run Code Online (Sandbox Code Playgroud)
flop1和flop2是新创建的触发器.
离你应该去的地方还有很长的路要走.
Verilog不是一种编程语言; 它是一种硬件描述语言.您将硬件建模为并发进程的网络.每个过程模拟一小部分硬件,如计数器,状态机,移位寄存器,某些组合逻辑......在Verilog中,每个过程都被编码为一个always块.因此,一个always声明永远不会出现在另一个声明中; 这是没有意义的.
其次,generate是一个相当专业的声明.当您需要大量或可变数量的并发进程时,可以使用它.这不是常见的事情,因此generate不常见,但在需要时很有用.您不需要generate语句来实现可参数化的shift-register.并且,因为always块是并发语句,所以它位于generate语句中,而不是相反.
我不知道你的设计意图是什么,我怀疑这段代码并不能完全符合你的要求.但是,它实现了一个参数可移动的长度n和宽度的移位寄存器DATA_WIDTH+1(你的意思是?),由en输入启用:
module N_FLOPS #(n = 2, DATA_WIDTH = 8) (input [DATA_WIDTH:0] dina, input clk, en, output [DATA_WIDTH:0] douta);
reg [DATA_WIDTH:0] flops [n-1:0];
always @(posedge clk)
if (en)
begin : SR
integer i;
flops[0] <= dina;
for (i = 1; i <= n ; i = i + 1)
flops[i] <= flops[i-1];
end
assign douta = flops[n-1];
endmodule
Run Code Online (Sandbox Code Playgroud)
http://www.edaplayground.com/x/3kuY
你可以看到 - 不需要任何generate陈述.此代码符合此模板,无需异步重置即可满足任何顺序逻辑:
always @(posedge CLOCK) // or negedge
begin
// do things that occur on the rising (or falling) edge of CLOCK
// stuff here gets synthesised to combinational logic on the D input
// of the resulting flip-flops
end
Run Code Online (Sandbox Code Playgroud)