I'm trying to make a counter that counts from 0-9 and displays on my Nexys A7's seven segment display. The code compiles, but in the testbench it shows that all the outputs are unknown. I tested my clock divider module, and it looks fine. I'm not sure why it isn't working.
module BCD_sevenseg(
input clk,
output segA, segB, segC, segD, segE, segF, segG, segDP, div_clk
);
counter module1(
.clk(clk),
.div_clk(div_clk)
);
reg[3:0] BCD; //BCD signal is 4 bits wide
always#(posedge clk) //check every positive edge
if(div_clk) //executes if counter value from module1 is true
BCD <= (BCD == 4'h9 ? //check if BCD is at binary 9
4'h0 : BCD + 4'h1 );
//true: reset to 0
//false: count up
reg [7:0] sevenseg; //8 segments on 7 segment display (w/ decimal point)
always#(*)
case(BCD) //one case for each digit
4'h0: sevenseg = 8'b11111100;
4'h1: sevenseg = 8'b01100000;
4'h2: sevenseg = 8'b11011010;
4'h3: sevenseg = 8'b11110010;
4'h4: sevenseg = 8'b01100110;
4'h5: sevenseg = 8'b10110110;
4'h6: sevenseg = 8'b10111110;
4'h7: sevenseg = 8'b11100000;
4'h8: sevenseg = 8'b11111110;
4'h9: sevenseg = 8'b11110110;
default: sevenseg = 8'b00000000;
endcase
assign {segA, segB, segC, segD, segE, segF, segG, segDP} = sevenseg;
endmodule
Clock divider:
module counter(
input clk,
output reg div_clk=0
);
integer count_value=0;
always#(posedge clk)
begin
if(count_value == 10)//change this number to adjust output signal frequency
begin
div_clk = ~div_clk;
count_value <= 0;
end
else
count_value <= count_value+1;
end
endmodule
Testbench code:
module BCD_sevenseg_tb();
reg clk=0;
wire segA, segB, segC, segD, segE, segF, segG, segDP, div_clk;
BCD_sevenseg UUT(
.clk(clk),
.segA(segA),
.segB(segB),
.segC(segC),
.segD(segD),
.segE(segE),
.segF(segF),
.segG(segG),
.segDP(segDP),
.div_clk(div_clk)
);
always
#1 clk=~clk;
endmodule
Your outputs are always X because BCD is always X. You declared BCD as a reg, which defaults to X. You need to initialize BCD to a known value, such as 0.
For simulation purposes, you can do this simply with:
reg[3:0] BCD = 0; //BCD signal is 4 bits wide
A standard way to initialize signals is to use a reset input signal. For example:
always #(posedge clk) begin
if (reset) begin
BCD <= 4'h0;
end else begin
if (div_clk) BCD <= (BCD == 4'h9 ? 4'h0 : BCD + 4'h1 );
end
end
Related
HDLBits 12-hour clock
I wrote the answer for this question, but something wrong occurred. I can't find out where I'm wrong because the answer just tells me how many mismatches I have. Can some one tell me please?
Here are results from HDLBIts:
result
result
result
And here is my code:
module top_module(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss);
wire [1:0] ssc, mmc, hhc;
assign ssc[0] = ss[3]&ss[0];
counter4buenld cssl(clk, ena, reset, ssc[0], 4'h0, ss[3:0]);
assign ssc[1] = ss[4]&ss[6]&ssc[0];
counter4buenld cssh(clk, ena&ssc[0], reset, ssc[1], 4'h0, ss[7:4]);
assign mmc[0] = mm[3]&mm[0]&ssc[1];
counter4buenld cmml(clk, ena&ssc[1], reset, mmc[0], 4'h0, mm[3:0]);
assign mmc[1] = mm[4]&mm[6]&mmc[0];
counter4buenld cmmh(clk, ena&mmc[0], reset, mmc[1], 4'h0, mm[7:4]);
assign hhc[0] = hh[3]&hh[0]&mmc[1];
assign hhc[1] = hh[4]&hh[1]&mmc[1];
counter4buenld chhl(clk, ena&mmc[1], 1'b0, reset|hhc[0]|hhc[1], {2'b00, reset, ~reset}, hh[3:0]);
counter4buenld chhh(clk, ena&hhc[0], 1'b0, reset|hhc[1], {3'b000, reset}, hh[7:4]);
reg pml;
assign pm = pml;
always#(posedge clk) begin
if(reset) begin
pml <= 1'b0;
end
else begin
if(hh[4]&hh[0]&mmc[1]) begin
pml <= ~pml;
end
else begin
pml <= pml;
end
end
end
endmodule
module counter4buenld(
input clk,
input ena,
input reset,
input load,
input [3:0] d,
output reg [3:0] q
);
always#(posedge clk) begin
if(reset)
q <= 4'h0;
else
if(load)
q <= d;
else
q <= q + ena;
end
endmodule
The HDLBits waveform snapshots do not give you enough visibility to debug your problem. You need to create your own testbench and view the complete waveforms.
When you do so, you would see that your hour increments from 9 to 11. It skips 10.
Your Verilog code is too difficult to understand. Here is a simpler approach, including a trivial testbench:
module top_module (
input clk,
input reset,
input ena,
output reg pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss
);
reg [7:0] hhd, mmd, ssd;
function [7:0] bcd ([7:0] in);
bcd[3:0] = in % 10;
bcd[7:4] = in / 10;
endfunction
assign ss = bcd(ssd);
assign mm = bcd(mmd);
assign hh = bcd(hhd);
always#(posedge clk) begin
if (reset) begin
pm <= 0;
end else if (ena && hhd==11 && mmd==59 && ssd==59) begin
pm <= ~pm;
end
end
always#(posedge clk) begin
if (reset) begin
ssd <= 0;
end else if (ena) begin
if (ssd==59) begin
ssd <= 0;
end else begin
ssd <= ssd + 1;
end
end
end
always#(posedge clk) begin
if (reset) begin
mmd <= 0;
end else if (ena && ssd==59) begin
if (mmd==59) begin
mmd <= 0;
end else begin
mmd <= mmd + 1;
end
end
end
always#(posedge clk) begin
if (reset) begin
hhd <= 12;
end else if (ena && mmd==59 && ssd==59) begin
if (hhd==12) begin
hhd <= 1;
end else begin
hhd <= hhd + 1;
end
end
end
endmodule
module tb;
bit clk;
bit ena=1;
bit reset=1;
wire pm;
wire [7:0] hh;
wire [7:0] mm;
wire [7:0] ss;
top_module dut (
// Inputs:
.clk (clk),
.ena (ena),
.reset (reset),
// Outputs:
.hh (hh),
.mm (mm),
.pm (pm),
.ss (ss)
);
always #5 clk++;
initial begin
#12 reset=0;
#5ms $finish;
end
endmodule
Compare MINE vs. YOURS:
This is the verilog code for mod 64 counter, incrementing every clock cycle
module modulus64counter
#(parameter N=64,
parameter WIDTH=5)
(input clk,
input rstn,
output reg[WIDTH-1:0] out);
integer i;
always #(posedge clk) begin
if(!rstn) begin
out<=0;
end
else begin
if(out==N-1)
out<=0;
else
out<= out+1;
end
end
endmodule
and the test bench is
module modulus64countertb;
// Inputs
reg clk;
reg rstn;
// Outputs
wire [4:0] out;
// Instantiate the Unit Under Test (UUT)
modulus64counter uut (
.clk(clk),
.rstn(rstn),
.out(out)
);
always #10 clk = ~clk;
initial begin
// Initialize Inputs
clk = 1;
rstn = 0;
$monitor ("T=%0t rstn=%0b out=0X%h", $time,rstn,out);
repeat(2) #(posedge clk);
rstn <=1;
repeat(50) #(posedge clk);
$finish;
end
endmodule
Now if i want to increment the value of out every "n" clock cycle instead of consecutive clock cycle , how can i modify the program
Kindly help
Updated 20220131
Updated the code to produce output after every 2 clock cycles. Similarly, if you wish to delay for even more clock cycle, the simplest way is to continuously flopping it.
For a better implementation, you can try out a shift register.
module modulus64counter #(
parameter N=64,
parameter WIDTH=8,
parameter DELAY_CYCLE=2
)(
input clk,
input rstn,
output reg[WIDTH-1:0] out,
output reg[WIDTH-1:0] actual_out
);
integer i;
reg [WIDTH-1:0] cntr;
reg [WIDTH-1:0] dly1clk;
always #(posedge clk) begin
if(!rstn) begin
out <= 0;
dly1clk <= 0;
end else if(out == DELAY_CYCLE-1) begin
out <= 0;
dly1clk <= dly1clk + 1;
end else begin
out <= out + 1;
end
end
always #(posedge clk) begin
if(!rstn) begin
actual_out <= 0;
end else begin
actual_out <= dly1clk;
end
end
endmodule
The code below should work for you. You can always swap the out and actual_out if you insist on using out as the final counting variable.
Also, removing the out on the monitor line in the testbench will only print the value when it reaches mod n. I kept both out and actual_out on testbench's monitor to ease debugging purpose.
Verilog code
module modulus64counter #(
parameter N=64,
parameter WIDTH=8
)(
input clk,
input rstn,
output reg[WIDTH-1:0] out,
output reg[WIDTH-1:0] actual_out
);
integer i;
reg [WIDTH-1:0] cntr;
always #(posedge clk) begin
if(!rstn) begin
out <= 0;
actual_out <= 0;
end else if(out == N-1) begin
out <= 0;
actual_out <= actual_out + 1;
end else begin
out <= out + 1;
end
end
endmodule
Testbench
module modulus64countertb;
// Inputs
reg clk;
reg rstn;
// Outputs
wire [7:0] out;
wire [7:0] actual_out;
// Instantiate the Unit Under Test (UUT)
modulus64counter uut (
.clk(clk),
.rstn(rstn),
.out(out),
.actual_out(actual_out)
);
always #10 clk = ~clk;
initial begin
// Initialize Inputs
clk = 1;
rstn = 0;
$monitor ("T=%0t rstn=%0b out=%d actual_out=%d", $time,rstn,out,actual_out);
repeat(2) #(posedge clk);
rstn <=1;
repeat(200) #(posedge clk);
$finish;
end
endmodule
Output result simulated using edaplayground:
I am trying to create a second clk counter using a 100 MHz clk input, but when I simulate the clk divider, it just shows the output as an X even though the clk input is correct. What could I be doing wrong?
1 second clk divider:
module clkdiv(
input clk,
input [25:0] terminalcount,
output reg clk_div
);
reg [25:0] count;
wire tc;
assign tc = (count == terminalcount);
always # (posedge(clk)) begin
if (tc) count <= 0;
else count <= count + 1;
end
always # (posedge(clk)) begin
if (tc) clk_div = !clk_div;
end
endmodule
Test Bench:
module clockdivTB;
// inputs
reg clk; // make 100 MHz -- T = 10 ns
// outputs
wire newclk;
// second clock -- connect test signals to clkdiv
clkdiv slowclkCUT (
.clk(clk),
.terminalcount(50000000-1), // 1 Hz
.clk_div(newclk)
);
// initialize inputs
initial begin
clk = 0;
// create input clock 100MHz
forever #5 clk = ~clk;
end
endmodule
Result:
The output is X because reg types are initialized to X (unknown). You need to initialize the output to a known value. For simulation purposes, you can set clk_div and count to 0 as follows:
module clkdiv(
input clk,
input [25:0] terminalcount,
output reg clk_div = 0
);
reg [25:0] count = 0;
However, if you want to synthesize your logic, you likely need to add a reset input. You can drive the input from your testbench.
module clkdiv(
input reset,
input clk,
input [25:0] terminalcount,
output reg clk_div
);
reg [25:0] count;
wire tc;
assign tc = (count == terminalcount);
always # (posedge(clk)) begin
if (reset) count <= 0;
else if (tc) count <= 0;
else count <= count + 1;
end
always # (posedge(clk)) begin
if (reset) clk_div <= 0;
else if (tc) clk_div <= !clk_div;
end
endmodule
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
This code should dispaly S for 1 sec then turn off for 1 sec and then dispaly G for 1 sec and then turn of for 1 sec and then display S for 1 sec and so on.
The problem is I am getting S then off then G then off then G then off and so on. I believe the error in the hex7segm module but I could not find a solution. Any help would be appreciated
Here is the code:
module asqw (output wire [6:0]a2g,output wire [3:0]AN,input wire fastclk);
wire slowclk;
slow_clock xx(fastclk,slowclk);
hex7segm zz(slowclk,a2g,AN);
endmodule
moduleslow_clock (input wire fastclk,output wire slowclk);
reg[27:0]period_count=0;
always#(posedge fastclk)
begin
period_count<=period_count+1;
end
assign slowclk=period_count[27];
endmodule
module hex7segm (input wire slowclk,
output reg [6:0]a2g,
output reg [3:0]AN
);
reg[1:0]x;
reg[1:0]y=0;
always#(*)
begin
if(slowclk)
begin
x=y;
AN= 4'b1110;
y=y+1;
if(y==2) y=0;
else
x=2;
AN= 4'b1110;
end
case(x)
0: a2g=7'b0100100;
1: a2g=7'b0100000;
2: a2g=7'b1111111;
default: a2g=7'b0100100;
endcase
end
endmodule
Hi probably a little bit late to answer but here it is: The main problem is that you are mixing combinational and sequential logic. You need to separate these two. Moreover, I couldn't see why your new clock has a duty cycle of 50%.
Top module:
module asqw (
output [6:0]a2g,
input wire fastclk);
wire slowclk;
slow_clock xx(fastclk,slowclk);
hex7segm zz(slowclk,a2g);
endmodule
Seven Segment Driver:
module hex7segm (
input wire slowclk,
output reg [6:0]a2g
);
localparam S = 7'b0100100;
localparam G = 7'b0100000;
localparam OFF = 7'b1111111;
reg [2:0] state = 0;
always # (posedge slowclk)
begin
state <= (state == 5) ? 0 : state + 3'b1;
end
always # (*)
begin
case(state)
0: a2g <= S;
2: a2g <= G;
4: a2g <= S;
default: a2g <= OFF;
endcase
end
endmodule
Slow clock:
module slow_clock (
input wire fastclk,
output reg slowclk = 0
);
reg[27:0]period_count = 0;
always#(posedge fastclk)
begin
period_count <= (period_count == 25000000) ? 0 : period_count+ 28'b1;
slowclk <= (period_count == 25000000) ? ~slowclk : slowclk;
end
endmodule