Variable use in VHDL - variables

I was reading some codes in VHDL and saw this example:
signal count : integer range 0 to width;
begin
process(clk, rst)
variable temp : integer range 0 to width;
begin
temp := count + 1;
count <= temp;
end process;
what's the purpose of count signal here? Why can't we just use the variable?

Variables are local to the process, and signals are used to communicate between processes.
So you would rather do without the variable, and in the process just have:
count <= count + 1;

Related

Index out of range error in Verilog, although the register is declared correctly

I am trying to learn Verilog and I have this simple code
module division (
output reg [14:0] A,
input [14:0] D);
reg[4:0] i;
always #(*) begin
for (i = 14; i >= 0; i = i-1) begin
A[0] = D[i];
end
end
endmodule
This returns the error : Index out of range for D.. I have no idea why, since D is declared on that interval. Can you please help me?
I know the code might not make any sense, but I only included the relevant part to the issue.
You have declared i as unsigned, so the expression i >= 0 will always be true.
When i reaches 0, the next iteration is 5'b11111, which is out of range. You should declare i as an integer or add the signed keyword.

Verilog Instantiating module inside a always block. Using Adder for multiplication

I have a code written for multiplying two 53 bit numbers (written below). I am using shift-add strategy using two other 106 bit registers. This code is working fine. Now I have another 53 bit highly optimized hans carlson adder module written in form:
module hans_carlson_adder(input [52:0] a, b, input c_in, output [52:0] sum, output c_out);
I want to use this adder to do the summation line in for loop (mentioned in code). I am having problem instantiating the adder inside an always block. Plus I dont want to have 106 instances (due to for loop) of this adder. Can you please help with this code
module mul1(
output reg [105:0] c,
input [52:0] x,
input [52:0] y,
input clk,
input state
);
reg [105:0] p;
reg [105:0]a;
integer i;
always #(posedge clk) begin
if (state==1) begin
a={53'b0,x[52:0]};
p=106'b0; // needs to zeroed
for(i=0;i<106;i=i+1) begin
if(y[i]) begin
p=p+a; //THIS LINE NEEDS TO BE REPLACED WITH HANS CARLSONADDER
end
a=a<<1;
end
c<=p;
end else begin
c=0;
end
end
endmodule
First you need to instantiate your adder outside of the always block and connect it to signals:
wire [52:0] b;
reg [5:0] count;
assign b = c[count+7'd52:count];
wire [52:0] sum;
wire c_out;
// Add in x depending on the bits in y
// b has the running result bits that still apply at this point
hans_carlson_adder u0(x, b, 1'b0, sum, c_out);
Now because this is a pipelined adder you are going to need something to kick off the multiplication (I'll call that input start) and something that indicates that the result is available (I'll call that output reg done). You'll want to add them to your mul1 module definition. You can choose a slightly different protocol depending on your needs. It appears that you have something that you've been implementing with the input state. I'm also going to use start to initialize during each calculation so that I don't need a separate reset signal.
reg [52:0] shift;
always #(posedge clk) begin
if (start) begin
done <= 0;
count <= 0;
c <= 106'b0;
shift <= y;
end else if (count < 53) begin
if (shift[0]) begin
c[count+7'd52:count] <= sum;
c[count+7'd53] <= c_out;
end
count <= count + 1;
shift = shift >> 1;
end else begin
done <= 1;
end
end
If you want to make an optimization you could end once the shift signal is equal to 0. In this case the done signal would become high as soon as there were no more bits to add into the result, so multiplying by small values of y would take less cycles.

The value of variables in a process after few executions

Let say I have some process in which i have initialized some variable.
process (clk) is
variable integer := 0;
begin
if (clk'event and clk='1') and (integer<32) then
integer := integer +1;
end if;
if (integer = 32) then
BusyOUT <= '1'; -- This is some outside signal
end if;
end proces;
Will this code set integer to 0 each time clk is on rising edge (since it will execute the entire code), or will it initialize integer to 0 only once (on first read rising edge of the clock, since it is in sensitivity list) and than increment it every time the clk is on rising edge until it reaches 32 and than it will activate the control BusyOUT signal (some outer signal) with which it will stop raising integer?
Thanks in advance,
Bojan
Yes, in meanwhile I figured that the part between the process and begin is executed only once.

Is it possible to declare variables in VHDL with an asterisk?

Quite new to VHDL here, so I'm not entirely sure if this is feasible at all, but here goes:
In my test code for some RAM, I have 2 8-bit std_logic_vector variables wdata_a_v and wdata_b_v. This is all I need for the current setup, but if the ratio of read to write data length changes, I will need more variables of the name wdata_*_v. I'm trying to write the code generically so that it will function for any amount of these variables, but I don't want to declare 26 of them in the code when I will likely only need a few.
It would be nice if there was a way to declare a variable like so:
variable wdata_*_v : std_logic_vector (7 downto 0);
that would, behind the scenes, declare all of the variables that fit this framework so that I could write a loop without worrying about running out of variables.
If there's a way to write a function or procedure etc. to make this work, that would be excellent.
Yes, you can go with a 2d array, recipe:
entity TestHelper is
generic (n: natural range 2 to 255 := 8);
end TestHelper;
architecture behavioral of TestHelper is
type array2d is array (n-1 downto 0) of std_logic_vector(7 downto 0);
begin
process
variable a : array2d;
begin
a(0)(0) := '0';
end process;
end architecture behavioral;
EDIT: Now to use it and create similar code for each of wdata_*_v:
process
variable wdata_v : array2d;
begin
someLabel: for i in 0 to n-1 generate
wdata_v(i)(0) := '0';
x <= y and z;
...
end generate;
x <= '1';
...
anotherLabel: for i in 1 to n generate
...
end generate;
...
end process;

VHDL: Counting input values not registering final input

I am working on a vhdl module.
I want to sum up the input values for 6 clock cycles and then set the output high or low depending on if a threshold has been reached.
The problem I am having is that on the last clock cycle, the sum value does not have the final input value added in. I need to have the output high on the rising edge of the clock.
Here is the code:
architecture Behavioral of inputCounter is
signal totalBitWidth : integer := 6;
-- This signal is specified by the user to determine the majority value
-- for the output.
signal majorityValue : integer := 4;
signal Sum : integer := 0;
process(clk, input)
variable clkCount : integer := 0;
begin
if input = '1' then
Sum <= Sum + 1;
else
Sum <= Sum + 0;
end if;
clkCount := clkCount + 1;
if clkCount >= (totalBitWidth) then
-- Determine if the majoritySum variable has met the
-- threshold for a 1 value
if Sum >= majorityValue then
output <= '1';
else
output <= '0';
end if;
if Sum = totalBitWidth Or Sum = 0 then
countError <= '0';
else
countError <= '1';
end if;
-- Reset the clock counter, sum value and majority vector
clkCount := 0;
Sum <= 0;
-- Set the bit counter high to alert other midules that a new bit
-- has been received
bitReady <= '1';
end process;
end behavioral;
If you need more info, let me know.
Thanks for the help.
UPDATE: I was messing around with the sum integer and I changed it to a variable in the process instead of an overall signal in the architecture.
This seems to have worked. But since I am using ISim and ISE Project navigator, I am unable to trace the variable from the process.
The solution for this was to change my signal into a variable in the process.
Here is my code:
architecture Behavioral of inputCounter is
signal totalBitWidth : integer := 6;
signal majorityValue : integer := 4;
-- This signal is to trace the variable sum
signal SumS : integer := 0;
begin
-- Process for recognizing a single input value from a 6 clock cycle
-- wide input signal
majority_proc: process(clk, input)
variable clkCount : integer := 0;
variable Sum : integer := 0;
begin
if rising_edge(clk) And enable = '1' then
-- Reset bitReady after one clock cycle
bitReady <= '0';
-- Check the input value and add it to the Sum variable
if input = '1' then
Sum := Sum + 1;
else
Sum := Sum + 0;
end if;
-- Increment the clock counter variable
clkCount := clkCount + 1;
-- Check if the clock count has reached the specified number of cycles
if clkCount >= totalBitWidth then
-- Determine if the Sum variable has met the threshold for
-- value of 1, set the output accordingly
if Sum >= majorityValue then
output <= '1';
else
output <= '0';
end if;
-- This checks if the value for all clock cycles was the same and
-- sets an error flag if not
if Sum = totalBitWidth Or Sum = 0 then
countError <= '0';
else
countError <= '1';
end if;
-- Reset the clock counter and sum value
clkCount := 0;
Sum := 0;
-- Set the bit counter high to alert other midules that a new bit
-- has been received
bitReady <= '1';
end if;
end if;
-- Assign the variable Sum to the signal SumS
SumS <= Sum;
end process;
end Behavioral;
If you have to change the output at the end of the same clock cycle you get your last input, you need to break apart the accumulator register and the adder. Put the accumulator register and the output compare logic in your process, and pull the adder into asynchronous logic. Abbreviated example code:
process (clk)
if rising_edge(clk) and enable='1' then
accumulator <= sum;
if sum >= majorityValue then
output <= '1';
else
output <= '0';
end if;
end if;
end process;
sum <= accumulator + 1 when input='1' else accumulator;