generate inside generate verilog + error near generate(veri - 1137) 生成
generate inside generate verilog + error near generate(veri - 1137)
写了好几天的 verilog 代码,我有一个问题是 'Can we write generate block inside generate block'?我正在写这样的 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
编译上述代码时,我得到:
ERROR: syntax error near generate (VERI-1137)
不知道为什么。此 RTL 的目的是在设计的输出端创建 'n' 个触发器的流水线。
假设 n 为 2,则电路应变为:
flop1-> flop2-> primary output of design
flop1 和 flop2 是新创建的翻牌。
你离你应该去的地方还有很长的路要走。
Verilog 不是一种编程语言;它是一种硬件描述语言。您将硬件建模为 并发 进程的网络。每个进程都对一小部分硬件进行建模,例如计数器、状态机、移位寄存器、一些组合逻辑……在 Verilog 中,每个进程都被编码为一个 always
块。因此,一个 always
语句永远不会出现在另一个语句中;这毫无意义。
其次,generate
是一个比较专业的说法。当您需要大量或可变数量的并发进程时,可以使用它。这不是通常需要的东西,所以 generate
并不常见,但在需要时很有用。您不需要生成语句来实现可参数化的移位寄存器。而且,因为 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
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
写了好几天的 verilog 代码,我有一个问题是 'Can we write generate block inside generate block'?我正在写这样的 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
编译上述代码时,我得到:
ERROR: syntax error near generate (VERI-1137)
不知道为什么。此 RTL 的目的是在设计的输出端创建 'n' 个触发器的流水线。
假设 n 为 2,则电路应变为:
flop1-> flop2-> primary output of design
flop1 和 flop2 是新创建的翻牌。
你离你应该去的地方还有很长的路要走。
Verilog 不是一种编程语言;它是一种硬件描述语言。您将硬件建模为 并发 进程的网络。每个进程都对一小部分硬件进行建模,例如计数器、状态机、移位寄存器、一些组合逻辑……在 Verilog 中,每个进程都被编码为一个 always
块。因此,一个 always
语句永远不会出现在另一个语句中;这毫无意义。
其次,generate
是一个比较专业的说法。当您需要大量或可变数量的并发进程时,可以使用它。这不是通常需要的东西,所以 generate
并不常见,但在需要时很有用。您不需要生成语句来实现可参数化的移位寄存器。而且,因为 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
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