SystemVerilog: Parameter used in concatenation gives error with irun - verilog

Cadence irun gives error for below code, where fifo_depth_base2 is parameter as below:
ncvlog: *E,NONOWD (buff_mgr.v,17|46): Illegal use of a constant without an explicit width specification [4.1.14(IEEE)].
I can understand this error, but my question is how would I otherwise assign it for parameterized design.
// rd pointer and read logic
always #(posedge clk or posedge rst) begin
if(rst) rd_ptr <= 0;
else begin
case({flush, rd})
2'b10, 2'b11: rd_ptr <= {fifo_depth_base2{'b0}}; // error here
...
endcase
end
end

You are missing a 1 before 'b0. The simulator doesn't know the bit size of 'b0 because it is not specified.
{fifo_depth_base2{'b0}}; should be {fifo_depth_base2{ 1'b0}};
With SystemVerilog you can use: rd_ptr <= '0;, where '0 means fill zeros

Related

Error (10734): Verilog HDL error at m.v(156): cnt is not a constant

I need to write 4 bytes from input pins to different parts of a register depending on a counter, with the code i have now I get this error:
Error (10734): Verilog HDL error at m.v(156): cnt is not a constant
How should I deal with it?
wire wren, rst;
wire [3:0] abcd;
reg [31:0] my_reg;
reg [3:0] cnt;
always #(posedge wren or posedge rst)
begin
if (rst == 1)
begin
my_reg <= 0;
end
else
begin
if (wren == 1)
begin
my_reg [4*cnt+3:4*cnt] <= abcd;
end
end
end
As for your error: you should use the +: syntax [4*cnt +: 4]
See here for more information.
Even if that would be semantically allowed your values would be wrong:
[4*cnt-1:4*cnt] would give a low:high index e.g. if cnt=1 you get [3:4]
[4*cnt-1:4*cnt] gives a negative index if cnt==0 [-1:0] which is outside the range [31:0] of reg.
You probably meant to use [4*cnt+3:4*cnt]
But you have other errors too.
First it is very dangerous to use a keyword for a variable. (reg)
Second you are clocking using a non-clock signal: wren. This creates another clock tree. The normal procedure is to use an if with the standard system clock:
always #(posedge clk or posedge rst)
begin
if (rst == 1)
begin
my_reg <= 0;
end
else
begin
if (wren == 1)
begin
my_reg [4*cnt +: 4] <= abcd;
end
end
end

SystemVerilog Initialize multi dimensional parameterized array in

I am trying to initialize a multi dimensional parameterized array in SystemVerilog which I have described as below:
...
parameter INPUT_WIDTH = 16;
parameter NUM_ELEMENTS = 4;
...
reg signed [INPUT_WIDTH-1 : 0 ] ss_res_reg[NUM_ELEMENTS-1:0];
I want to initialize the ss_res_reg to zero on every falling edge of rst so:
always_ff #(posedge clk or negedge rst) begin
if(~rst) begin
ss_res_reg <= '{NUM_ELEMENTS{NUM_ELEMENTS{1'b0}}};
end else begin
ss_res_reg <= ss_res;
end
end
The problem is with this line ss_res_reg <= '{NUM_ELEMENTS{INPUT_WIDTH{1'b0}}};. If I change it to ss_res_reg <= '{NUM_ELEMENTS{16'b0}}; it works perfectly fine. However, when I want to use the INPUT_WIDTH parameter, Xilinx tool gives me the following error: syntax error near {. I also tried ss_res_reg <= '{NUM_ELEMENTS{16{1'b0}}}; and got the same error. Does anyone know what am I doing wrong?
You can use the default label in an assignment pattern to assign all elements of an unpacked array having any number of dimensions:
always_ff #(posedge clk or negedge rst) begin
if(~rst) begin
ss_res_reg <= '{default:'0};
end else begin
ss_res_reg <= ss_res;
end
end
'0 means fill the packed array with 0's
The error lies in the fact that you can not replicate unpacked array elements.
There is a simple solution:
if(~rst)
for (integer i=0; i<NUM_ELEMENTS; i++)
ss_res_reg[i] <= {INPUT_WIDTH{1'b0}};

Triangle waveform verilog

I'm trying to get a triangle waveform, but my code doesn't work! I think the "if conditions" are organised wrong but I can't find the mistake My wave goes up like it should be and it falls down by 90° after achieving the top
module pila(clk,res,out2);
input clk,res;
output [0:7]out2;
reg [0:7]out2;
always #(posedge clk)
begin
if (res)
begin
if(out2<=8'b11111111)
out2=out2+1;
else if(out2>=8'b00000000)
out2=out2-1;
else out2=8'b00000000;
end
else out2=8'b00000000;
end
endmodule
module testbench;
reg clk,res;
wire [0:7]out2;
pila Sevo(clk,res,out2);
always #2 clk=~clk;
initial
begin
clk=0;res=0;
#2 res=1;
end
initial #5000 $finish;
endmodule
You need some signal to indicate which direction you are currently counting. Also use the non-blocking assignment operator <= rather than the blocking assignment operator =.
module pila(clk,res,out2);
input clk,res;
output [0:7]out2;
reg [0:7]out2 = 8'h00;
reg count_down = 1'b0;
always #(posedge clk)
begin
if (count_down == 1'b0)
begin
if (out2==8'b11111111) // check for top of count
begin
count_down <= 1'b1;
out2<=out2-1;
end
else
out2<=out2+1;
end
else
begin
if(out2==8'b00000000) // check for bottom of count
begin
count_down <= 1'b0;
out2<=out2+1;
end
else
out2<=out2-1;
end
end
endmodule
The if(out2<=8'b11111111) condition is always evaluating to true. This is because out2 range is 0 to 255. Try adding another flop to control the direction, for example downup where 1 means decrement and 0 means increment.
if (out2 == 8'h00) begin
downup <= 1'b0; // up
out2 <= 8'h01;
end
else if (out2 == 8'hFF) begin
downup <= 1'b1; // down
out2 <= 8'hFE;
end
else if (downup) begin // down
out2 <= out2 - 1;
end
else begin // up
out2 <= out2 + 1;
end
Other issues:
Use non-blocking assignment (<=) for synchronous logic.
Typically reset (and set) conditions are declared before synchronous logic assignment
Little-Endian ([7:0]) is more commonly used for packed arrays (previously known as vectors) then Big-Endian ([0:7]), http://en.wikipedia.org/wiki/Endianness
Working example: http://www.edaplayground.com/x/4_b

cannot use an input for if statement in Verilog

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.

My Verilog behavioral code getting simulated properly but not working as expected on FPGA

I wrote a behavioral program for booth multiplier(radix 2) using state machine concept. I am getting the the results properly during the program simulation using modelsim, but when I port it to fpga (spartan 3) the results are not as expected.
Where have I gone wrong?
module booth_using_statemachine(Mul_A,Mul_B,Mul_Result,clk,reset);
input Mul_A,Mul_B,clk,reset;
output Mul_Result;
wire [7:0] Mul_A,Mul_B;
reg [7:0] Mul_Result;
reg [15:0] R_B;
reg [7:0] R_A;
reg prev;
reg [1:0] state;
reg [3:0] count;
parameter start=1 ,add=2 ,shift=3;
always #(state)
begin
case(state)
start:
begin
R_A <= Mul_A;
R_B <= {8'b00000000,Mul_B};
prev <= 1'b0;
count <= 3'b000;
Mul_Result <= R_B[7:0];
end
add:
begin
case({R_B[0],prev})
2'b00:
begin
prev <= 1'b0;
end
2'b01:
begin
R_B[15:8] <= R_B[15:8] + R_A;
prev <= 1'b0;
end
2'b10:
begin
R_B[15:8] <= R_B[15:8] - R_A;
prev <= 1'b1;
end
2'b11:
begin
prev <=1'b1;
end
endcase
end
shift:
begin
R_B <= {R_B[15],R_B[15:1]};
count <= count + 1;
end
endcase
end
always #(posedge clk or posedge reset)
begin
if(reset==1)
state <= start;
else
begin
case(state)
start:
state <= add;
add:
state <= shift;
shift:
begin
if(count>7)
state <= start;
else
state <=add;
end
endcase
end
end
endmodule
You have an incomplete sensitivity list in your combinational always block. Change:
always #(state)
to:
always #*
This may be synthesizing latches.
Use blocking assignments in your combinational always block. Change <= to =.
Good synthesis and linting tools should warn you about these constructs.
Follow the following checklist if something does work in the simulation but not in reality:
Did you have initialized every register? (yes)
Do you use 2 registers for one working variable that you transfer after each clock (no)
(use for state 2 signals/wires, for example state and state_next and transfer after each clock state_next to state)
A Example for the second point is here, you need the next stage logic, the current state logic and the output logic.
For more informations about how to proper code a FSM for an FPGA see here (go to HDL Coding Techniques -> Basic HDL Coding Techniques)
You've got various problems here.
Your sensitivity list for the first always block is incomplete. You're only looking at state, but there's numerous other signals which need to be in there. If your tools support it, use always #*, which automatically generates the sensitivity list. Change this and your code will start to simulate like it's running on the FPGA.
This is hiding the other problems with the code because it's causing signals to update at the wrong time. You've managed to get your code to work in the simulator, but it's based on a lie. The lie is that R_A, R_B, prev, count & Mul_Result are only dependent on changes in state, but there's more signals which are inputs to that logic.
You've fallen into the trap that the Verilog keyword reg creates registers. It doesn't. I know it's silly, but that's the way it is. What reg means is that it's a variable that can be assigned to from a procedural block. wires can't be assigned to inside a procedural block.
A register is created when you assign something within a clocked procedural block (see footnote), like your state variable. R_A, R_B, prev and count all appear to be holding values across cycles, so need to be registers. I'd change the code like this:
First I'd create a set of next_* variables. These will contain the value we want in each register next clock.
reg [15:0] next_R_B;
reg [7:0] next_R_A;
reg next_prev;
reg [3:0] next_count;
Then I'd change the clocked process to use these:
always #(posedge clk or posedge reset) begin
if(reset==1) begin
state <= start;
R_A <= '0;
R_B <= '0;
prev <= '0;
count <= '0;
end else begin
R_A <= next_R_A;
R_B <= next_R_B;
prev <= next_prev;
count <= next_count;
case (state)
.....
Then finally change the first process to assign to the next_* variables:
always #* begin
next_R_A <= R_A;
next_R_B <= R_B;
next_prev <= prev;
next_count <= count;
case(state)
start: begin
next_R_A <= Mul_A;
next_R_B <= {8'b00000000,Mul_B};
next_prev <= 1'b0;
next_count <= 3'b000;
Mul_Result <= R_B[7:0];
end
add: begin
case({R_B[0],prev})
2'b00: begin
next_prev <= 1'b0;
end
.....
Note:
All registers now have a reset
The next_ value for any register defaults to it's previous value.
next_ values are never read, except for the clocked process
non-next_ values are never written, except in the clocked process.
I also suspect you want Mul_Result to be a wire and have it assign Mul_Result = R_B[7:0]; rather than it being another register that's only updated in the start state, but I'm not sure what you're going for there.
A register is normally a reg, but a reg doesn't have to be a register.

Resources