Initializing arrays in Verilog - verilog

How do I initialize the array Save_state? This statement is giving X value at the output:
reg [9:0] count
reg [9:0] Save_state [0: 1024];
always # (posedge Clock )
Count <=count+1 ;
Save_state[count] <=count ;

You can use an initial block as well. This is allowed in simulation and is synthesizable on some architectures (Xilinx FPGA and CPLD support register initialization)
reg [9:0] count
reg [9:0] Save_state [0: 1024];
integer i;
initial begin
count = 0;
for (i=0;i<=1024;i=i+1)
Save_state[i] = 0;
end
always # (posedge Clock ) begin
count <= count + 1;
Save_state[count] <= count;
end
Although for this particular example, in which the elements of the Save_state array will always have the same value, you can do like this (synthesizable on Xilinx and Altera, AFAIK):
reg [9:0] Save_state [0: 1024];
integer i;
initial begin
for (i=0;i<=1024;i=i+1)
Save_state[i] = i[9:0];
end
And at the beginning of you simulation, Save_state already have the values 0,1,2,...,1023 stored in it.

You can use a reset port to initialize count and save_state such as the following code :
integer i;
reg [9:0] count;
reg [9:0] save_state [0:1024];
always #(posedge clock or posedge reset) begin
if (reset) begin
count <= 0;
for (i=0; i<=1024; i=i+1)
save_state[i] <= 0;
end
else begin
count <= count + 1;
save_state[count] <= count;
end
end
The two statements inside the else block is applied at the same time and at the end of always block.

Related

Reading data in verilog

Problem: I'm trying to manipulate 16 bit binary numbers in Verilog. The results I'm getting do not seem to match the expected results. I've isolated the problem in that the testbench.v seems to be sending the wrong values to my classify.v file.
This is what my testbench.v file looks like.
module testbench3();
reg clk, reset; // clock and reset are internal
reg [0:15] data_row;
wire [0:1] actual_class;
reg EN;
reg [0:15] memory [0:2]; //HERE
integer i;
classify dut(.actual_class(actual_class), .data_row(data_row), .EN(EN));
// Set up the system clk
always begin
#5 clk <= !clk;
end
initial begin // ASSIGN 16 bit to memory
memory[0] <= 0001111111000000;
memory[1] <= 0010111111000000;
memory[2] <= 0010111111000000;
end
initial begin
clk <= 0;
EN <= 0;
i <= 0;
reset <= 0;
#27;
reset <= 1;
end
always #(posedge clk) begin
data_row <= memory[i];
i <= i + 1;
$display ("%b", data_row); // HERE
if(i == 3) begin
$display("End simulation");
$finish;
end
EN = 1;
end
endmodule
I'm expecting the console to display:
0001111111000000
0010111111000000
0010111111000000
and what I'm getting are these values instead:
0101111111000000
1110111111000000
1110111111000000
Not sure where these values are coming from.
I'm using Icarus Verilog 0.10.0, if that helps.
When you initialize your memory your are using decimal values, not binary.
Add 16'b to the front:
memory[0] <= 16'b0001111111000000;
memory[1] <= 16'b0010111111000000;
memory[2] <= 16'b0010111111000000;

Verilog Counter - 50MHz to 1Hz clock

How can I use this verilog code to generate a 1Hz clock signal while maintaining the counting functionality? Maxval enables the counter to count up to a certain value and then go back to 0 by reset and start over again. Or, it'll just reset and count again if it hits the maximum value. The thing is, my FPGA has a 50Mhz clock, but I need to use this counter with a 1Hz and a 2Hz clock. Any tips on adapting this code for that purporse?
module clocktime(input clk, freerun, Reset, output, input[7:0] Maxval, output reg[7:0] Count, output reg Carry);
always # (posedge clk or posedge Reset) begin
if ( Reset ) begin
Count <= 0;
Carry <= 0;
end
else
if ( freerun )
if ( Count < Maxval ) begin
Count <= Count + 8'd1;
Carry <= 0;
end
else begin
Count <= 0;
Carry <= 1;
end
end
endmodule
Start with increasing the width of Maxval and Count variables. You'll need 26 bits to fit a number of 50 millions there. Right now with 8 bits you can divide the clock by 255 at most.
To get additional outputs (1hz, 2hz) you can do something like this:
module top(clk50, reset, out_1hz, out_2hz);
input clk50;
input reset;
output out_1hz;
output out_2hz;
reg[25:0] clk50_divisor = 12500000;
reg [1:0] div2_4;
assign out_1hz = div2_4[1];
assign out_2hz = div2_4[0];
wire tmp_4hz;
clocktime div_clk50(
.clk(clk50),
.freerun(1),
.Reset(reset),
.Maxval(clk50_divisor),
.Carry(tmp_4hz));
always #(posedge tmp_4hz)
div2_4 <= div2_4 + 1'd1;
/* another option, might be better in your particular case,
or not different at all
always #(posedge clk50)
if (tmp_4hz)
div2_4 <= div2_4 + 1'd1;
*/
endmodule
module clocktime(clk, freerun, Reset, Maxval, Count, Carry);
input clk;
input freerun;
input Reset;
input [25:0] Maxval;
output reg[25:0] Count;
output reg Carry;
always # (posedge clk or posedge Reset) begin
if ( Reset ) begin
Count <= 0;
Carry <= 0;
end
else
if ( freerun )
if ( Count < Maxval ) begin
Count <= Count + 8'd1;
Carry <= 0;
end
else begin
Count <= 0;
Carry <= 1;
end
end
endmodule

Serializer 32 to 8 - Verilog HDL

I am trying to make serializer from 32bits to 8 bits. Because I am just starting verilog I am facing problem. I would like to get 32 bits (on every 4th clock cycles) and then to send 8 bits on every clock cycle. How can I take just part of my dataIn, I wrote code below but assignment expression is not working. Sorry if question is basic. Thank you in advance on answer.
module ser32to8(clk, dataIn, dataOut);
input clk;
input [32:0] dataIn;
output [7:0] dataOut;
always #(posedge clk)
begin
dataOut <= dataIn << 8;
end
endmodule
The reason why the assignment failed (besides your code not doing any serialization) is because you didn't declare dataOut as a reg, and so you cannot assign to it inside an always block.
Here's how you do it correctly. (Since you didn't say in which order you wanted to serialize, I chose to go for lowest byte first, highest byte last. To reverse the order, exchange >> by << and tmp[7:0] by tmp[31:24].)
module ser32to8(
input clk,
input [31:0] dataIn,
output [7:0] dataOut
);
// count: 0, 1, 2, 3, 0, ... (wraps automatically)
reg [1:0] count;
always #(posedge clk) begin
count <= count + 2'd1;
end
reg [31:0] tmp;
always #(posedge clk) begin
if (count == 2'd0)
tmp <= dataIn;
else
tmp <= (tmp >> 8);
end
assign dataOut = tmp[7:0];
endmodule
How can you just take part of your dataIn data? By using the [] notation. dataIn[7:0] takes the 8 least significant bits, dataIn[15:8] takes the next 8 bits, and so on up to dataIn[31:24] which would take the 8 most significant bits.
To apply this to your problem, you can do like this (take into account that this is not an optimal solution, as outputs are not registered and hence, glitches may occur)
module ser32to8(
input wire clk,
input wire [31:0] dataIn,
output reg [7:0] dataOut
);
reg [1:0] cnt = 2'b00;
always #(posedge clk)
cnt <= cnt + 1;
always #* begin
case (cnt)
2'd0: dataOut = dataIn[7:0];
2'd1: dataOut = dataIn[15:8];
2'd2: dataOut = dataIn[23:16];
2'd3: dataOut = dataIn[31:24];
default: dataOut = 8'h00;
endcase
end
endmodule
You must declare dataOut as a reg, since you are using it in always block.Also, you are trying to assign 32 bit datain to 8 bit dataout , it is not logically correct.
The idea behind the question is not so clear but my guess would be that you want to wait for 4 clock cycles before you send the data, if that is the case below snippet could help, A counter to wait before 4 clock cycles will do the trick
module top (input clk,rst,
input [31:0] dataIn,
output [7:0] dataOut
);
reg [31:0] tmp;
reg [31:0] inter;
integer count;
always #(posedge clk)
begin
if (rst) begin
count <= 0;
tmp <= '0;
end
else
begin
if (count < 3) begin
tmp <= dataIn << 4;
count <= count +1; end
else if (count == 3)
begin
inter <= tmp;
count <= 0;
end
else
begin
tmp <= dataIn;
end
end
end
assign dataOut = inter[7:0];
endmodule
But there are some limitations tested with tb http://www.edaplayground.com/x/4Cg
Note: Please ignore the previous code it won't work(I was not clear so
tried it differently)
EDIT:
If I understand your question correctly a simple way to do it is
a)
module top ( input rst,clk,
input [31:0] dataIn,
output [7:0] dataOut);
reg [1:0] cnt;
always #(posedge clk) begin
if (rst) cnt <= 'b0;
else cnt <= cnt + 1;
end
assign dataOut = (cnt == 0) ? dataIn [7:0] :
(cnt == 1) ? dataIn [15:8] :
(cnt == 2) ? dataIn [23:16] :
(cnt == 3) ? dataIn [31:24] :
'0;
endmodule
Incase if you don't want to write it seperately for loop will come in handy to make it more simple
b)
module top ( input rst,clk,
input [31:0] dataIn,
output reg [7:0] dataOut);
reg [1:0] cnt;
integer i;
always #(posedge clk) begin
if (rst) cnt <= 'b0;
else cnt <= cnt + 1;
end
always # * begin
for ( i =0;i < cnt ; i=i+1) begin
dataOut <= dataIn[(i*8)+:8]; end
end
endmodule
I have tried both with test cases and found to be working, tc's present #
a) http://www.edaplayground.com/x/VCF
b) http://www.edaplayground.com/x/4Cg
You may want to give it a try
You can follow the figure below to design your circuit. Hope it can be useful with you. If you need the code, feel free to contact me.
SER 112 bits with 8 outputs in parallel

calculate how many times input is repeated verilog

I'm trying to calculate times in which input x with 8 bits is repeated on every posedge clk.
I'm thinking about creating 256b counter to each value of these 8 bit to compare x with it, but I get error when I'm trying to compare each value of these counter with each input x on rising edge.
module counter_initial(x);
input[7:0] x;
//output [7:0] y;
//reg [7:0] y;
//reg [7:0] freq_tst,gap_tst;
reg [7:0] freq_num;
endmodule
module counter_256(clk,x,out);
input [7:0] x;
input clk;
// input [7:0] in;
output [7:0] out;
reg [7:0] out;
//reg [7:0] freq_tst,gap_tst;
reg [7:0] k=0;
// reg [] t=0;
genvar i;
generate
for (i=0;i<256;i=i+1)
begin
counter_initial m(i);
//t=m(i);
end
endgenerate
always #(posedge clk)
begin
if(k<256) begin
if (x==m[i])
//counter_initial[k]==x
begin
freq_num=freq_num+1;
end
//else
//begin gap_tst=gap_tst+1; end
k=k+1;
end
end
endmodule
You don't need an additional module to count. You can use a memory array. Example:
input [WIDTH-1:0] x;
reg [7:0] mem [WIDTH-1:0];
integer i;
always #(posedge clk) begin
if (reset) begin
for (i = 0; i < 2**WIDTH; i = i+1) begin
mem[i] <= 8'b0;
end
end
else if (mem[x] < 8'd255) begin // cap counting and prevent overflow
mem[x] <= mem[x] + 1'b1;
end
end
If you want to use separate modules then pass the clock to it. Example:
module counter (output reg [7:0] count, input increment, clk, reset);
always #(posedge clk) begin
if (reset) begin
count <= 8'b0;
end
else if (count < 8'd255) begin // cap counting and prevent overflow
count <= count + increment;
end
end
endmodule
module my_device ( /* ..., */ input [7:0] x, input clk, reset );
/* ... */
genvar i;
generate
for (i=0; i<256; i=i+1) begin
counter icount( .count(/* ... */), .increment(x==i), .* );
end
endgenerate
/* ... */
endmdoule
Reminder 8'd255 + 1 is 8'd0 because the MSB of 8'd256 is out of range. I capped the counters so the will not overflow and roll back to zero.

Reduce array to sum of elements

I am trying to reduce a vector to a sum of all it elements. Is there an easy way to do this in verilog?
Similar to the systemverilog .sum method.
Thanks
My combinational solution for this problem:
//example array
parameter cells = 8;
reg [7:0]array[cells-1:0] = {1,2,3,4,5,1,1,1};
//###############################################
genvar i;
wire [7:0] summation_steps [cells-2 : 0];//container for all sumation steps
generate
assign summation_steps[0] = array[0] + array[1];//for less cost starts witch first sum (not array[0])
for(i=0; i<cells-2; i=i+1) begin
assign summation_steps[i+1] = summation_steps[i] + array[i+2];
end
endgenerate
wire [7:0] result;
assign result = summation_steps[cells-2];
Verilog doesn't have any built-in array methods like SV. Therefore, a for-loop can be used to perform the desired functionality. Example:
parameter N = 64;
integer i;
reg [7:0] array [0:N-1]
reg [N+6:0] sum; // enough bits to handle overflow
always #*
begin
sum = {(N+7){1'b0}}; // all zero
for(i = 0; i < N; i=i+1)
sum = sum + array[i];
end
In critiquing the other answers delivered here, there are some comments to make.
The first important thing is to provide space for the sum to be accumulated. statements such as the following, in RTL, won't do that:
sum = sum + array[i]
because each of the unique nets created on the Right Hand Side (RHS) of the expression are all being assigned back to the same signal called "sum", leading to ambiguity in which of the unique nets is actually the driver (called a multiple driver hazard). To compound the problem, this statement also creates a combinational loop issue because sum is used combinationally to drive itself - not good. What would be good would be if something different could be used as the load and as the driver on each successive iteration of the loop....
Back to the argument though, in the above situation, the signal will be driven to an unknown value by most simulator tools (because: which driver should it pick? so assume none of them are right, or all of them are right - unknown!!). That is if it manages to get through the compiler at all (which is unlikely, and it doesn't at least in Cadence IEV).
The right way to do it would be to set up the following. Say you were summing bytes:
parameter NUM_BYTES = 4;
reg [7:0] array_of_bytes [NUM_BYTES-1:0];
reg [8+$clog2(NUM_BYTES):0] sum [NUM_BYTES-1:1];
always #* begin
for (int i=1; i<NUM_BYTES; i+=1) begin
if (i == 1) begin
sum[i] = array_of_bytes[i] + array_of_bytes[i-1];
end
else begin
sum[i] = sum[i-1] + array_of_bytes[i];
end
end
end
// The accumulated value is indexed at sum[NUM_BYTES-1]
Here is a module that works for arbitrarily sized arrays and does not require extra storage:
module arrsum(input clk,
input rst,
input go,
output reg [7:0] cnt,
input wire [7:0] buf_,
input wire [7:0] n,
output reg [7:0] sum);
always #(posedge clk, posedge rst) begin
if (rst) begin
cnt <= 0;
sum <= 0;
end else begin
if (cnt == 0) begin
if (go == 1) begin
cnt <= n;
sum <= 0;
end
end else begin
cnt <= cnt - 1;
sum <= sum + buf_;
end
end
end
endmodule
module arrsum_tb();
localparam N = 6;
reg clk = 0, rst = 0, go = 0;
wire [7:0] cnt;
reg [7:0] buf_, n;
wire [7:0] sum;
reg [7:0] arr[9:0];
integer i;
arrsum dut(clk, rst, go, cnt, buf_, n, sum);
initial begin
$display("time clk rst sum cnt");
$monitor("%4g %b %b %d %d",
$time, clk, rst, sum, cnt);
arr[0] = 5;
arr[1] = 6;
arr[2] = 7;
arr[3] = 10;
arr[4] = 2;
arr[5] = 2;
#5 clk = !clk;
#5 rst = 1;
#5 rst = 0;
#5 clk = !clk;
go = 1;
n = N;
#5 clk = !clk;
#5 clk = !clk;
for (i = 0; i < N; i++) begin
buf_ = arr[i];
#5 clk = !clk;
#5 clk = !clk;
go = 0;
end
#5 clk = !clk;
$finish;
end
endmodule
I designed it for 8-bit numbers but it can easily be adapted for other kinds of numbers too.

Resources