Using a recursive assignment inside for loop in Verilog - verilog

I am trying to implement a fitness evaluation function in Verilog called Rosenbrock function (https://en.wikipedia.org/wiki/Rosenbrock_function). The issue I am facing is that if I use the following code it gives me a undefined state since there are 4 drivers to the wire fitness_val.
module test_module1 ( x, fitness);
input [4*2 -1:0] x;
output [1:0] fitness;
wire [1:0] x_i;
wire [1:0] x_im1;
wire [3:0] fitness_val;
wire [3:0] a;
wire [3:0] b;
wire [1:0] x_array1 [3:0];
genvar k;
assign fitness = fitness_val;
genvar j;
generate
for (j =0 ; j <4 ; j = j+1) begin
assign x_array1[j] = x[2*j +: 2];
end
for (k=1; k<4; k=k+1) begin
assign x_i = x_array1[k];
assign x_im1 = x_array1[k-1];
assign a = 100*(x_i[1:0] - x_im1[1:0])*(x_i[1:0] - x_im1[1:0]);
assign b = (1 - x_im1[1:0])*(1 - x_im1[1:0]);
assign fitness_val = fitness_val + a[2:1] + b[2:1];
end
endgenerate
endmodule
module tb_tm1();
wire [1:0] fitness;
wire [4*2-1:0] x_array;
test_module1 tm1(x_array, fitness);
assign x_array = 8'b11100100;
endmodule
However if I expand the for loop in this format, I get a valid output.
assign fitness_val = 100*(x_array1[1] - x_array1[0])*(x_array1[1] - x_array1[0]) + (1 - x_array1[0])*(1 - x_array1[0])
+ 100*(x_array1[2] - x_array1[1])*(x_array1[2] - x_array1[1]) + (1 - x_array1[1])*(1 - x_array1[1])
+ 100*(x_array1[3] - x_array1[2])*(x_array1[3] - x_array1[2]) + (1 - x_array1[2])*(1 - x_array1[2]);
Is there a way to implement this recursively in Verilog?

assign statements run concurrently; not sequentially. Generate loops are static unrolled during elaborations. When two assign statements drive different values to the same net, the result will be x.
To do sequential operations you will need to an always block.
Minimum change as follows (plus ANSI style header):
module test_module1 (
input [4*2 -1:0] x,
output [1:0] fitness ); // <-- ANSI style header
reg [1:0] x_i; // 'always' block assign 'reg' type
reg [1:0] x_im1;
reg [3:0] fitness_val;
reg [3:0] a;
reg [3:0] b;
wire [1:0] x_array1 [3:0]; // 'assign' drives 'wire' type
interger k; // index for loop in an always block
genvar j; // index for a generate loop
assign fitness = fitness_val;
generate
for (j =0 ; j <4 ; j = j+1) begin
assign x_array1[j] = x[2*j +: 2];
end
endgenerate
always #* begin // #* is auto-sensitivity, use for combination logic
fitness_val = 4'b0000; // initial value, otherwise it infers a latch
for (k=1; k<4; k=k+1) begin
x_i = x_array1[k];
x_im1 = x_array1[k-1];
a = 100*(x_i[1:0] - x_im1[1:0])*(x_i[1:0] - x_im1[1:0]);
b = (1 - x_im1[1:0])*(1 - x_im1[1:0]);
fitness_val = fitness_val + a[2:1] + b[2:1];
end
end
endmodule
FYI: 4-bits is not enough to hold the value decimal 100. Do Do you want to make it bigger you did you intend the 100 to represent 4 in binary (4'b0100)?

Related

Systemverilog recursion update value for next stage

I am trying to create a recursive logic in Systemverilog but I seem to be missing the right logic to carry the output of one iteration to the next.
Here is an example of the problem:
parameter WIDTH=4;
module test_ckt #(parameter WIDTH = 4)(CK, K, Z);
input CK;
input [WIDTH-1:0] K;
output reg Z;
wire [WIDTH/2-1:0] tt;
wire [WIDTH-1:0] tempin;
assign tempin = K;
genvar i,j;
generate
for (j=$clog2(WIDTH); j>0; j=j-1)
begin: outer
wire [(2**(j-1))-1:0] tt;
for (i=(2**j)-1; i>0; i=i-2)
begin
glitchy_ckt #(.WIDTH(1)) gckt (tempin[i:i], tempin[(i-1):i-1], tt[((i+1)/2)-1]);
end
// How do I save the value for the next iteration?
wire [(2**(j-1))-1:0] tempin;
assign outer[j].tempin = outer[j].tt;
end
endgenerate
always #(posedge CK)
begin
// How do I use the final output here?
Z <= tt[0];
end
endmodule
module glitchy_ckt #(parameter WIDTH = 1)(A1, B1, Z1);
input [WIDTH-1:0] A1,B1;
output Z1;
assign Z1 = ~A1[0] ^ B1[0];
endmodule
Expected topology:
S1 S2
K3--<inv>--|==
|XOR]---<inv>----|
K2---------|== |
|==
<--gckt---> |XOR]
|==
K1--<inv>--|== |
|XOR]------------|
K0---------|== <-----gckt---->
Example input and expected outputs:
Expected output:
A - 1010
----
S1 0 0 <- j=2 and i=3,1.
S2 1 <- j=1 and i=1.
Actual output:
A - 1010
----
S1 0 0 <- j=2 and i=3,1.
S2 0 <- j=1 and i=1. Here, because tempin is not updated, inputs are same as (j=2 & i=1).
Test-bench:
`timescale 1 ps / 1 ps
`include "test_ckt.v"
module mytb;
reg CK;
reg [WIDTH-1:0] A;
wire Z;
test_ckt #(.WIDTH(WIDTH)) dut(.CK(CK), .K(A), .Z(Z));
always #200 CK = ~CK;
integer i;
initial begin
$display($time, "Starting simulation");
#0 CK = 0;
A = 4'b1010;
#500 $finish;
end
initial begin
//dump waveform
$dumpfile("test_ckt.vcd");
$dumpvars(0,dut);
end
endmodule
How do I make sure that tempin and tt get updated as I go from one stage to the next.
Your code does not have any recursion in it. You were trying to solve it using loops, but generate blocks are very limited constructs and, for example, you cannot access parameters defined in other generate iterations (but you can access variables or module instances).
So, the idea is to use a real recursive instantiation of the module. In the following implementation the module rec is the one which is instantiated recursively. It actually builds the hierarchy from your example (I hope correctly).
Since you tagged it as system verilog, I used the system verilog syntax.
module rec#(WIDTH=1) (input logic [WIDTH-1:0]source, output logic result);
if (WIDTH <= 2) begin
always_comb
result = source; // << generating the result and exiting recursion.
end
else begin:blk
localparam REC_WDT = WIDTH / 2;
logic [REC_WDT-1:0] newSource;
always_comb // << calculation of your expression
for (int i = 0; i < REC_WDT; i++)
newSource[i] = source[i*2] ^ ~source[(i*2)+1];
rec #(REC_WDT) rec(newSource, result); // << recursive instantiation with WIDTH/2
end // else: !if(WIDTH <= 2)
initial $display("%m: W=%0d", WIDTH); // just my testing leftover
endmodule
The module is instantiated first time from the test_ckt:
module test_ckt #(parameter WIDTH = 4)(input logic CK, input logic [WIDTH-1:0] K, output logic Z);
logic result;
rec#(WIDTH) rec(K, result); // instantiate first time )(top)
always_ff #(posedge CK)
Z <= result; // assign the results
endmodule // test_ckt
And your testbench, a bit changed:
module mytb;
reg CK;
reg [WIDTH-1:0] A;
wire Z;
test_ckt #(.WIDTH(WIDTH)) dut(.CK(CK), .K(A), .Z(Z));
always #200 CK = ~CK;
integer i;
initial begin
$display($time, "Starting simulation");
CK = 0;
A = 4'b1010;
#500
A = 4'b1000;
#500 $finish;
end
initial begin
$monitor("Z=%b", Z);
end
endmodule // mytb
Use of $display/$monitor is more convenient than dumping traces for such small examples.
I did not do much testing of what I created, so there could be issues, but you can get basic ideas from it in any case. I assume it should work with any WIDTH which is power of 2.

Verilog Temporary Variable

I tried to make a CMP instruction in Verilog. To keep the result of the substraction, I declared a wire. This is what the code looks like (It is executed in an always statement).
wire [data_width:0] tmp_wire = reg_accumulator - reg_x;
f_zero <= tmp_wire & 'hFF == 0;
f_carry <= tmp_wire & 'h100;
Now Icarus Verilog complains about a syntax error and that reg_accumulator - reg_x is not an l-value:
cpu.v:149: syntax error
cpu.v:149: Syntax in assignment statement l-value.
And why does it complain? What would be the right approach to declare a temporary variable in a function / task?
module comparator(
input clk,
input [7:0] op_a,
input [7:0] op_b
);
reg f_zero;
reg f_carry;
function compare;
input [data_width-1:0] a;
input [data_width-1:0] b;
begin
wire [7:0] tmp_wire = reg_accumulator - reg_x;
f_zero <= tmp_wire & 'hFF == 0;
f_carry <= tmp_wire & 'h100;
end
endfunction
always #(posedge clk) begin
compare(op_a, op_b);
end
endmodule // comparator
Either you should use systemverilog and include this in a class or you can create a parameterized module:
module compare_zero_n_carry
# (
parameter DATA_WIDTH = 8
)
(zero, carry, a, b);
/* ports */
input [DATA_WIDTH-1:0] a; //.."reg_accumulator"
input [DATA_WIDTH-1:0] b; //.."reg_x"
output zero;
output carry;
wire [DATA_WIDTH-1:0] tmp_wire = a - b;
assign zero = (tmp_wire & {DATA_WIDTH{1'b1}}) == {DATA_WIDTH{1'b0}};
//..HERE IM NOT REALLY SURE WHAT IS THE LOGIC FOR THE CARRY,
//..IT SHOULD BE ONE BIT
assign carry = (tmp_wire & {1'b1,{(DATA_WIDTH-1){1'b0}}});
endmodule // compare_zero_n_carry
And instantiate it in the main comparator module as:
input clk;
input [DATA_WIDTH-1:0] op_a;
input [DATA_WIDTH-1:0] op_b;
wire f_zero;
wire f_carry;
reg f_zero_reg;
reg f_carry_reg;
compare_zero_n_carry
# (
.DATA_WIDTH (DATA_WIDTH)
)
compare_zero_n_carry_inst (
.a (op_a),
.b (op_b),
.zero (f_zero),
.carry (f_carry)
);
always # (posedge clk) begin
f_zero_reg <= f_zero;
f_carry_reg <= f_carry;
end
You cannot declare a wire inside the always block.
wire [7:0] tmp_wire = reg_accumulator - reg_x;
always #(posedge clk) begin
f_zero <= tmp_wire & 'hFF == 0;
f_carry <= tmp_wire & 'h100;
end

how to concatenate a row buffer into a register in Verilog

I have a problem with this
wire [7:0] table [0:999];
wire [8*1000-1:0] y;
assign y = {table[0], table[1], table[2], ...., table[999]}; // this line code is right, I don't want hard code
I want y is all 1000 values of table but I don't know how to assign all values in 1 line of code( or 2,3). code assign above is right but if there is 100000 values, do I have to type 100000 times?
You can use a for loop but your problem is the sensitivity list. Not all simulators allow two dimensional arrays as sensitivity argument.
wire [7:0] tbl [0:999];
reg [8*1000-1:0] y; // <<== Needs to be reg
integer i;
always #( tbl ) // <<== may give error/warning
for (i=0; i<1000; i=i+1)
y[i*8 +: 8] = tbl[i];
As long as you are using Verilog-2001 or higher, you can use:
wire [7:0] table [0:999];
reg [8*1000-1:0] y;
integer i;
always #* begin
for (i=0; i<1000; i=i+1) begin
y[ i*8 +: 8] = table[i];
end
end
See: Indexing vectors and arrays with +:
Verilog-95 solution is not as pretty and has more overhead:
wire [7:0] table [0:999];
reg [8*1000-1:0] y;
integer i;
always #( table ) begin
y = {8000{1'b0}};
for (i=999; i>=0; i=i-1) begin
y = {[8*999-1:0],table[i]};
end
end
If you can use SystemVerilog, it can be done in one step with bitsteaming
wire [7:0] table [1000];
wire [8*1000-1:0] y = {<<8{table}};

How I can find maximum number in verilog array

So, I have a reg[7:0] corr_Output[0:63]; which is filled with values in my module. How I can find maximum number in this array at one CLK cycle?
I wrote a 8 bit comparator:
module Comparator2D(
input [7:0] X1,
input [7:0] indexX1,
input [7:0] X2,
input [7:0] indexX2,
output [7:0] Y,
output [7:0] indexY
);
always begin
if (X1 > X2) begin
Y = X1;
indexY = indexX1;
end
else begin
Y = X2;
indexY = indexX2;
end
end
endmodule
But I dont know how I should instantiate this module in my top design? I think I should use "for loop", or even write another module which will concatenate my Comparator2D module in pyramid form, but as I found I cant pass whole array to input port of module, so Im a little stuck..
You can do it by using for/generate, like in this code sample, in which I can compare 8 bytes at a time.
The key point is that I cannot pass a memory as input (an array of registers), but I can pass an array of bits that hold the current values from memory.
// This is just your compare module.
module C2D (
input wire [7:0] X1,
input wire [7:0] indexX1,
input wire [7:0] X2,
input wire [7:0] indexX2,
output reg [7:0] Y,
output reg [7:0] indexY
);
always #* begin
if (X1 > X2) begin
Y = X1;
indexY = indexX1;
end
else begin
Y = X2;
indexY = indexX2;
end
end
endmodule
// Compare 8 bytes at a time
module greatest8bytes (
input wire [63:0] array, // 8 byte array
output wire [7:0] indexG,
output wire [7:0] valueG
);
wire [7:0] value_l1[0:3];
wire [7:0] index_l1[0:3];
genvar i;
generate
for (i=0;i<8;i=i+2) begin :gen_comps_l1
C2D cl1 (array[i*8+7:i*8],
i,
array[(i+1)*8+7:(i+1)*8],
(i+1),
value_l1[i/2],
index_l1[i/2]
);
end
endgenerate
wire [7:0] value_l2[0:1];
wire [7:0] index_l2[0:1];
generate
for (i=0;i<4;i=i+2) begin :gen_comps_l2
C2D cl2 (value_l1[i],
index_l1[i],
value_l1[i+1],
index_l1[i+1],
value_l2[i/2],
index_l2[i/2]
);
end
endgenerate
wire [7:0] value_l3[0:0];
wire [7:0] index_l3[0:0];
generate
for (i=0;i<2;i=i+2) begin :gen_comps_l3
C2D cl3 (value_l2[i],
index_l2[i],
value_l2[i+1],
index_l2[i+1],
value_l3[i/2],
index_l3[i/2]
);
end
endgenerate
assign indexG = index_l3[0];
assign valueG = value_l3[0];
endmodule
The greatest8bytes module is synthesized the way you expect: as a pyramid-like arrangement of comparators:
To connect an array of regs (a memory) to the input of this module, create a wire of the desired number of bits (64 in this example) and concatenate all elements of memory, like in this example module:
module findgreatest (
input wire clk,
input wire [2:0] addr,
input wire [7:0] data,
input wire we,
output wire [2:0] indexG,
output wire [7:0] valueG
);
reg [7:0] memory[0:7]; // 8 bytes
// To load data from the outside so the synthesizer won't throw away memory
always #(posedge clk) begin
if (we)
memory[addr] <= data;
end
wire [63:0] array = {memory[7],memory[6],memory[5],memory[4],
memory[3],memory[2],memory[1],memory[0]};
greatest8bytes compar (array, indexG, valueG);
endmodule
Not sure if this is synthesizable, but it is good to know that SystemVerilog has built in min and max functions:
module maximum ();
reg[7:0] corr_Output[0:63] = '{0:8'd112, 2:8'd250, 3:8'd37, 4:8'd15, default:8'd25};
reg[7:0] max_i[$];
reg[7:0] min_i[$];
initial begin
max_i = corr_Output.max;
min_i = corr_Output.min;
$display ("max=%d, min=%d", max_i[0], min_i[0]);
end
endmodule
Output:
# max=250, min= 15
Alternatively, it is probably shorter to just use this classic and synthesizable for-loop of comparisons:
always_comb begin
max = corr_Output[0];
for (c = 0; c <= 63; c++)
begin
if (corr_Output[c] > max)
begin
max = array[c];
index = c;
end
end

Verilog code adding two integers generated by a for loop

How about this? I'm looking for an output i+j=1+2, 2+3... 4+5.
module add(i,j,b);
input [31:0] i, j; //32 bit unsigned
output [31:0] y;
task ADD(i, j, y);
begin
for (i= 1; i <= 4; i++)
begin
for(j=2; j <= 5; j++)
assign y = i + j;
end
end
$display("y ", y);
endtask
endmodule
Is this intended for synthesis? If so you should probably avoid using tasks until you have learnt when they can be used. I never use them in synthesisable code.
functions on the other hand are often used for synthesis but can not contain timing information. Ie a function can only represent combinatorial logic, that all happens in an instant.
1) That is not how you use assign. The correct use would be:
wire [9:0] a;
assign a = 10'b0;
//or
//a,b both 10 bits driven from other logic
wire [9:0] sum;
assign sum = a + b;
Note how you assign to a wire, this is combinatorial.
2) Your display is outside of the for loop it will only display once at the end.
I would have done this some thing like:
module add(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
assign sum = a + b ;
endmodule
module testharness();
reg [31:0] a;
reg [31:0] b;
wire [31:0] sum;
reg clock;
// Make clock toggle every 10ns (20ns clock period)
initial begin
clock = 0;
forever begin
#10ns clock= ~clock;
end
end
//DUT (Device Under Test)
add add_0 (
.a ( a ),
.b ( b ),
.sum ( sum )
);
// Test program
initial begin
a=0;
b=0;
#(posedge clock);
$display( "a (%2d) + b (%2d) = sum (%2d)", a, b, sum );
a=1;
b=2;
#(posedge clock);
$display( "a (%2d) + b (%2d) = sum (%2d)", a, b, sum );
a=3;
b=4;
#(posedge clock);
$display( "a (%2d) + b (%2d) = sum (%2d)", a, b, sum );
$finish;
end
endmodule
Note how we have used time to separate the results, for more complicated designs you may use flip-flops which means you only get a new result per clock. Or per rising and falling edge if using DDR techniques.
You can now try to modify the test program section to stimulate the DUT as per your requirements.

Resources