Verilog (register delay or mistake in code?) - verilog

I am trying to study Verilog
and I got problem with my code:
the problem is when I trying to add my numbers like
first value clk> second value clk> 3rd value clk> 4th value clk>and here supposed to be my average value BUT for some unknown reason I need to press clock 2 times AGAIN to get averege value
and I don't know why. (I think there is a problem in my code with avereger)
why I have such delay
my avereger must get 4 - 10 bits numbers and show me the averege of it (on my leds)
Here is my code
and I am including my vector form [
]
module avereger (data_in,Led1,Led2,Led3,clk,rst);
input clk,rst;
input [9:0]data_in;
output[6:0] Led1,Led2,Led3;
reg [9:0] data[3:0];
reg [11:0] sum,avg_reg;
always # (posedge clk)
begin
if(rst==1'b1)
begin //all values will be 0
data[0]<=0;
data[1]<=0;
data[2]<=0;
data[3]<=0;
sum<=0;
avg_reg<=0;
end
else
begin
data[3]<=data[2];
data[2]<=data[1];
data[1]<=data[0];
data[0]<=data_in;
sum<= data[0] + data[1] + data[2] + data[3];
avg_reg<=sum[11:2];
end
end
decoder_driver BCD(avg_reg,Led1,Led2,Led3);
endmodule
module decoder_driver(A,Led1,Led2,Led3);
input [9:0] A;
output [6:0] Led1,Led2,Led3;
reg [3:0] B,C,D;
wire [3:0] wireB,wireC,wireD;
assign wireB=B;
assign wireC=C;
assign wireD=D;
display1 HUN(wireB,Led1);
display1 TEN(wireC,Led2);
display1 ONE(wireD,Led3);
always # (A)
begin
B=A/7'd100;
C=A%7'd100/7'd10;
D=A%7'd100%7'd10;
end
endmodule
module display1 (a,Led);
input [3:0] a;
output [6:0] Led;
reg [6:0] Led;
always # (a)
begin
case(a)
4'b0000: Led <= 7'b1000000; //0
4'b0001: Led <= 7'b1111001; //1
4'b0010: Led <= 7'b0100100; //2
4'b0011: Led <= 7'b0110000; //3
4'b0100: Led <= 7'b0011001; //4
4'b0101: Led <= 7'b0010010; //5
4'b0110: Led <= 7'b0000010; //6
4'b0111: Led <= 7'b1111000; //7
4'b1000: Led <= 7'b0000000; //8
4'b1001: Led <= 7'b0010000; //9
4'b1010: Led <= 7'b0001110; //F
default: Led <= 7'b1111111; //-
endcase
end
endmodule

The reason the code is taking 6 total cycles instead of 4 is because calculating sum and avg_reg takes a cycle each, thus combined with the 4 cycles needed to shift in the 4 data items, and you get 6 cycles.
If you watch what happens during simulation, you'll notice shifting in the 4 items takes 4 cycles as expected. However, sum is, at the edge the 4th value is take into data[0], the sum of the first third items and whatever was in data[4] which is probably all zeroes if you've just done a reset. And avg_reg is the value of sum from right before the edge shifted over twice. On the next cycle sum becomes correct and then the cycle after that avg_reg becomes correct.
If you want to remove these cycles, you can simply have sum determined combinationally and don't really need avg_reg at all:
module avereger (data_in,Led1,Led2,Led3,clk,rst);
input clk, rst;
input [9:0] data_in;
output[6:0] Led1,Led2,Led3;
reg [9:0] data[3:0];
wire [11:0] sum;
always # (posedge clk) begin
if(rst==1'b1) begin //all values will be 0
data[0]<='0;
data[1]<='0;
data[2]<='0;
data[3]<='0;
end
else begin
data[3]<=data[2];
data[2]<=data[1];
data[1]<=data[0];
data[0]<=data_in;
end
end
// Find sum combinationally
assign sum = data[0] + data[1] + data[2] + data[3];
// Do >>2 here
decoder_driver BCD(.A(sum[11:2]),
.Led1(Led1),
.Led2(Led2),
.Led3(Led3));
endmodule
Side note, you should avoid writing your own sensitivity lists as its very easy to make mistakes, use always #(*) instead of always #(A) in your other modules.

Related

Why does value only update on the next clock pulse?

I am simulating the code below and when I change the valid signal the data is put into the line only on the next positive edge why does that happen? I have not done any testbench just simulating in Vivaldo and forcing these values.
module lineBuffer(
input i_clk,
input i_rst,
input [7:0] i_data,
input i_data_valid,
output [23:0] o_data,
input i_rd_data
);
reg [7:0] line [511:0]; //line buffer
reg [8:0] wrPntr;
reg [8:0] rdPntr;
always #(posedge i_clk)
begin
if(i_data_valid)
line[wrPntr] <= i_data;
end
always #(posedge i_clk)
begin
if(i_rst)
wrPntr <= 'd0;
else if(i_data_valid)
wrPntr <= wrPntr + 'd1;
end
assign o_data ={line[rdPntr],line[rdPntr+1],line[rdPntr+2]};
always #(posedge i_clk)
begin
if(i_rst)
rdPntr <= 'd0;
else if(i_rd_data)
rdPntr <= rdPntr + 'd1;
end
endmodule
This is the way a sequence of hardware flops work. You designed such sequences. Here is an example,
at posedge clk you scheduled an update of the wrPntr. It will be stored at the output of the first flop, expressed by wrPntr <= wrPntr + 'd1.
the next flop, line[wrPntr] <= i_data; will not see the value of wrPntr evaluated before. It will only see it on the next clock cycle.
+--+ +--+
| | Q1 | |
Q----> |------> |----Q2
+^-+ +^-+
clk---|---------|
In the above, Q2 will have one clock cycle delay in relation to Q
You should really run a simulation to study behavior of different signals.

Connecting output of 4-bit counter to Hex to 7-Seg decoder and creating testbench

I have the general abstract idea, but doing it in Verilog is very hard for me. I know I have to connect the two and then make a testbench. Would that require 2 more modules? I have trouble understanding how to declare inputs and outputs correctly, and that makes it hard to make the testbench.
The input of the counter is a clock, and the output is 4 bits. That 4 bit connects to the 4 bit input of the decoder. The testbench needs to display the clock input, 4 counter outputs, and the 7 outputs of the decoder.
One thing that is unclear is whether I need one more module to connect the two modules, or can I just implement this functionality into one testbench?
//4-bit counter counting from 0000 to 1111
module lab_x_counter (clk, cnt);
input clk;
output reg[3:0] cnt;
always #(posedge clk) begin
cnt <= cnt + 1;
end
initial
cnt <= 0;
endmodule
//Hex to 7-seg
module lab_x_behavioral (SW, HEX0);
input [3:0] SW;
output [6:0] HEX0;
bcd_behavioral u0 (SW[3:0], HEX0[6:0]);
endmodule
module bcd_behavioral (bcd, HEX0);
input [3:0] bcd;
output reg [6:0] HEX0;
always #(bcd) begin
case (bcd)
4'b0000: HEX0 <= ~7'b0111111;
4'b0001: HEX0 <= ~7'b0000110;
4'b0010: HEX0 <= ~7'b1011011;
4'b0011: HEX0 <= ~7'b1001111;
4'b0100: HEX0 <= ~7'b1100110;
4'b0101: HEX0 <= ~7'b1101101;
4'b0110: HEX0 <= ~7'b1111101;
4'b0111: HEX0 <= ~7'b0000111;
4'b1000: HEX0 <= ~7'b1111111;
4'b1001: HEX0 <= ~7'b1101111;
4'b1010: HEX0 <= ~7'b1110111;
4'b1011: HEX0 <= ~7'b1111100;
4'b1100: HEX0 <= ~7'b0111001;
4'b1101: HEX0 <= ~7'b1011110;
4'b1110: HEX0 <= ~7'b1111001;
4'b1111: HEX0 <= ~7'b1110001;
endcase
end
endmodule
Instead of your lab_x_behavioral module, I created a tb module without ports. Then I instantiated the counter, added a clock, and made the connections. There is no need for the port names to match. Here is one way to code a quick testbench:
module tb;
wire [3:0] cnt;
wire [6:0] HEX0;
reg clk = 0;
bcd_behavioral u0 (cnt, HEX0);
lab_x_counter u1 (clk, cnt);
always #5 clk = ~clk;
initial begin
#500 $finish;
end
endmodule
See also Testbench 101

Why am I getting a High Z output for cathode in seven segment display controller instead of a numeric value?

I wrote a verilog code for a seven segment display controller as part of my assignment, but in the simulation, i get the following error:
Can someone please resolve this issue? I have attached the following verilog modules:
1.Main controller code
module top(switch, button,clk,anode,cathode);
input wire clk;
input wire[7:0] switch;
input wire[3:0] button;
output wire [3:0] anode;
output wire [7:0] cathode;
wire refreshclock;
wire[1:0] refreshcounter;
wire[3:0] MUXED_digit;
//to instantiate clockmodule here, do this..
clock_module refreshclock_generator (.clk(clk), .sclk(refreshclock));
//to instantaiate seven segment controller modules..
refresh_counter R1 (.refreshclock(refreshclock), .refreshcounter(refreshcounter));
anode_control A1 ( .refreshcounter(refreshcounter), .anode(anode));
bcd_control B1( .digit1(switch[3:0]), .digit2(switch[7:4]),.digit3(button[3:0]), .digit4(button[3:0]),.refreshcounter(refreshcounter), .MUXED_digit(MUXED_digit));
bcd_7seg_case BS1 (.bcd(bcd), .S(S));
endmodule
Clock divider code
module clock_module(t_count,sclk,rst,en,clk);
parameter n=19;
parameter Nc=400000;
input rst;
input en;
input clk;
output reg [n-1:0]t_count;
output reg sclk;
always#(posedge clk or posedge rst) //on FPGA, clock won't start until rst is also pressed. If rst not pressed, then value of N doesn't go into t_count, so at that moment, t_count would be giving us garbage values
begin //always begin
if (rst==1)
begin //rst 1 begin
//counter will be cleared
t_count=0;
sclk=0;
end //rst 1 end
else
begin //rst 0 begin
//counter counts normally
if(en==1)
begin
if(t_count<Nc)
begin
t_count=t_count+1;
sclk=sclk;
end
else
begin
t_count=0;
sclk=~sclk;
end
end
else
begin
//retains previous values
t_count=t_count;
sclk=sclk;
end
end //rst 0 end
end //always end
endmodule
Refresh counter code:
module refresh_counter(refreshclock,refreshcounter);
input refreshclock;
output reg[1:0] refreshcounter = 0;
always#(posedge refreshclock)
refreshcounter <= refreshcounter+1;
endmodule
Anode control code
module anode_control(refreshcounter,anode); //we want to make sure each anode is turned on based on each case value of the refresh counter
input[1:0] refreshcounter;
output reg[3:0] anode = 0;
always#(refreshcounter)
begin
case(refreshcounter)
2'b00: anode = 4'b1110; //digit 1 on (rightmost)
2'b01: anode = 4'b1101; //digit 2 on
2'b10: anode = 4'b1011; //digit 3 on
2'b11: anode = 4'b0111; //digit 4 on (leftmost)
endcase
end
endmodule
BCD control code:
module bcd_control(MUXED_digit, refreshcounter,digit1,digit2,digit3,digit4);
input[3:0] digit1; //rightmost digit (ones)
input[3:0] digit2; //tens
input[3:0] digit3; //hundreds
input[3:0] digit4; //leftmost digit(thousands)
input[3:0] refreshcounter; //because we are checking for both anode value and displayed value at the same time, and also to make sure both of them are in sync with each other
/*we are choosing which input digit to display when the corresponding anode is turned on. so we can say that the bcd control acts like a 4to1 mux with refreshcounter as select lines*/
output reg[3:0] MUXED_digit = 0;
always#(refreshcounter)
begin
case(refreshcounter)
2'd0: MUXED_digit = digit1; //digit 1 on (rightmost)
2'd1: MUXED_digit= digit2; //digit 2 on
2'd2: MUXED_digit = digit3; //digit 3 on
2'd3: MUXED_digit = digit4; //digit 4 on (leftmost)
endcase
end
endmodule
BCD to 7 segment code:
module bcd_7seg_case(bcd,S);
input [3:0] bcd;
//input cs;
output reg [6:0]S;
//circuit is sensitive to changes in inputs
always#(bcd)
begin
//if(~cs)
//S=0'b0000_000;
//else
//begin
case(bcd)
0: S = 7'b1111_110;
1: S = 7'b0110_000;
2: S = 7'b1101_101;
3: S = 7'b1111_001;
4: S = 7'b0110_011;
5: S = 7'b1011_011;
6: S = 7'b1011_111;
7: S = 7'b1110_000;
8: S = 7'b1111_111;
9: S = 7'b1111_011;
endcase
end
endmodule

Verilog code 2 errors i can't find: Would be grateful for an extra pair of eyes to spot a mistake i might've overlooked

I'm writing a verilog code where i'm reading two files and saving those numbers into registers. I'm then multiplying them and adding them. Pretty much a Multiplication Accumulator. However i'm having a hard frustrating time with the code that i have. It read the numbers from the files correctly and it multiples but here is the problem? When i first run it using ModelSim, I reset everything so i can clear out the accumulator. I then begin the program, but there is always this huge delay in my "macc_out" and i cannot seem to figure out why. This delay should not be there and instead it should be getting the result out A*B+MAC. Even after the delay, it's not getting the correct output. My second problem is that if i go from reset high, to low (start the program) and then back to reset high ( to reset all my values), they do not reset! This is frustrating since i've been working on this for a week and don't know/can't see a bug. Im asking for an extra set of eyes to see if you can spot my mistake. Attached is my code with the instantiations and also my ModelSim functional Wave Form. Any help is appreciated!
module FSM(clk,start,reset,done,clock_count);
input clk, start, reset;
output reg done;
output reg[10:0] clock_count;
reg [0:0] macc_clear;
reg[5:0] Aread, Bread, Cin;
wire signed [7:0] a, b;
wire signed [18:0] macc_out;
reg [3:0] i,j,m;
reg add;
reg [0:0] go;
reg[17:0] c;
parameter n = 8;
reg[1:0] state;
reg [1:0] S0 = 2'b00;
reg [1:0] S1 = 2'b01;
reg [1:0] S2 = 2'b10;
reg [1:0] S3 = 2'b11;
ram_A Aout(.clk(clk), .addr(Aread), .q(a));
ram_B Bout(.clk(clk), .addr(Bread), .q(b));
mac macout(.clk(clk), .macc_clear(macc_clear), .A(a), .B(b), .macc_out(macc_out), .add(add));
ram_C C_in(.clk(clk), .addr(Cin), .q(c));
always #(posedge clk) begin
if (reset == 1) begin
i <= 0;
add<=0;
j <= 0;
m <= 0;
clock_count <= 0;
go <= 0;
macc_clear<=1;
end
else
state<=S0;
case(state)
S0: begin
// if (reset) begin
// i <= 0;
// add<=0;
// j <= 0;
// m <= 0;
// clock_count <= 0;
// go <= 0;
// macc_clear<=1;
// state <= S0;
// end
macc_clear<=1;
done<=0;
state <= S1;
end
S1: begin
add<=1;
macc_clear<=0;
clock_count<=clock_count+1;
m<=m+1;
Aread <= 8*m + i;
Bread <= 8*j + m;
if (m==7) begin
state <= S2;
macc_clear<=1;
add<=0;
end
else
state <=S1;
end
S2: begin
add<=1;
macc_clear<=0;
m<=0;
i<=i+1;
if (i<7)
state<=S1;
else if (i==8) begin
state<=S3;
add<=0;
end
end
S3: begin
add<=1;
i<=0;
j<=j+1;
if(j<7)
state<=S1;
else begin
state<=S0;
done<=1;
add<=0;
end
end
endcase
end
always # (posedge macc_clear) begin
Cin <= 8*j + i;
c <= macc_out;
end
endmodule
module mac(clk, macc_clear, A, B, macc_out, add);
input clk, macc_clear;
input signed [7:0] A, B;
input add;
output reg signed [18:0] macc_out;
reg signed [18:0] MAC;
always #( posedge clk) begin
if (macc_clear) begin
macc_out <= MAC;
MAC<=0;
end
else if (add) begin
MAC<=(A*B)+ MAC;
macc_out<=MAC;
end
end
endmodule
module ram_A( clk, addr,q);
output reg[7:0] q;
input [5:0] addr;
input clk;
reg [7:0] mem [0:63];
initial begin
$readmemb("ram_a_init.txt", mem);
end
always #(posedge clk) begin
q <= mem[addr];
end
endmodule
module ram_C(clk,addr, q);
input [18:0] q;
input [5:0] addr;
input clk;
reg [18:0] mem [0:63];
always #(posedge clk) begin
mem[addr] <= q;
end
endmodule
ModelSim Functional Simulation Wave Form
1) Take a look at the schematic view for your MACC module - I think some of your "problems" will be obvious from that;
2) Consider using an always#(*) (Combinational) block for your FSM control signals (stuff like add or macc_clear) rather than a always#(posedge clk) (sequential) - it makes the logic to assert them easier. Right now they're registered, so you have a cycle delay. ;
3) In your MAC, you clear the MAC register on a reset, but you don't clear the macc_out register.
In short, I think you need to step back, and consider which signals are combinational logic, and which ones are sequential and need to be in registers.

how to define m*n output in verilog

i am writting verilog code for shift left register which store its value after each shift in sub registers. can i define the output registers as array like this,the provided code is just a simple example to show the concept not my code,
module test(a,b,c);
input a,b;
output [7:0] c [3:0];
endmodule
instead of
module test(a,b,c1,c2,c3,c4);
input a,b;
output [7:0] c1,c2,c3,c4;
endmodule
and for the first way how i can call c[i]
... Yes you can very much use a 2D array at the output, like in your first example. Check out Section 5 of this paper by Stuart Sutherland himself, this should give you some confidence. The section is titled Module Ports.
http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CC4QFjAA&url=http%3A%2F%2Fwww.sutherland-hdl.com%2Fpapers%2F2006-SNUG-Europe_SystemVerilog_synthesis_paper.pdf&ei=7KmYUNKPN6GyigKDnoHwDA&usg=AFQjCNGmr3flHrARC-w40xveo8zitcdjfg&cad=rja
Also, elaborating on your first example, you can define your module this way for clarity:
module lshift(clk, reset, a, c);
input wire clk, reset;
input wire [7:0] a;
output reg [7:0] c [0:3]; // <-- defining the unpacked dimension as [0:3] for clarity
always#(posedge clk) begin
if(reset) begin
c[0] <= 8'd0;
...
c[3] <= 8'd0;
end
else begin
c[0] <= a;
c[1] <= c[0];
c[2] <= c[1];
c[3] <= c[2];
end
end
endmodule
... and now you can slice into your array. c[0], c[1] .. c[3] each represents a Byte and c[0][3:0] would mean the lower nibble of the first byte.
... Hope this helps!

Resources