how to map reg values to the ports of other module - verilog

i am an amateur in verilog. i am trying to call module divider. but i get errors like "Reference to vector reg 'qtnt' is not a legal net lvalue" in synthesis. i have tried using wires as inputs but when i tried to assign values to them an error message was recieved. please help
module euclid_mul(
input[9:0] p0,p1,q0,
input[19:0] tot,
input clk,
output reg [20:0] p2,
output reg out_en,o1,o2
);
reg[20:0] dvr,dvd,qtnt,rem;
reg[9:0] ph;
reg[20:0] mul,res;
reg enable,f1;
initial f1=0;
initial enable=0;
divider div2(dvd,dvr,enable,qtnt,rem,f1);
always # (negedge clk)
begin
if(f1==0) begin
mul=q0*p1;
ph=p0;
res={11'b00000000000,ph[9:0]}-mul;
if(res[20])
begin
o1=1;
dvd=-res;
end
else
dvd=res;
o2=1;
dvr=tot;
enable=1;
end
end
always #(posedge f1)
begin
if(res[20])
begin
p2=tot-rem;
out_en=1;
end
else
begin
p2=rem;
out_en=1;
end
end
endmodule

You may get more response if you formatted the code so that it was easier to read. Something like the following:
I have also pointed out a section where I think you are missing a begin and end statement.
Also inside clocked sections you often want to use nonblocking assignments <=.
Since you have not provided the divider module, I would prefer to see ports named rather than specified in order, it might help us to know what it is likely to do, even better label it with its direction and width.
module euclid_mul(
input [9:0] p0,p1,q0,
input [19:0] tot,
input clk,
output reg [20:0] p2,
output reg out_en,o1,o2
);
reg [20:0] dvr,dvd,qtnt,rem;
reg [9:0] ph;
reg [20:0] mul,res;
reg enable,f1;
initial begin
f1 = 0;
enable = 0;
end
divider div2(dvd,dvr,enable,qtnt,rem,f1);
// My prefered style to help us understand conectivity.
//divider
// divider_i0(
// .divisor( dvd ), //input [20:0]
// .result ( res ) //output [20:0]
//);
always # (negedge clk) begin
if(f1==0) begin
mul = q0*p1;
ph = p0;
res = {11'b00000000000,ph[9:0]}-mul;
if ( res[20] ) begin
o1 = 1;
dvd = -res;
end
else begin //There was a missing begin
dvd = res;
o2 = 1;
dvr = tot;
enable = 1;
end //Missing End
end
end
always #(posedge f1) begin
if(res[20]) begin
p2 = tot-rem;
out_en = 1;
end
else begin
p2 = rem;
out_en = 1;
end
end
endmodule
Inputs can be regs and driven from inside always or initial blocks, or wires driven from a single assign or another modules output.
Outputs should always be connected to wires, the module drives them.

Related

How do I add an input called Unsigned / Signed for Verilog comparator testbench code?

I'm new to coding verilog.
This is code for a 3-bit Comparator. I need help adding a signal called 'US' (unsigned/signed) to my testbench code. When the signal is High(unsigned mode), the Comparator interprets the numbers as Unsigned numbers. When the signal is Low (Signed Mode), the Comparator interprets the numbers as signed numbers.
module comparator(A,B,G,E,L,US);
input [2:0]A;
input [2:0]B;
input US;
output G,E,L;
reg G,E,L;
always#(*)
begin
if(US==0)
begin
L=$signed(A)<$signed(B);
E=$signed(A)==$signed(B);
G=$signed(A)>$signed(B);
end
else
L = A < B;
E = A==B;
G = A > B;
end
endmodule
TEST BENCH CODE:
`timescale 1ns /1ps
module comparator_tb();
reg [2:0]A=3'b000;
reg [2:0]B=3'b000;
reg US;
wire G,E,L;
integer i,j;
comparator uut(A,B,G,E,L,US);
initial begin
for(i=0;i<8;i=i+1)
begin
for(j=0;j<8;j=j+1)
begin
#50
B=B+1;
end
A = A+1;
B=3'b000;
end
#100
$stop;
end
endmodule
i guess you want to toggle US in your test bench. something like the following?
since US is declared as wire (default), you need the assign statement:
integer us_count;
assign US = us_count;
initial begin
for(us_count = 0; us_count < 1; us_count++) begin
for(i=0;i<8;i=i+1)
begin
for(j=0;j<8;j=j+1)
begin
#50
B=B+1;
end
A = A+1;
B=3'b000;
end
end
#100
$stop;
end
if you declare it as reg, you can use it directly in the loop instead of the us_count and do not need the assign
reg US;
initial begin
for (US = 0; US < 1; US++)
...
The rest depends on how you want to test it.

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 Reg Array

Having a bit of trouble with looping through a 1D reg array.
ultimately I am trying to accomplish the following.
in "Listen" state, the rx_values fill a read buffer (4 8-bit characters) to store the characters being typed in a console and echo back the character by setting tx_data to the last character (this works)
when the enter key is hit, the state switches to "Read" which sets the tx_data to the readbuffer with each iteration until the 4th character is reached at which time the state is reset to idle. (this doesnt work)
I get to the read state;however,the counter does not work as expected.
any help would be greatly appreciated.
module receiver (
input clk,
input rst,
output reg [7:0] tx_data,
output reg new_tx_data,
input tx_busy,
input [7:0] rx_data,
input new_rx_data
);
localparam idle = 4'h0 ,listen = 4'h1 ,read = 4'h2, write = 4'h3;
reg [3:0] state = idle;
reg [7:0] readbuff[3:0];
integer buffdex;
always #* begin
end
always #(posedge clk) begin
new_tx_data = 1'b0;
case (state)
idle: begin
if(new_rx_data) begin
state<=listen;
end
end
listen: begin
new_tx_data = 1'b1;
readbuff[buffdex] = rx_data;
tx_data = readbuff[buffdex];
//tx_data = buffdex;
buffdex = buffdex + 1';
if(rx_data == 8'h0D) begin
tx_data = "\n";
buffdex = 0;
state <= read;
end else begin
state<=idle;
end
end
read: begin
new_tx_data = 1'b1;
tx_data = readbuff[buffdex];
buffdex = buffdex + 1;
if (buffdex == 3) begin
state <= idle;
end
//tx_data = state;
end
endcase
end
endmodule
Sorry to use "answer" feature instead of comment but I don't have enough points yet. This is intended as a "comment". Since you wanted any help I hope this fits.
1) Your code needs some improvement both in functionality and readability (empty combo blocks, mixing BA with NBA -> mixing combo with sequential logic, reset input but no reset logic, commented logic lines, latches on FSM).
Consider rewriting it according to some good coding practices, e.g. http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf
You also have inconsistencies like buffdex = buffdex + 1' and buffdex = buffdex + 1. (And thus doesn't compile on incisive).
2) Can you provide a testbench for this module? Have you tried strobing signals to check their values? Does buffdex increment in read state? Is the if statement reachable?
3) Since this isn't a 1st problem with Mojo (seems like under developement) you may consider free https://www.edaplayground.com/ for both testing and compiling/syntax checking.
So I read the paper (along with other various IEEE instructions) and finally got a working version. below is the code. as before I am open the suggestions as to how the code can be made more efficient or functional. I think the read buffer is one big latch, but not sure how to fix it.
module receiver (
//inputs
input clk,
input rst,
input tx_busy,
input [7:0] rx_data,
input new_rx_data,
//outputs
output reg [7:0] tx_data,
output reg new_tx_data,
output reg [0:4] LED
);
//local parameters
localparam IDLE = 2'b00 , LISTEN = 2'b01 ,NEWLINE = 2'b10, READ = 2'b11;
//fsm state reg and readbuff reg
reg [1:0] stated, stateq;
reg [3:0] cntrd,cntrq;
reg [7:0] readbuff [15:0];
reg nl;
//on clock edge set flip-flop - non-blocking assignments
always #(posedge clk ) begin
if(rst) begin
stateq <= IDLE;
cntrq<=4'b0000;
end else begin
//update the state and readbuff index values to be current.
stateq <= stated;
cntrq <=cntrd;
end
end
//sequential and combinational blocking assignments
always #(*) begin
//set default states to avoid latches.
stated = stateq;
cntrd = cntrq;
LED = cntrq;
//set output defaults
tx_data = 8'hxx;
new_tx_data = 1'b0;
case (stateq)
IDLE: begin
//move to listen state
cntrd=4'b0;
stated = stateq + 1'b1;
end
LISTEN: begin
if(new_rx_data) begin
//set readbuffer[indx] to the rx data
readbuff[cntrq] = rx_data;
new_tx_data = 1'b1;
tx_data = readbuff[cntrq];
cntrd = cntrq + 1'b1;
//if enter is pressed change states, otherwise, echo and increase the read buffer.
if(rx_data == "\r" || rx_data == "\n") begin
stated = stateq + 1'b1;
cntrd=4'b0000;
end
end
end
NEWLINE: begin
if(!tx_busy) begin
new_tx_data = 1'b1;
tx_data = 8'h0A;
nl = 1'b1;
stated = stateq + 1'b1;
end
end
READ: begin
//check the value of cntrq for the enter statement
if(readbuff[cntrq] == "\r" || readbuff[cntrq] == "\n" ) begin
stated = IDLE;
//otherwise write out the value of the readbuff - tx busy should sync to avr clock
end else begin
if (!tx_busy) begin
new_tx_data = 1'b1;
tx_data = readbuff[cntrq];
cntrd = cntrq + 1'b1;
end
end
end
endcase
end
endmodule

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

verilog average, add n-bit numbers together and then divide by nbit numbers

I am having trouble putting this code together my main code is a state machine it adds 2 numbers together = sum then loads A to add A to sum(sum=a+sum) after clock is reached it then divides by n bit. I'm lost putting it together. In having Lots of trouble assigning outputs. what is legal and what is not am I able to set the regs equal to each other sometimes I feel like I can do that and some other times I cannot.if I use the module can the input be an output and vice versa I posted my whole code cause I wanted to get it to work. I think my device is correct but I need to create a test bench to tested.
module Adder (A1, B1, Cin,Q);
parameter n = 5;
output[n:0]Q;
reg [n:0]Q;
input [n:0] A1;
wire[n:0] A1;
input [n:0] B1;
wire [n:0] B1;
input Cin;
always #(A1 or B1 or Cin)
begin
Q = A1 +B1 + Cin;
end
endmodule
module ave(Clk,X,LA,DataA,Sum,Q);
parameter n=5;
input A,B,EB,Temp,DataA,DataB,Sum,Q;
input X;
reg A,B,Temp,Sum;
reg y,Y
wire
reg S1=3'b000;S2=3'b001;S3=3'b010;S4=3'b011;S5=3'b100;
always (Clk)
begin
case(y)
S1:
y=S2;
S2:
y=S3;
S3:
if (counter>0) y=S2;
else y=S4;
S4:
y=S4;
S5:
Done;
endcase
end
always (Clk)
begin
case
S1:
Counter=n; Temp=n; Sum=0;
S2:
A=X;
S3:
if (counter>0) B<=A+B;
else B<=B;
S4:
DataA=Temp;
DataB=Sum;
S5:
Done=1;
end
Adder add(A,Sum,Cin,Sum);
divider divid(Clk,1,1,1,1,DataA,DataB,1,1,Q,0);
endmodule
this is my divider plus the other modules:
module shiftlne(R,C,L,w,Clk,Q);
parameter n=8;
input [n-1:0]R;
input L,w,Clk,C;
output [n-1:0]Q;
reg [n-1:0]Q;
integer k;
always #(posedge Clk)
begin
if(L)begin
if(C)begin
Q<=R;end
else
begin
for (k=0;k<(n-1);k=(k+1))
Q[k+1]=Q[k];
Q[0]<=w;
end
end
end
endmodule
module downcounter (R,E,L,Clk,Q);
parameter n=8;
input[n-1:0]R;
input Clk,L,E;
output [n-1:0]Q;
reg[n-1:0]Q;
always #(posedge Clk)
begin if(L)
Q<=R;
else if(E)
Q<=(Q-1);
end
endmodule
module muxdff( D0, D1, Sel, Clk,Q);
input Clk,D0,D1,Sel;
wire D;
output Q;
reg Q;
assign D=Sel?D1:D0;
always # (posedge Clk)
begin
Q=D;
end
endmodule
module regne (R,Clk,Resetn,E,Q);
parameter n=8;
input [n-1:0]R;
input Clk,Resetn,E;
output [n-1:0]Q;
reg [n-1:0] Q;
always #(posedge Clk or negedge Resetn)
begin
if (Resetn==0)
Q<=0;
else if (E)
Q<=R;
end
endmodule
Are you stuck using Verilog-95 if not you can clean up the code style, if nothing else it helps spot the bugs easier.
NB: Uses spaces to indent your code, not tabs as they mess up the formatting when posting Q's and can look different to people review your code depending on how there editor is setup.
module Adder #(
parameter n = 5
)(
input [n:0] A1, //Inputs do not have to be declared as wires
input [n:0] B1,
input Cin,
output reg [n:0] Q;
);
//Auto sensitivity list with #* lowers chance of bugs
always #* begin
Q = A1 + B1 + Cin;
end
endmodule
Most languages, and I apply this to my verilog keep constants like parameters and localparam in UPPERCASE, everything else is lowercase.
Your shiftlne code be made more readable: readable code to me implies easier to spot the bugs and understand the design intention.
always #(posedge Clk) begin
if( L ) begin
if( C ) begin
Q <= R;
end
else begin
for (k=0;k<(n-1);k=(k+1))
Q[k+1] = Q[k]; //For loop only applies to this line
// should it not be Q[k+1] <= Q[k];
Q[0] <= w;
end
end
end
endmodule

Resources