I cannot synthesize the Verilog code in Vivado, simulation runs correctly. I declare an array localparam, use an external counting variable cnt1 inside a generate block to get the desired address for parameter. When I remove the cnt1 variable inside module1, it could be synthesized. Please guys give me some suggestion to solve this problem. I really appreciate that.
module multiply_s1(
input clk,
input rst,
input [9:0]in,
input ena,
output [9:0]out);
localparam [0:24] pi_values = {5'h4, 5'h5, 5'h6, 5'h7, 5'h8};
reg [1:0] cnt1;//count CC times of GG coeffcient
always#(posedge clk or negedge rst) begin
if(rst == 0) begin
cnt1 <= 0;
end
else if(ena == 0) begin
cnt1 <= 0;
end
else begin
if (cnt1 == 3)
cnt1 <= 0;
else
cnt1 <= cnt1 + 1;
end
end
genvar i;
generate
for (i=0; i<2; i=i+1)
begin: mod1
module1 mod1(.clk(clk),
.rst(rst),
.multiplier(in[i*5 +: 5]),
.multiplicand(pi_values[(i + cnt1)*5 +: 5]),
.result(out[i*5 +: 5]));
end
endgenerate
endmodule
Without knowing what Vivado told you, I guess the error may be here:
[(i + cnt1)*5 +: 5]
cnt1 is a register whose value is only known at "runtime", therefore, Vivado cannot know which value to use to bitslicing the pi_values vector.
You would need something like this:
localparam [0:24] pi_values = {5'h4, 5'h5, 5'h6, 5'h7, 5'h8};
reg [1:0] cnt1;//count CC times of GG coeffcient
always#(posedge clk or negedge rst) begin
if(rst == 0)
cnt1 <= 0;
else if(ena == 0)
cnt1 <= 0;
else
cnt1 <= cnt1 + 1;
end
reg [0:24] pi_values_rotated;
always #* begin
case (cnt1)
0: pi_values_rotated = pi_values;
1: pi_values_rotated = {pi_values[5:24], pi_values[0:4]};
2: pi_values_rotated = {pi_values[10:24], pi_values[0:9]};
3: pi_values_rotated = {pi_values[15:24], pi_values[0:14]};
default: pi_values_rotated = pi_values;
endcase
end
genvar i;
generate
for (i=0; i<2; i=i+1)
begin: mod1
module1 mod1(.clk(clk),
.rst(rst),
.multiplier(in[i]),
.multiplicand(pi_values_rotated[i*5 +: 5]),
.result(out[i]));
end
endgenerate
pi_values_rotated would be the pi_values vector, as seen after the current value of cnt1 is applied. Then, you can use i as the sole value to generate your instances, which should be accepted now.
Notice here:
else begin
if (cnt1 == 3)
cnt1 <= 0;
else
cnt1 <= cnt1 + 1;
end
It can be either 0, 1, 2 or 3. This works fine in simulation. But in synthesis, you are constantly changing the value of cnt1 while trying to build logic gates for mod1 where mod1 uses that changing variable cnt1. This is a conflict for synthesizing logic gates.
Synthesis can't build gates for your generate block as it is building actual hardware and wants to know a deterministic value of cnt1 in order to construct the gates accordingly.
I believe you need to develop an architecture that can handle the largest value of cnt1
Related
I am trying to build a module for practice which gets as input:
clk, rst.
an array of 3 numbers each one is 4 bits.
The final purpose is to return in the output the minimum value in the array but I can't get it really working and I don't understand why.
module minVal(
input logic rstN, clk,
input logic unsigned [2:0][3:0] resArray,
output logic [3:0] minVal
);
logic unsigned [3:0] currRes;
always_ff #(posedge clk, posedge rstN) begin
if(rstN == 1'b1) begin
currRes <= 4'b1111;
end
else begin
for(int i = 0; i < 3; i++) begin
if( resArray[i] < currRes) begin
currRes <= resArray[i];
minVal <= resArray[i];
end
end
end
end
endmodule
I wrote the following test bench:
module minVal_tb();
logic rstN, clk;
logic unsigned [2:0][3:0] resArray;
logic [3:0] minVal;
minVal thisInst(.rstN(rstN), .clk(clk), .resArray(resArray), .minVal(minVal));
always begin
#20 clk = ~clk;
end
initial begin
clk = 1'b0;
rstN = 1'b1;
resArray[0] = 5;
resArray[1] = 1;
resArray[2] = 3;
#5 rstN = 1'b0;
end
endmodule
I expect the output to be 1 right after the first clock cycle, but I get it only after 2 clock cycles. Why?
When you unroll the for loop, this is what it would look like:
always_ff #(posedge clk, posedge rstN) begin
if(rstN == 1'b1) begin
currRes <= 4'b1111;
end
else begin
if( resArray[0] < currRes) begin
currRes <= resArray[0];
minVal <= resArray[0];
end
if( resArray[1] < currRes) begin
currRes <= resArray[1];
minVal <= resArray[1];
end
if( resArray[2] < currRes) begin
currRes <= resArray[2];
minVal <= resArray[2];
end
end
end
You end up with multiple nonblocking assignments to the same register (currRes).
On the 1st posedge of the clock after reset, all 3 if clauses are true, and the last assignment wins:
currRes <= resArray[2];
So, currRes is assigned the value 3, not 1.
The same is true of minVal.
You need to sort the 3 input values, then compare the minimum of those values to the current minimum.
I'm making a simple project with leds blinking every second. Led 1 and 3 blink alternating to led 2 and 4. I've written the following Verilog code:
module leds_blinking(input i_Clk,
output o_LED_1,
output o_LED_2,
output o_LED_3,
output o_LED_4);
parameter c_CYCLESINSECOND = 50_000_000;
reg r_LED_1 = 1;
reg r_LED_2 = 0;
reg r_LED_3 = 1;
reg r_LED_4 = 0;
reg [32:0] r_Count = 0;
always #(posedge i_Clk)
begin
if (r_Count < c_CYCLESINSECOND)
r_Count <= r_Count + 1;
else if (r_Count == c_CYCLESINSECOND)
begin
r_LED_1 <= ~r_LED_1;
r_LED_2 <= ~r_LED_2;
r_LED_3 <= ~r_LED_3;
r_LED_4 <= ~r_LED_4;
r_Count <= 0;
end
else
r_Count <= 0;
end
assign o_LED_1 = r_LED_1;
assign o_LED_2 = r_LED_2;
assign o_LED_3 = r_LED_3;
assign o_LED_4 = r_LED_4;
endmodule
All LEDs are active at the same time, though I instantiated 1,3 other than 2,4.
I’m assuming you are synthesizing and not running simulation on the RTL first. Synthesizer that target for ASIC typically ignore default values and initial blocks. Synthesizer that target for FPGA often do. Not knowing which synthesizer you are using it is hard to guess your root causes issue.
However, you can simplify your code and solve your problem by using one registers instead of four. Notice how the o_LED_# are driven.
always #(posedge i_Clk)
begin
if (r_Count < c_CYCLESINSECOND)
r_Count <= r_Count + 1;
else
begin
r_LED <= ~r_LED;
r_Count <= 0;
end
end
assign o_LED_1 = r_LED;
assign o_LED_2 = ~r_LED;
assign o_LED_3 = r_LED;
assign o_LED_4 = ~r_LED;
This is code for ALU that does addition and multiplication only. An addition is handled in same clock cycle but the multiplication result has to be delayed by 3 clock cycles.
module my_addmul(
//control signals
input i_clk,
input i_rst,
input i_en,
//add=01, mul=10
input [1:0] i_op,
//input and output registers
input [31:0] i_A,
input [31:0] i_B,
output [31:0] o_D,
//to signal if output is valid
output o_done
);
//registers to save output
reg [31:0] r_D;
reg [63:0] r_mul;//(*keep="true"*)
reg r_mul_done;
reg r_mul_done2;
reg r_done;
//updating outputs
assign o_D = r_D;
assign o_done = r_done;
always # (posedge i_clk)
begin
r_done <= 0;
r_mul_done <= 0;
if (i_rst) begin
r_D <= 0;
r_mul <= 0;
r_mul_done <= 0;
r_mul_done2 <= 0;
end else if (i_clk == 1) begin
if (i_en == 1) begin
//addition - assignment directly to OP registers
if (i_op == 01) begin
r_done <= 1;
r_D <= i_A + i_B;
//multiplication - indirect assignment to OP registers
end else if (i_op == 2'b10) begin
r_mul <= i_A * i_B;
r_mul_done <= 1;
end
end
//1-clock cycle delay
r_mul_done2 <= (r_mul_done == 1) ? 1 : 0;
//updating outputs in the 3rd cycle
if (r_mul_done2 == 1) begin
r_D <= r_mul[31:0];
r_done <= 1;
end
end
end
endmodule
The problem is that if the keep attribute is not used, the r_mul register that stores the multiplication output until 3rd clock cycle is optimised out. I read on the problem and realised that Vivado is thinking like this: "If the multiplication happens every clock cycle, the r_mul is over-written before it is sent to output. Therefore, it is a register being written but not read, Lets remove it!" Since I insert the 3 clock cycle wait in test bench, the simulation result is always accurate. I want to know what is the "Proper" way of doing this so I don't have to use the keep attribute. It is an ok solution but I think useful techniques should be learned so hacks don't have to be used. Any ideas or discussion welcome.
If I want to delay a signal, I'd probably insert flops for that. You can probably flop your mul_output like the way you do for the mul_done signal. Also, it is better to have different always blocks for doing the same. You can check the code below but it might be buggy since I haven't simulated/synthesized it -
module my_addmul(
//control signals
input i_clk,
input i_rst,
input i_en,
//add=01, mul=10
input [1:0] i_op,
//input and output registers
input [31:0] i_A,
input [31:0] i_B,
output [31:0] o_D,
//to signal if output is valid
output o_done
);
//registers to save output
reg [31:0] r_D;
reg [63:0] r_mul;//(*keep="true"*)
reg r_mul_1;
reg r_mul_2;
reg r_mul_done;
reg r_mul_done2;
reg r_done;
//updating outputs
assign o_D = r_D;
assign o_done = r_done;
always # (posedge i_clk)
begin
r_done <= 0;
r_mul_done <= 0;
if (i_rst) begin
r_D <= 0;
r_mul <= 0;
r_mul_done <= 0;
r_mul_done2 <= 0;
end else if (i_clk == 1) begin
if (i_en == 1) begin
//addition - assignment directly to OP registers
if (i_op == 01) begin
r_done <= 1;
r_D <= i_A + i_B;
//multiplication - indirect assignment to OP registers
end else if (i_op == 2'b10) begin
r_mul <= i_A * i_B;
r_mul_done <= 1;
end
end
end
end
always # (posedge i_clk)
begin
if (i_rst)
begin
r_mul_1 <= 0;
r_mul_done2 <= 0;
end
else
begin
r_mul_1 <= r_mul;
r_mul_done2 <= r_mul_done;
end
end
always # (posedge i_clk)
begin
if (i_rst)
begin
r_D <= 0;
r_done <= 0;
end
else
begin
r_D <= r_mul_1;
r_done <= r_mul_done2;
end
end
endmodule
I'm tring to write universal fifo buffer.
To make it universal i used code like this.
genvar i;
generate
for(i=0;i<BusWidthIn;i=i+1) begin: i_buffin
always # (negedge clkin) begin
if (!full)
Buffer[wr_ptr+i] <= datain[i*BitPerWord+BitPerWord-1:i*BitPerWord];
end
end
endgenerate
In simulation it works properly, but in Quartus it gives
Error (10028): Can't resolve multiple constant drivers for net "Buffer[30][6]" at fifo.v(33) and so on.
All Code
module fifo_m(clkin,datain,clkout,dataout,full,empty);
parameter BusWidthIn = 3, //in 10*bits
BusWidthOut = 1, //in 10*bits
BufferLen = 4, // in power of 2 , e.g. 4 will be 2^4=16 bytes
BitPerWord = 10;
input clkin;
input [BusWidthIn*BitPerWord-1:0] datain;
input clkout;
output [BusWidthOut*BitPerWord-1:0] dataout;
output full;
output empty;
reg [BusWidthOut*BitPerWord-1:0] dataout;
reg [BitPerWord-1:0] Buffer [(1 << BufferLen)-1 : 0];
wire [BusWidthIn*BitPerWord-1:0] tbuff;
reg [BufferLen - 1 : 0] rd_ptr, wr_ptr;
wire [BufferLen - 1 : 0] cnt_buff;
wire full;
wire empty;
assign cnt_buff = wr_ptr > rd_ptr ? wr_ptr - rd_ptr : (1 << BufferLen) - rd_ptr + wr_ptr;
assign full = cnt_buff > (1 << BufferLen) - BusWidthIn;
assign empty = cnt_buff < BusWidthOut;
initial begin
rd_ptr = 0;
wr_ptr = 0;
end
genvar i;
generate
for(i=0;i<BusWidthIn;i=i+1) begin: i_buffin
always # (negedge clkin) begin
if (!full)
Buffer[wr_ptr+i] <= datain[i*BitPerWord+BitPerWord-1:i*BitPerWord];
end
end
endgenerate
always # (negedge clkin)
begin
if (!full)
wr_ptr = wr_ptr + BusWidthIn;
end
genvar j;
generate
for(j=0;j<BusWidthOut;j=j+1) begin : i_buffout
always # (posedge clkout) begin
dataout[j*BitPerWord+BitPerWord-1:j*BitPerWord] <= Buffer[rd_ptr+j];
end
end
endgenerate
always # (posedge clkout)
begin
if (!empty)
rd_ptr = rd_ptr + BusWidthOut;
end
endmodule
To solve this problem I must put for inside always, but how I can do it?
I think the issue is that synthesis doesn't know that wr_ptr is always a multiple of 3, hence from the synthesis point of view 3 different always blocks can assign to each Buffer entry. I think you can recode your logic to assign just a single Buffer entry per always block.
genvar i, j;
generate
for(i=0;i < (1<<(BufferLen)); i=i+1) begin: i_buffin
for(j = (i%BusWidthIn);j == (i%BusWidthIn); j++) begin // a long way to write 'j = (i%BusWidthIn);'
always # (negedge clkin) begin
if (!full) begin
if (wr_ptr*BusWidthIn + j == i) begin
Buffer[i] <= datain[j*BitPerWord+BitPerWord-1:j*BitPerWord];
end
end
end
end
end
endgenerate
Also at http://www.edaplayground.com/x/23L (based off of Morgan's copy).
And, don't you need to add a valid signal into the fifo, or is the data actually always available to be pushed in ?
Other then the *_ptr in your code should be assigned with non-blocking assignment (<=), there really isn't anything wrong with your code.
If you want to assign Buffer with a for-loop inside of an always block, you can use the following:
integer i;
always #(negedge clkin) begin
if (!full) begin
for (i=0;i<BusWidthIn;i=i+1) begin: i_buffin
Buffer[wr_ptr+i] <= datain[i*BitPerWord +: BitPerWord];
end
wr_ptr <= wr_ptr + BusWidthIn;
end
end
datain[i*BitPerWord+BitPerWord-1:i*BitPerWord] will not compile in Verilog because the MSB and LSB select bits are variables. Verilog requires a known range. +: is for part-select (also known as a slice) allows a variable select index and a constant range value. It was introduced in IEEE Std 1364-2001 § 4.2.1. You can also read more about it in IEEE Std 1800-2012 § 11.5.1, or refer to previously asked questions: What is `+:` and `-:`? and Indexing vectors and arrays with +:.
I am trying to pass an integer value to a module, but the IF statement does not work with the parameter. It throws the following error. I am new to Verilog so I have no idea how to make this work.
Error (10200): Verilog HDL Conditional Statement error at clock_divider.v(17):
cannot match operand(s) in the condition to the corresponding edges in the enclosing
event control of the always construct
clock_divider.v module
module clock_divider (clockHandler, clk, rst_n, clk_o);
parameter DIV_CONST = 10000000 ; // 1 second
parameter DIV_CONST_faster = 10000000 / 5;
input clockHandler;
input clk;
input rst_n;
output reg clk_o;
reg [31:0] div;
reg en;
integer div_helper = 0;
always # (posedge clk or negedge rst_n)
begin
if(clockHandler == 0)
begin div_helper = DIV_CONST;
end
else
begin div_helper = DIV_CONST_faster;
end
if (!rst_n)
begin div <= 0;
en <= 0;
end
else
begin
if (div == div_helper)
begin div <= 0;
en <= 1;
end
else
begin div <= div + 1;
en <= 0;
end
end
end
always # (posedge clk or negedge rst_n)
begin
if (!rst_n)
begin
clk_o <= 1'b0;
end
else if (en)
clk_o <= ~clk_o;
end
endmodule
main.v module
reg clockHandler = 1;
// 7-seg display mux
always # (*)
begin
case (SW[2:0])
3'b000: hexdata <= 16'h0188;
3'b001: hexdata <= register_A ;
3'b010: hexdata <= program_counter ;
3'b011: hexdata <= instruction_register ;
3'b100: hexdata <= memory_data_register_out ;
3'b111: hexdata <= out;
default: hexdata <= 16'h0188;
endcase
if(SW[8] == 1)
begin
clockHandler = 1;
end
else
begin
clockHandler = 0;
end
end
HexDigit d0(HEX0,hexdata[3:0]);
HexDigit d1(HEX1,hexdata[7:4]);
HexDigit d2(HEX2,hexdata[11:8]);
HexDigit d3(HEX3,hexdata[15:12]);
clock_divider clk1Hzfrom50MHz (
clockHandler,
CLOCK_50,
KEY[3],
clk_1Hz
);
It's my understanding that the first statement in a verilog always block must be the if(reset) term if you're using an asynchronous reset.
So the flop construct should always look like this:
always # (posedge clk or negedge rst_n) begin
if(~rst_n) begin
...reset statements...
end else begin
...all other statements...
end
end
So for your case you should move the if(clockHandler==0) block inside the else statement, because it is not relevant to the reset execution. Even better would be to move it into a separate combinational always block, since mixing blocking and nonblocking statements inside an always block is generally not a good idea unless you really know what you're doing. I think it is fine in your case though.
To add to Tim's answer - the original code (around line 17, anyway) is valid Verilog.
What it's saying is "whenever there's a rising edge on clk or a falling edge on rst_n, check clockHandler and do something" (by the way, get rid of the begin/ends; they're redundant and verbose). The problem comes when you want to implement this in real hardware, so the error message is presumably from a synthesiser, which needs more than valid Verilog. The synth suspects that it has to build a synchronous element of some sort, but it can't (or won't, to be precise) handle the case where clockHandler is examined on an edge of both clk and rst_n. Follow the rules for synthesis templates, and you won't get this problem.
is this a compilation error or synthesis error? i used the same code to see if it compiles fine, and i din get errors.. Also, it is recommended to use "<=" inside synchronous blocks rather than "="
You're using the same flop construct for two different things. Linearly in code this causes a slipping of states. I always place everything within one construct if the states rely on that clock or that reset, otherwise you require extra steps to make sure more than one signal isn't trying to change your state.
You also don't need the begin/end when it comes to the flop construct, Verilog knows how to handle that for you. I believe Verilog is okay with it though, but I generally don't do that. You also don't have to use it when using a single statement within a block.
So your first module would look like this (if I missed a block somewhere just let me know):
clock_divider.v module (edited)
module clock_divider (clockHandler, clk, rst_n, clk_o);
parameter DIV_CONST = 10000000 ; // 1 second
parameter DIV_CONST_faster = 10000000 / 5;
input clockHandler;
input clk;
input rst_n;
output reg clk_o;
reg [31:0] div;
reg en;
integer div_helper = 0;
always # (posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
div <= 0;
en <= 0;
clk_o <= 1'b0;
end
else if(en)
begin
clk_o <= ~ clk_o;
if(clockHandler == 0)
begin
div_helper = DIV_CONST;
end
else
begin
div_helper = DIV_CONST_faster;
end
else
begin
if (div == div_helper)
begin
div <= 0;
en <= 1;
end
end
else
begin
div <= div + 1;
en <= 0;
end
end
end
end module
If that clk_o isn't meant to be handled at the same time those other operations take place, then you can separate everything else with a general 'else' statement. Just be sure to nest that second construct as an if-statement to check your state.
And also remember to add always # (posedge clk or negedge rst_n) to your main.v module as Tim mentioned.