Instantiate a module number of times based on a parameter value in Verilog - module

Assume we have the following arbitrary parameterized module
module module_x #(parameter WIDTH = 1) (in_a, in_b, out);
input [WIDTH - 1] in_a, in_b;
output out;
// Some module instantiation here
endmodule
How do I instantiate another based on the value of WIDTH ? like if it's 5 I instantiate it 5 times on each bit, is it possible to do this in Verilog ?

Generate statements are a common approach to this: Section 27 page 749 of IEEE 1800-1012.
A quick example :
logic [WIDTH-1:0] a;
logic [WIDTH-1:0] b;
genvar i;
generate
for(i=0; i<WIDTH; i++) begin
module_name instance_name(
.a(a[i]),
.b(a[i])
);
end
endgenerate
As #toolic has pointed out instance arrays are also possible, and simpler.
logic clk;
logic [WIDTH-1:0] a_i;
logic [WIDTH-1:0] b_i;
module_name instance_name[WIDTH-1:0] (
.clk ( clk ), //Single bit is replicated across instance array
.a ( a_i ), //connected wire a_i is wider than port so split across instances
.b ( b_i )
);

Related

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.

4-Bit verilog adder not passing carry bit

I had my 2-bit adder working, except for some reason it is not passing the carry bit. For instance if I use A=1 and B=1 the result S=00, but if either A or B is 1 i get S=1
?i tried printing out the values and it seems my c1 wire in the 2nd module isn't being set, and for some reason Cout is.
So with a input of A=1, B=1, S=00 and Cout=1
when it should be. S=10 and Cout=0
I have only been using Verilog for one day so the syntax is very new to me.
module fulladder(Cin,A,B,S,Cout); // dont forget semi colon
input A,B, Cin; // defaults to 1 bit or [0,0] size
output S, Cout;
wire XOR1,AND1,AND2;
xor(XOR1,A,B);
and(AND1,A,B);
xor(S,Cin,XOR1);
and(AND2,Cin,XOR1);
or(Cout,AND2,AND1);
endmodule
module adder4(Cin,A,B,S,Cout);
input Cin;
input [0:1]A;
input [0:1]B;
output [0:1]S;
output Cout;
wire c1;
fulladder FA1(Cin,A[0:0],B[0:0],S[0:0],c1);
fulladder FA2(c1,A[1:1],B[1:1],S[1:1],Cout);
endmodule
module t_adder;
reg Cin;
reg [1:0]A;
reg [1:0]B;// to declare size, must be on own line, wires can be more than 1 bit
wire [1:0]S;
wire Cout;
adder4 add4bit(Cin,A,B,S,Cout);
initial
begin
A = 1; B = 1; Cin = 0;
#1$display("S=%b Cout = %b",S,Cout);
end
endmodule
You're reversing the bit order in the adder4 module, by declaring the inputs as [0:1], where elsewhere it is [1:0].
Since you reverse the bits, to adder4 it looks like you are adding A=2'b10, B=2'b10, which gives the output you see (3'b100).

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 shift operators?

I'm still trying to get used to some of the quirks of VHDL and I'm having a bit of an issue. First off, I understand that shift operators like rol, ror, ssl, srl, etc. are not synthesizeable. The purpose of this lab is to use a golden model to check against a synthesizeable version of the same thing in a testbench.
Now, the purpose of this program is to convert thermometer code into a 3-bit binary number. So, in other words, thermometer code "00000001" = "001", "00000011" = "010", "00000111" = "011", etc. I'm basically trying to count the number of 1's in the string from right to left. There will be no case where a '0' is placed between the string of 1's, so the vector "00011101" is invalid and will never occur.
I've devised a non-synthesizeable (and so far, non-compile-able) algorithm that I can't figure out how to get working. Basically, the idea is to read the thermometer code, shift it right and increment a counter until the thermometer code equals zero, and then assign the counter value to the 3-bit std_logic_vector. Below is the code I've done so-far.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity therm2bin_g is
port(therm : inout std_logic_vector(6 downto 0); -- thermometer code
bin : out std_logic_vector(2 downto 0); -- binary code
i : integer range 0 to 7);
end therm2bin_g;
architecture behavioral_g of therm2bin_g is
begin
golden : process(therm)
begin
while(therm /= "00000000") loop
therm <= therm srl 1;
i = i + 1;
end loop;
bin <= std_logic'(to_unsigned(i,3));
end process golden;
behavioral_g;
here's a version that is synthesisable. the while loop is replaced by a for loop. srl is implemented explicitly:
entity therm2bin_g is
port(therm : inout std_logic_vector(6 downto 0); -- thermometer code
bin : out std_logic_vector(2 downto 0); -- binary code
i : out integer range 0 to 7);
end therm2bin_g;
architecture behavioral_g of therm2bin_g is
begin
golden : process(therm)
variable i_internal: integer range 0 to 7;
begin
i_internal:=0;
for idx in 0 to therm'length loop
if therm/="0000000" then
therm<='0' & therm(therm'left downto 1);
i_internal := i_internal + 1;
end if;
end loop;
bin<=std_logic_vector(to_unsigned(i_internal,bin'length));
i<=i_internal;
end process golden;
end behavioral_g;
"... operators like rol, ror, ssl, srl, etc. are not synthesizeable..."
Who says that on who's authority? Have you checked? On which synthesis tool? Was it a recent version, or a version from the early 1990s?
Note that the argument that some tools might not support it is just silly. The fact that some kitchens might not have an oven does not stop people from writing recipes for cake.

the buffer and output sequence of cout and printf

I know cout and printf have buffer today, and it is said that the buffer is some like a stack and get the output of cout and printf from right to left, then put them out(to the console or file)from top to bottem. Like this,
a = 1; b = 2; c = 3;
cout<<a<<b<<c<<endl;
buffer:|3|2|1|<- (take “<-” as a poniter)
output:|3|2|<- (output 1)
|3|<- (output 2)
|<- (output 3)
Then I write a code below,
#include <iostream>
using namespace std;
int c = 6;
int f()
{
c+=1;
return c;
}
int main()
{
int i = 0;
cout <<"i="<<i<<" i++="<<i++<<" i--="<<i--<<endl;
i = 0;
printf("i=%d i++=%d i--=%d\n" , i , i++ ,i-- );
cout<<f()<<" "<<f()<<" "<<f()<<endl;
c = 6;
printf("%d %d %d\n" , f() , f() ,f() );
system("pause");
return 0;
}
Under VS2005, the output is
i=0 i++=-1 i--=0
i=0 i++=-1 i--=0
9 8 7
9 8 7
Under g++( (GCC) 3.4.2 (mingw-special)), the output is,
i=0 i++=0 i--=1
i=0 i++=-1 i--=0
9 8 7
9 8 7
It seems that the buffer is like a stack. However, I read C++ Primer Plus today, and it is said that the cout work from left to right, every time return an object(cout), so "That’s the feature that lets you concatenate output by using insertion". But the from left to right way can not explain cout< output 9 8 7
Now I'm confused about how cout's buffer work, can somebody help me?
The output of:
printf("i=%d i++=%d i--=%d\n" , i , i++ ,i-- );
is unspecified. This is a common pitfall of C++: argument evaluation order is unspecified.
Not so with the cout case: it uses chained calls (sequence points), not arguments to a single function, so evaluation order is well defined from left to right.
Edit: David Thornley points out that the behavior of the above code is in fact undefined.
This is not a bug, nor is it anything to do with output buffering.
The order of execution of the i-- and i++ operations is not defined when they're invoked more than once as parameters to the same function call.
To elaborate (and possibly correct) Iraimbilanja's mention of "sequence points", the cout version is equivalent to:
(((cout << a) << b) << c)
Effectively, it's actually three separate function calls, each of whose parameters are evaluated in order, even though it's written like a single statement.
The << operator is really ostream& operator<<(ostream& os, int), so another way of writing this is:
operator<< ( operator<< ( operator<< ( cout, a ), b ), c )
Since for the outer call it's not (AFAIK) defined which order the two parameters are evaluated, it's perfectly possible for the right-hand "c" parameter (or in your case "i--") to happen before the left hand parameter is evaluated.
if possible try updating to gcc >= 4. i just ran this on 4.0.1 and it executes just dandy.