Generating number sequence in verilog (automat) - verilog

I was given a task to create verilog code that generates number sequence 323135343355.
It should be generated like automat so it has states and next number in sequence is generated according to its previous output.
Task should be done in two ways.
First one is that sequence is generated in eternity (solved that one, but still wonder can my code be reduced.)
Second one is when sequence is generated once output should be only one number that repeats (for example 32313534335511111111111111....) I tried this one by settinf if statment but default case always outputs 4 if all demands are not met.
//implementation
module prvi(
output reg [3:0] out,
input clk, restart
);
reg [3:0] state;
always#(posedge clk)
begin
if(restart)
begin
out<=3;
state<=5;//state is set to 5 because previos number is 5
end
else
begin
case(out)
3:begin
if(state==5)
begin
out<=2;
state<=2;//state is set to 2 because it is our output
end
else if(state==2)
begin
out<=1;
state<=1;//output is 1 so state is 1
end
else if(state==1)
begin
out<=5;
state<=0;//state is 0 because 5 already in use 0=STATE WHEN 3534
end
else if(state==0)
begin
out<=4;
state<=4;//output is 4 so state is 4
end
else if(state==4)
begin
out<=3;
state<=3;//output is 3 so state is 3 BUT STATE AT 4335
end
else if(state==3)
begin
out<=5;
state<=6;//5 ALREADY IN USE SO STATE=6 IS FOR 355
end
end
2:begin
out<=3;
state<=2;
end
1:begin
out<=3;
state<=1;
end
5:begin
if(state==6)
begin
out<=5;
state<=3;
end
else if(state==3)
begin
out<=3;
state<=5;
end
else if(state==0)
begin
out<=3;
state<=0;
end
end
4:begin
out<=3;
state<=4;
end
default:begin
out<=4;
state<=4;
end
endcase
end
end
endmodule
//test module
module test_prvi;
// Inputs
reg clk;
reg restart;
// Outputs
wire [3:0] out;
// Instantiate the Unit Under Test (UUT)
prvi uut (
.out(out),
.clk(clk),
.restart(restart)
);
initial begin
// Initialize Inputs
clk = 0;
restart = 0;
#60 restart=1;
#9 restart=0;
// Wait 100 ns for global reset to finish
#200 $stop;
// Add stimulus here
end
always begin
#3 clk=~clk;
end
endmodule

but still wonder can my code be reduced
Here is a possible solution which reduces your code size: store the sequence in a variable and just retrieve what is needed every cycle, without creating a classic state machine:
module prvi(
output reg [3:0] out,
input clk, restart
);
reg [48-1:0] state;
reg [3:0] count;
always#(posedge clk)
begin
if(restart)
begin
count <= 0;
state <= 48'h553343531323; // reverce of 323135343355
end
else if (count == 12)
begin
out <= 4'h1;
end
else
begin
count <= count + 1;
out <= state & 4'hf;
state <= state >> 4;
end
end
endmodule
To simplify code and demonstrate the concept I used right shift >> and for that reason reversed your sequence of numbers. When count reaches 12 (length of the sequence), the result will always be '1'. The signal width you need is 12 * 4 = 48, 4 bits per hex digit. Decimal digits are a subset of hex.
You can use direct sequences or two-dimensional arrays to achieve it.

Related

Verilog Synchronous 4 bit Counter stay on max value until given signal

So I have my counter in verilog which is 4 bits and I want it to stay on max value, 1111, until I give it a signal to start counting from 0000 again.
Here's what I've been able to come up with so far:
module contadorAscMax
(
input iClk,
input iRst,
output oQ,
input iCE,
input iSignal,
output [3:0] orCnt
);
reg[3:0] rvCnt_d;
reg[3:0] rvCnt_q;
assign orCnt = rvCnt_q;
always #(posedge iClk or posedge iRst)
begin
if(iRst)
begin
rvCnt_q<=4'b0;
end
else
begin
if(iCE)
begin
rvCnt_q<=rvCnt_d;
end
else
begin
rvCnt_q<=rvCnt_q;
end
end
end
always #*
begin
rvCnt_d=rvCnt_q+4'b1;
if(rvCnt_d == 4'b1111)
begin
rvCnt_d = rvCnt_d;
end
else if(rvCnt_d == 4'b1111 & iSignal)
begin
rvCnt_d = 4'b0;
end
end
endmodule
But it just won't wait for the signal. I am very new to verilog so my code probable doesn't make much sense to a hardware guy, since I am a software engineer so sorry if there are some rookie mistakes here.
As for the testbench, here is what I have:
`timescale 1ns / 1ps
module vtfContMax;
// Inputs
reg iClk;
reg iRst;
reg iCE;
reg iSignal;
// Outputs
wire oQ;
wire [3:0] orCnt;
// Instantiate the Unit Under Test (UUT)
contadorAscMax uut (
.iClk(iClk),
.iRst(iRst),
.oQ(oQ),
.iCE(iCE),
.iSignal(iSignal),
.orCnt(orCnt)
);
initial begin
// Initialize Inputs
iClk = 1;
iRst = 1;
iCE = 1;
iSignal = 0;
// Wait 100 ns for global reset to finish
#10;
iRst = 0;
repeat(10)
begin
repeat(10)
begin
wait(iClk);
wait(!iClk);
end
end
$stop();
// Add stimulus here
end
always
begin
#5;
iClk = ~iClk;
#10
iSignal = ~iSignal;
end
endmodule
Thanks for any help :)
You have split the code in a register and combinatorial section. Although that is a good idea for complex logic, for a simple 4 bit counter it is a bit over the top.
For solving your problem you are close. The trick with code like this, is to make the definition using 'programming' language. Then the code flows from that.
I want to have a counter which goes from 1111 to 0000 when a signal is present, else I want it to count up.
This then leads to:
always #(clk or posedge reset)
begin
if (reset)
count <= 4'b1111;
else
begin
if (count==4'b1111 && start_signal)
count <= 4'b0000;
else
count <= count + 4'b0001
end
end
What you don't mention, but what I see from your code you also have an enable (iCE) and an unused output oQ. The total then becomes:
module contadorAscMax
(
input iClk,
input iRst,
// output oQ,
input iCE,
input iSignal,
output reg [3:0] orCnt
);
always #(iClk or posedge iRst)
begin
if (iRst)
orCnt <= 4'b0000; // or should that be 4'b1111
// Is this really what you want?
// It will start counting after a reset!
else
begin
if (iCE)
begin
if (orCnt==4'b1111 && iSignal)
orCnt <= 4'b0000;
else
orCnt <= orCnt+ 4'b0001;
end
end
end
endmodule
Some more remarks:
Your reset condition looks flawed to me but you have to solve that.
Give the counter enable signal a decent name: 'count_enable' not 'signal'.
Last: I would not use all the 'i's and 'o's. The 'o' signals from one module will be the 'i' of another. Thus you have to change the signal names somewhere. It is better to have a defined signal in your system. If only so you can find in the timing report or gates after synthesis.

Verilog: wait for module logic evaluation in an always block

I want to use the output of another module inside an always block.
Currently the only way to make this code work is by adding #1 after the pi_in assignment so that enough time has passed to allow Pi to finish.
Relevant part from module pLayer.v:
Pi pi(pi_in,pi_out);
always #(*)
begin
for(i=0; i<constants.nSBox; i++) begin
for(j=0; j<8; j++) begin
x = (state_value[(constants.nSBox-1)-i]>>j) & 1'b1;
pi_in = 8*i+j;#1; /* wait for pi to finish */
PermutedBitNo = pi_out;
y = PermutedBitNo>>3;
tmp[(constants.nSBox-1)-y] ^= x<<(PermutedBitNo-8*y);
end
end
state_out = tmp;
end
Modllue Pi.v
`include "constants.v"
module Pi(in, out);
input [31:0] in;
output [31:0] out;
reg [31:0] out;
always #* begin
if (in != constants.nBits-1) begin
out = (in*constants.nBits/4)%(constants.nBits-1);
end else begin
out = constants.nBits-1;
end
end
endmodule
Delays should not be used in the final implementation, so is there another way without using #1?
In essence i want PermutedBitNo = pi_out to be evaluated only after the Pi module has finished its job with pi_in (=8*i+j) as input.
How can i block this line until Pi has finished?
Do i have to use a clock? If that's the case, please give me a hint.
update:
Based on Krouitch suggestions i modified my modules. Here is the updated version:
From pLayer.v:
Pi pi(.clk (clk),
.rst (rst),
.in (pi_in),
.out (pi_out));
counter c_i (clk, rst, stp_i, lmt_i, i);
counter c_j (clk, rst, stp_j, lmt_j, j);
always #(posedge clk)
begin
if (rst) begin
state_out = 0;
end else begin
if (c_j.count == lmt_j) begin
stp_i = 1;
end else begin
stp_i = 0;
end
// here, the logic starts
x = (state_value[(constants.nSBox-1)-i]>>j) & 1'b1;
pi_in = 8*i+j;
PermutedBitNo = pi_out;
y = PermutedBitNo>>3;
tmp[(constants.nSBox-1)-y] ^= x<<(PermutedBitNo-8*y);
// at end
if (i == lmt_i-1)
if (j == lmt_j) begin
state_out = tmp;
end
end
end
endmodule
module counter(
input wire clk,
input wire rst,
input wire stp,
input wire [32:0] lmt,
output reg [32:0] count
);
always#(posedge clk or posedge rst)
if(rst)
count <= 0;
else if (count >= lmt)
count <= 0;
else if (stp)
count <= count + 1;
endmodule
From Pi.v:
always #* begin
if (rst == 1'b1) begin
out_comb = 0;
end
if (in != constants.nBits-1) begin
out_comb = (in*constants.nBits/4)%(constants.nBits-1);
end else begin
out_comb = constants.nBits-1;
end
end
always#(posedge clk) begin
if (rst)
out <= 0;
else
out <= out_comb;
end
That's a nice piece of software you have here...
The fact that this language describes hardware is not helping then.
In verilog, what you write will simulate in zero time. it means that your loop on i and j will be completely done in zero time too. That is why you see something when you force the loop to wait for 1 time unit with #1.
So yes, you have to use a clock.
For your system to work you will have to implement counters for i and j as I see things.
A counter synchronous counter with reset can be written like this:
`define SIZE 10
module counter(
input wire clk,
input wire rst_n,
output reg [`SIZE-1:0] count
);
always#(posedge clk or negedge rst_n)
if(~rst_n)
count <= `SIZE'd0;
else
count <= count + `SIZE'd1;
endmodule
You specify that you want to sample pi_out only when pi_in is processed.
In a digital design it means that you want to wait one clock cycle between the moment when you are sending pi_in and the moment when you are reading pi_out.
The best solution, in my opinion, is to make your pi module sequential and then consider pi_out as a register.
To do that I would do the following:
module Pi(in, out);
input clk;
input [31:0] in;
output [31:0] out;
reg [31:0] out;
wire clk;
wire [31:0] out_comb;
always #* begin
if (in != constants.nBits-1) begin
out_comb = (in*constants.nBits/4)%(constants.nBits-1);
end else begin
out_comb = constants.nBits-1;
end
end
always#(posedge clk)
out <= out_comb;
endmodule
Quickly if you use counters for i and j and this last pi module this is what will happen:
at a new clock cycle, i and j will change --> pi_in will change accordingly at the same time(in simulation)
at the next clock cycle out_comb will be stored in out and then you will have the new value of pi_out one clock cycle later than pi_in
EDIT
First of all, when writing (synchronous) processes, I would advise you to deal only with 1 register by process. It will make your code clearer and easier to understand/debug.
Another tip would be to separate combinatorial circuitry from sequential. It will also make you code clearer and understandable.
If I take the example of the counter I wrote previously it would look like :
`define SIZE 10
module counter(
input wire clk,
input wire rst_n,
output reg [`SIZE-1:0] count
);
//Two way to do the combinatorial function
//First one
wire [`SIZE-1:0] count_next;
assign count_next = count + `SIZE'd1;
//Second one
reg [`SIZE-1:0] count_next;
always#*
count_next = count + `SIZE'1d1;
always#(posedge clk or negedge rst_n)
if(~rst_n)
count <= `SIZE'd0;
else
count <= count_next;
endmodule
Here I see why you have one more cycle than expected, it is because you put the combinatorial circuitry that controls your pi module in you synchronous process. It means that the following will happen :
first clk positive edge i and j will be evaluated
next cycle, the pi_in is evaluated
next cycle, pi_out is captured
So it makes sense that it takes 2 cycles.
To correct that you should take out of the synchronous process the 'logic' part. As you stated in your commentaries it is logic, so it should not be in the synchronous process.
Hope it helps

What is meant by the error: "Decimal constant 123456745678901 is too large, using -2089244619 instead" in a Verilog HDL program?

I got this errror for a fast multiplication algo program. The program has no error in syntax and generates correct output for LOW DIGIT NUMBERS (a,b<12). In my program a = 123456745678901, b = 098765467845623 is the multipicand and multiplier respectively. The test bench was also added.
`timescale 1ns / 1ps
module multiply (a,b,s);
parameter n=200;
input [0:n-1] a,b;
output reg [0:2*n-1] s;
wire [0:n-1] num0,num1,pow0,pow1;
reg [0:n-1] num00,num01;
numdigits a0(a,num0); // count the number of digits
numdigits a1(b,num1); // count the number of digits
powerof2 a2(num0,pow0);// checks the distance between num0 and the next power of 2
powerof2 a3(num1,pow1);// checks the distance between num1 and the next power of 2
always #(*)
begin
if(pow0==0&&pow1==0&&num0==num1)
begin
// 1st type of task
split00 (a,b,num0,s);
end
else if (pow0==0&&pow1==0&&num0>num1)
begin
split00 (a,b,num0,s);
end
else if (pow0==0&&pow1==0&&num0<num1)
begin
split00 (a,b,num1,s);
end
else if(pow0!=0 || pow1!=0 )
begin
// 1st type of task
if(num0>num1)
begin
num00=num0+pow0;
split00 (a,b,num00,s);
end
else
begin
num01=num1+pow1;
split00(a,b,num01,s);
end
end
end
task automatic split00;
input [0:n-1] a;
input [0:n-1] b;
input [0:n-1] num0;
output [0:2*n-1] s;
reg [0:n-1] a0,b0,u0,v0,w0,s0,s1,a1,b1,a2,b2,u1,w1,v1;
reg [0:n-1] num00,num;
begin
num00=num0;
/*if(num00==2)
begin
u0=(a/10)*(b/10);
w0=(a%10)*(b%10);
if ((a%10-a/10)<(b%10-b/10))
begin
v0=((a%10-a/10)*(b/10-b%10));
s=u0*100+(u0+w0+v0)*10+w0;
end
if ((a%10-a/10)>(b%10-b/10))
begin
v0=(a%10-a/10)*(b%10-b/10);
s=u0*100+(u0+w0-v0)*10+w0;
end
else
begin
v0=((a%10-a/10)*(b/10-b%10));
s=u0*100+(u0+w0+v0)*10+w0;
end
end */
if(num00==2)
begin
u0=((a/10)*(b/10));
w0=((a%10)*(b%10));
if((a%10)<(a/10))
begin
v0=(((a/10)-(a%10))*((b%10)-(b/10)));
s=((u0*100)+((u0+w0+v0)*10)+w0);
end
else if((b%10)<(b/10))
begin
v0=(((a%10)-(a/10))*((b/10)-(b%10)));
s=((u0*100)+((u0+w0+v0)*10)+w0);
end
else
begin
v0=(((a%10)-(a/10))*((b%10)-(b/10)));
s=((u0*100)+((u0+w0-v0)*10)+w0);
end
end
else
begin
num=num00/2;
a0=a/(10**(num00/2));
a1=a%(10**(num00/2));
b0=b/(10**(num00/2));
b1=b%(10**(num00/2));
split00(a0,b0,num,u1);
split00(a1,b1,num,w1);
if(a1<a0 && b1>b0)
begin
a2=a0-a1;
b2=b1-b0;
split00(a2,b2,num,v1);
s=u1*(10**num00)+(u1+v1+w1)*(10**(num00/2))+w1;
end
else if(a1>a0 && b1<b0)
begin
a2=a1-a0;
b2=b0-b1;
split00(a2,b2,num,v1);
s=u1*(10**num00)+(u1+v1+w1)*(10**(num00/2))+w1;
end
else if(a1<a0 && b1<b0)
begin
a2=a0-a1;
b2=b0-b1;
split00(a2,b2,num,v1);
s=u1*(10**num00)+(u1-v1+w1)*(10**(num00/2))+w1;
end
else
begin
a2=a1-a0;
b2=b1-b0;
split00(a2,b2,num,v1);
s=u1*(10**num00)+((u1-v1+w1)*(10**(num00/2)))+w1;
end
end
end
endtask
endmodule
///testbench///
module karastubatest;
// Inputs
reg [0:199] a;
reg [0:199] b;
// Outputs
wire [0:399] s;
// Instantiate the Unit Under Test (UUT)
multiply uut (
.a(a),
.b(b),
.s(s)
);
initial begin
// Initialize Inputs
a = 48'd123456745678901;
b = 48'd198765467845623;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
end
endmodule
I am going to assume the error message in the title of your question is from the testbench used to stimulate your design. The default implicit size of a simple number is 32 bits. Decimal 123456745678901 requires at least 48 bits, so you need to write this as 48'd123456745678901. 200'd123456745678901 would be best.
123456745678901 indeed requires 48 bits.
11100000100100010000011011110001010100000110101
the tools only take the lower 32 (as explained by dave_59):
10000011011110001010100000110101
Which, interpreted as 2-complement, yields:
-2089244619
as in the error message.

Verilog code to count Number Repetition

I'm writing verilog code for an algorithm,but I have a problem with one module that receives for example:10 binary numbers (4 bits for each one)from previous module (1 input at every positive edge clk) so there are 10 clock cycles to have the 10 binary numbers.
How to Calculate the number of times each number repeats and save the frequency for each number for later use by another module using verilog hardawre language?
for example : at the end this module find 0000 twice ,0001 once,....,1111 zero. at the 10 clock cycles.
Thanks in advance...
Assuming you have a clock and active low reset:
module tracker(
input clk,
input rst_n,
input [3:0] data_rx
);
reg [7:0] count [0:15];
integer i;
always #(posedge clk, negedge rst_n) begin
if (~rst_n) begin
for(i=0; i<16, i=i+1) begin
count[i] <= 8'b0;
end
end
else begin
count[data_rx] <= count[data_rx] + 1;
end
end
endmodule
For an FPGA defaults an initial block can be used instead of the reset signal that could look like:
initial begin
for(i=0; i<16, i=i+1) begin
count[i] <= 8'b0;
end
end
always #(posedge clk) begin
count[data_rx] <= count[data_rx] + 1;
end
Note that a for loop has been used in the asynchronous reset and initial, This can be statically unrolled, there is no dynamic target so is fully synthesizable.

Cannot find why value doesn't jump to expectation in the right time

I have the following code
module POLY(CLK,RESET_n,IN_VALID,IN,OUT_VALID,OUT);
input CLK,RESET_n,IN_VALID;
input [ 3:0] IN;
output OUT_VALID;
output [12:0] OUT;
reg OUT_VALID;
reg [12:0] OUT;
reg OUT_VALID_w;
reg [12:0] OUT_w;
reg [ 1:0] COUNT_IN, COUNT_IN_w;
reg [ 2:0] COUNT_DO, COUNT_DO_w;
always #(posedge CLK or negedge RESET_n)
begin
if(!RESET_n)
begin
COUNT_IN <= 2'd0;
COUNT_DO <= 3'd0;
end
else
begin
COUNT_IN <= COUNT_IN_w;
COUNT_DO <= COUNT_DO_w;
end
end
always #(*)
begin
if(IN_VALID == 1'b0)
begin
if(COUNT_DO == 3'd7)
begin
COUNT_DO_w = COUNT_DO;
end
else
begin
COUNT_DO_w = COUNT_DO + 1'b1;
end
end
else
begin
COUNT_DO_w = 3'd0;
end
end
I want to ask is that why COUNT_DO doesn't jump to 1 in 14ns?
I think that due to the sensitive list in the second always block is COUNT_DO and IN_VALID,
so at start, the reset signal trigger first always block and set the COUNT_DO = 0, which change the COUNT_DO value from high impedence to 0. So, it triggers the second always block COUNT_DO_w = 0 + 1 = 1. And , in the next postive edge clock, which trigger the first always block to do COUNT_DO <= COUNT_DO_w. But it seems to delay one clock to assign it(22ns). I have tried to figure it out but still cannot, why it delay one clock?
Thx in advance.
At time=14ns, reset is asserted (RESET_N=0), which means COUNT_DO=0 in the 1st always block. At time t=20ns, you release reset and COUNT_DO remains at 0. At time=22ns, you have your 1st posedge CLK which assigns COUNT_DO to COUNT_DO_w. The time at which COUNT_DO changes is controlled only by the 1st always block, not the 2nd.

Resources