Why is this variable not considered a constant? - loops

The following is code I wrote is a test bench to simulate a decoder (Verilog HDL). It converts [15:0]IR to [25:0]ControlWord. Literal is a byproduct that is watched as well.
All values from 0-65535 need to be tested for the 16-bit IR variable. In the beginning of the loop, I distinctly assign IR to be 0, but Quartus is telling me that:
Warning (10855): Verilog HDL warning at controluni_tb.v(20): initial value for variable IR should be constant
and as a result I get the following:
Error (10119): Verilog HDL Loop Statement error at controluni_tb.v(23): loop with non-constant loop condition must terminate within 250 iterations
The code for my test bench module is as follows:
module controluni_tb;
reg [15:0]IR;
reg clock;
wire [25:0]ControlWord;
wire [15:0] literal;
Total_Control_Unit_2 dut (IR,ControlWord,literal);
initial
begin
clock <= 1'b0;
end
initial
begin
IR <= 16'b0;
end
initial
begin
forever
begin
#1 IR <= IR + 16'b1;
end
end
initial
#65535 $finish;
endmodule

Your code has no errors. initial blocks and system functions ($finish) is used for simulation (not synthesis). That error is related to synthesis. I edited your code for more readability (your clock is always zero!) :
module controluni_tb;
reg [15:0]IR;
reg clock;
wire [25:0]ControlWord;
wire [15:0] literal;
Total_Control_Unit_2 dut (IR,ControlWord,literal);
initial begin
clock = 1'b0;
end
initial begin
IR = 16'b0;
forever #1 IR = IR + 16'b1;
end
initial begin
#65535 $finish;
end
endmodule

Instead of using a forever loop, why not just use a for loop for IR? Then the problem is completely bounded.
initial begin
for (IR = 0; IR <= 65535; IR++);
$finish;
end

Related

Generating second counter in VHDL

I am new to VHDL and trying to generate 1 second counter. For simplicity, I am using the clock frequency of 10 Hz. For this purpose I am using a clk as an input and LED as an output. My VHDL code is given below:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
use ieee.numeric_std.all;
entity tick_counter is
generic(FrequencyHz : integer := 10);
Port ( clk : in STD_LOGIC;
led : out STD_LOGIC);
end tick_counter;
architecture Behavioral of tick_counter is
signal tick :integer;
signal counter :integer;
begin
process(clk, tick, counter)
begin
if rising_edge(clk) then
if tick = FrequencyHz - 1 then
tick <= 0;
counter <= counter + 1;
else
tick <= tick + 1;
end if;
end if;
end process;
led <= '1' when counter = 3 else '0';
end Behavioral;
I tried to write the code in such a way so that, when three seconds pass, the LED turns ON. My test bench code is given below:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
use ieee.numeric_std.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY tick_counter_tb IS
END tick_counter_tb;
ARCHITECTURE behavior OF tick_counter_tb IS
-- Component Declaration for the Unit Under Test (UUT)
-- We're slowing down the clock to speed up simulation time
constant FrequencyHz : integer := 10; -- 10 Hz
constant clk_period : time := 1000 ms / FrequencyHz;
COMPONENT tick_counter
PORT( clk : IN std_logic;
led : OUT std_logic);
END COMPONENT;
--Inputs
signal clk : std_logic := '0';
--Outputs
signal led : std_logic;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut : entity work.tick_counter
generic map(FrequencyHz => FrequencyHz)
PORT MAP (clk => clk,
led => led);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait until rising_edge(clk);
-- insert stimulus here
wait;
end process;
END;
But in the simulation result, I am just seeing a blank diagram as shown below (link given):
I don't understand where I am making a mistake. Any help would be highly appreciated.
The default initial value of an integer is INTEGER'LOW (a very negative number).
That means counter won't become 3 for a very long time (as the busybee indicated).
You can constrain and/or provide an initial value for tick. counter appears to be meant as a modulo counter range 0 to 3. It's modulus could be passed identically to tick which uses FrequencyHZ. Also note that any integer counter needs explicit roll over, it's an error if the result of an addition doesn't fall with the range INTEGER'LOW to INTEGER'HIGH or the constrained range.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- USE ieee.std_logic_unsigned.ALL;
-- use ieee.numeric_std.all;
entity tick_counter is
generic(FrequencyHz : integer := 10);
Port ( clk : in STD_LOGIC;
led : out STD_LOGIC);
end tick_counter;
architecture Behavioral of tick_counter is
-- Initial value of integers is INTEGER'LOW (a large negative number)
signal tick: integer range 0 to FrequencyHz - 1 := 0;
signal counter: integer := 0; -- ADDED default initial value
begin
process(clk, tick, counter)
begin
if rising_edge(clk) then
if tick = FrequencyHz - 1 then
tick <= 0;
if counter = 3 then -- ADDED MODULUS 4 test for counter
counter <= 0;
else
counter <= counter + 1;
end if;
else
tick <= tick + 1;
end if;
end if;
end process;
led <= '1' when counter = 3 else '0';
end Behavioral;
With the changes the simulation will cause led to be a '1' for one second every four seconds.

synthesizable way to load initial values in verilog

I would like to write a module that uses some coefficients that are loaded from a file.
For example:
reg [3:0] coeffs[0:1];
reg [6:0] ans;
always #(posedge clk) begin
if (!reset) begin
coeffs[0] <= 3;
coeffs[1] <= 2;
ans <= 0;
end
else begin
ans <= coeffs[0] * coeffs[1];
end
end
I would like to replace the values 3 and 2 by values that I can modify in a file, and provide the file during synthesis.
Obviously, this file will only assign initial values to the registers.
I don't want it to be a block ram, I want it to be like independent registers.
Just to clarify, I need the solution to be very generic, because I intent to use it in many modules that are doing the same thing, but with a different number of coefficients.
Meaning, in the end I wish to have a generic module that receives as a parameter a file name that stores the coefficients, and the number of coefficients and their width, and generates a code using those parameters.
I have tried readmemh but I understood it is only synthesizable to initiate a memory.
Any suggestions?
Thanks.
Here's a suggestion: put the statements initialising the array coeffs in an include file, eg
coeffs.v:
coeffs[0] <= 3;
coeffs[1] <= 2;
code:
reg [3:0] coeffs[0:1];
reg [6:0] ans;
always #(posedge clk) begin
if (!reset) begin
`include "coeffs.v"
ans <= 0;
end
else begin
ans <= coeffs[0] * coeffs[1];
end
end
An include file is included at compile time. So, your synthesiser will insert the contents of the file in the right place in the design. You could then manage the files using your operating system.
I am happy to stand corrected, but apart from 'Trickery' (Include files, define files, running a script generating such before synthesis) I am not aware of any method where you can load plain numbers from a file for synthesis.
I admit it a is problem waiting for a solution.
If only to prevent major embarrassment when your chip comes back from the manufacturer and you find the boot-rom is completely empty.... As if that ever happened where I worked (rolls eyes) Fixing requires only a single (contact) layer change but the lower layer masks are the most expensive).
Using parameter to pass the initial value is better option.
module A
#( parameter INITIAL_VALUE_COEFFS_0 = 3,
parameter INITIAL_VALUE_COEFFS_1 = 2)
( /* ignore it */ );
reg [3:0] coeffs[0:1];
reg [6:0] ans;
always #(posedge clk) begin
if (!reset) begin
coeffs[0] <= INITIAL_VALUE_COEFFS_0;
coeffs[1] <= INITIAL_VALUE_COEFFS_1;
ans <= 0;
end
else begin
ans <= coeffs[0] * coeffs[1];
end
end
endmodule

Verilog/SystemVerilog inferred latch in case statement

I am having trouble understanding why my code have a latch
logic [1:0] lru_list [0:3];
always_comb begin
if(reset) begin
lru_list[0] = 0;
lru_list[1] = 0;
lru_list[2] = 0;
lru_list[3] = 0;
end
else begin
case({access, update, access_index_i < 4})
3'b101: begin
lru_list[0] = lru_list[0] + 1;
lru_list[1] = lru_list[1] + 1;
lru_list[2] = lru_list[2] + 1;
lru_list[3] = lru_list[3] + 1;
lru_list[access_index_i] = 0;
end
3'b011: begin
lru_list[0] = lru_list[0];
lru_list[1] = lru_list[1];
lru_list[2] = lru_list[2];
lru_list[3] = lru_list[3];
lru_list[access_index_i] = 0;
end
default: begin
lru_list[0] = lru_list[0];
lru_list[1] = lru_list[1];
lru_list[2] = lru_list[2];
lru_list[3] = lru_list[3];
end
endcase
end
end // always_comb
In the case statement, I have a default case which will catch all the unmatched values. I have also set each index in the array a value. I don't understand where I am implicitly setting my array a implicit value.
I thought it might have to do with lru_list[access_index_i] = 0;, but commenting those two lines out will still give me the save error.
Here is what I would start with.
First add a sensitivity list to the always statement. You have a "reset" if in there so it sounds like you want the always # (posedge clk or posedge reset). I know you are using always_comb, but I would be curious to know if that actually does remove the issue or not. It would be telling.
EDIT: So I just realized you are doing operations on the LHS variables using the same variables on the RHS. You need to clock this. Otherwise when you combinatorially enter the counting state, it can never resolve as it is always adding in an infinite loop. Do the always # (posedge clk or posedge reset) and you will get better results I think.
Second, and probably more important, it looks like you are using access_index_i < 4 and trying to extract a bit from it to make up the least significant bit of your concatenated vector {access, update, access_index_i < 4}. If you are shifting to the right, I think the logic would insert 4'b0000 in the result and I am guessing it is not really a bit to begin with, so I am wondering what bit actually gets used during the 3'b101 case as it would be addressed by {bit,bit,vector}. Seems like you would want to say {bit,bit,vector[4]} or something to that effect. You might actually be using the least significant 3 bits of the your access_index_i to address your combinational statement.
EDIT: Responding to your comment below. You can, (And this is what I do) break the problem into two parts, the combinatorial and the clocked.
reg [3:0] my_sig;
wire [3:0] my_sig_wire;
always # (posedge clk)
begin
my_sig <= my_sig_wire;
end
always (*)
begin
if(reset)
begin
my_sig_wire = 4'b0000; // This will also reset the clocked version
end
else
begin
my_sig_wire = my_sig; // This is okay, because no matter
// how much I alter my_sig_wire, my_sig will
// only change on the clock pulse. So
// we avoid the infinite loop problem
my_sig_wire[index] = 1'b0; // Tweak one of the signals for fun.
// on the next clock, my_sig is updated!
end
end
Combinatorial blocks define there output purely based on inputs, there is no state.
Sequential elements (flip-flops) contain state and therefore outputs can be based on inputs and state, or just state.
Your default statement:
default: begin
lru_list[0] = lru_list[0];
Is maintaining state by holding a value and therefore can not be combinatorial. You have not defined a flip-flop (#(posedge clk)) so a latch has been inferred to hold the state.

Concatenation operator in System verilog in a loop

I am trying to do the following : concat = {concat[7:0],clk} inside a forever loop as below :
bit [7:0] concat;
concat = 0;
forever begin
#(posedge clk);
concat = {concat[7:0],clk};
end
I wanted to know what value will it contain after 8 clock iterations at any point of time, if the initial value of concat = 0.
Can it be different from 'hAA or 'h55 at any point of time?
You can not just write concat = 0; you should either assign concat = 0; or
initial begin
concat = 0;
end
Forever can not be used like that, the only two top levels you're allowed are initial and always. You want some thing like the following for a simulation:
initial begin
forever begin
#(posedge clk);
concat = {concat[6:0],clk};
end
end
If you are writing for synthesis then you might want to imply a flip-flop:
always #(posedge clk) begin
concat = {concat[6:0],clk};
end
Once you have fixed your RTL it should be easy to try out on EDA Playground.
Since you have #(posdege clk), clk will always be 1 (or x) when evaluating the RHS of the assignment. So concat will be 'h00, 'h01, 'h03, 'h07, 'h17, ...
Also note that if any other thread tries to read concat on the same positive edge of clk, you have a race condition, so please use a NBA to make the assignment.

How can I use a prepared module in a loop in Verilog?

I am trying to generate 128 parellel XOR gates, and then connecting their outputs to 64 XOR gates in Verilog. I use a module that prepared named "EXOR". My problem is: When I put this module "EXOR" into the loop, program gives syntax error "unexpected token: 'EXOR'". And I want to name the gates exor0, exor1, ... .
How can I solve it?
initial begin
for (i=0; i<128 ; i=i +1 )
EXOR exor[i](.I1(m[2*i]), .I2(m[2*i+1]), .o(t[i]));
end
initial begin
for (i=0; i<64 ; i=i +1 )
EXOR exor[i+128](.I1(t[2*i]), .I2(t[2*i+1]), .o(f[i]));
end
initial begin
for (i=0; i<32 ; i=i +1 )
EXOR exor[i+192](.I1(f[2*i]), .I2(f[2*i+1]), .o(g[i]));
end
To elaborate on Munkymorgy's answer what you're looking for here is a generate loop. 'initial' and 'always' blocks are used for "runtime" constructs. Since you're trying to create an array on instances you want something interpreted at elaboration time.
genvar i;
generate
for (i = 0; i < 64; i = i + 1) begin : gen_loop
EXOR exor(.I1(m[2 * i]), .I2(m[2 * i + 1], .o(t[i]));
end
endgenerate
Two things:
1) The loop variable has to be declared as a 'genvar'
2) The for loop needs to be named. This will be used in the hierarchical name of the instance.

Resources