Up Down counter code - verilog

I need help in my project which is a counter that counts up or down from 0 to 20. I already did my counter code and it's working in active HDL. But now I need to show the numbers in 7-segment in nexys 3 FPGA board.
I have the code of the segment, but I have a problem when I call the module of segment - it is giving me an error in active HDL. Can you please tell me what is the error?
This is my current code :
module main
#(parameter N=7)
(
input switch,
input button,
input fastclk,
output [3:0] enable,
output reg[6:0] out
);
wire[N:0]count;
wire slowclk;
clock c1(fastclk,slowclk);
Updown u1(switch,button,slowclk,count);
segment s1([3:0]count,[7:4]count,fastclk,enable,out);
endmodule
module clock(fastclk,slowclk); //clock code
input fastclk;
output wire slowclk;
reg[25:0]period_count = 0;
always #(posedge fastclk)
begin
period_count <= period_count + 1;
end
assign slowclk = period_count[25];
endmodule
module Updown // UpDown Counter
#(parameter N=7)
(
input switch,
input button,
input clk,
output reg [N:0]count=8'd0,
);
always #(posedge clk)
begin
if(switch == 1 && button == 1) // Countup from 0 to 20
begin
if(count == 8'd20)
count <= 0 ;
else
count <= count +1;
end
else if(switch == 0 && button == 1) // Countdown from 20 to 0
begin
if(count == 8'd0)
count <= 8'd20 ;
else
count <= count -1;
end
else count <=8'd0;
end
endmodule
module mux(A,B,sel,Y); // 2x1 Multiplexer
input [3:0]A;
input [3:0]B;
input sel;
output [3:0]Y;
reg [3:0]Y;
always #(*)
begin
if(sel==0)
Y=A;
else
Y=B;
end
endmodule
module hex7seg(input wire [3:0]x , output reg[6:0]a_to_g); // Hex to 7seg Code
always #(*)
case(x)
0: a_to_g = 7'b0000001;
1: a_to_g = 7'b1001111;
2: a_to_g = 7'b0010010;
3: a_to_g = 7'b0000110;
4: a_to_g = 7'b1001100;
5: a_to_g = 7'b0100100;
6: a_to_g = 7'b0100000;
7: a_to_g = 7'b0001111;
8: a_to_g = 7'b0000000;
9: a_to_g = 7'b0000100;
'hA: a_to_g = 7'b0001000;
'hB: a_to_g = 7'b1100000;
'hC: a_to_g = 7'b0110001;
'hD: a_to_g = 7'b1000010;
'hE: a_to_g = 7'b0110000;
'hF: a_to_g = 7'b0111000;
default: a_to_g = 7'b0000001;
endcase
endmodule
module segment (a,b,fast,enable,seg7);
input [3:0]a;
input [3:0]b;
input fast;
output [3:0] enable;
output [6:0] seg7;
wire [3:0]e1 = 4'b1110;
wire [3:0]e2 = 4'b1101;
wire slow;
wire [3:0]number;
clock c1(fast,slow);
mux m1(a,b,slow,number);
mux m2(e1,e2,slow,enable);
hex7seg h1(number,seg7);
endmodule

You have a small error in segment module initialization part of code:
segment s1([3:0]count,[7:4]count,fastclk,enable,out);
This part of code should look a little bit different:
segment s1(count[3:0],count[7:4],fastclk,enable,out);

The big issue is:
segment s1([3:0]count,[7:4]count,fastclk,enable,out);
It should be:
segment s1(count[3:0],count[7:4],fastclk,enable,out);
Other option (IEEE Std 1364-2001 auto connect by name (.*)):
segment s1(.a(count[3:0]), .b(count[7:4]), .fast(fastclk), .seg7(out), .*);
Some simulators may complain about initial values on outputs with ANSI style port lists or trailing comma in the port list. So this:
output reg [N:0]count=8'd0,
);
Should be:
output reg [N:0] count
);
initial count=8'd0;
I prefer being able to control the reset in my designs, so I'd prefer:
input reset_n,
output reg [N:0] count
);
always #(posedge clk
// or negedge reset_n // <-- uncomment for asynchronous reset
) begin
if (!reset_n) begin
count=8'd0;
end
else begin
// synchronous code here
end
end
In main you have output reg[6:0] out. Since out is not assigned by an always-block in main (sub-modules don't count), it should be a wire not a reg. This one is a guideline as it is best practice for Verilog, most simulates tolerate it.

Related

1KHz Binary Counter: output stuck at 0000

I'm trying to build a 1KHz binary counter in Verilog for use in an FPGA. I want to get it to work in a single .v file before separating each module into it's own file and getting practice in calling modules that way.
As far as I can see, I've set up the logic and the connections properly but after compiling/programming into the FPGA, my hex displays are just stuck at 0 instead of incrementing through.
Can someone please take a look and tell me where I might be going wrong?
Notes:
The input CLK50 and the HEX(0-3) pins have been connected to their proper pins via Pin Assignment.
module IO_Test3(
input CLK50,
output [6:0] HEX0,
output [6:0] HEX1,
output [6:0] HEX2,
output [6:0] HEX3
);
wire CLOCK1;
wire count;
One_KHz_Clock clock(CLK50, CLOCK1);
Counter_16B counter(CLOCK1, count);
Display_Driver_SevenSeg display(CLOCK1,count,HEX0,HEX1,HEX2,HEX3);
endmodule
//////////////////////////////////////////////////////////////////////////////////////////////////
module Display_Driver_SevenSeg(
input CLOCK_1, // 1KHz clock
input wire count, //16 bit register
output wire [6:0] HEX0,
output wire [6:0] HEX1,
output wire [6:0] HEX2,
output wire [6:0] HEX3
);
reg[15:0] counter;
always#(*)
begin
counter <= count;
end
seg7 Dig0(counter[3:0], HEX0);
seg7 Dig1(counter[7:4], HEX1);
seg7 Dig2(counter[11:8], HEX2);
seg7 Dig3(counter[15:12], HEX3);
endmodule
//////////////////////////////////////////////////////////////////////////////////////////////////
module seg7(input [3:0] hex, output wire [6:0] segments);
reg[6:0] leds;
always #(*) begin
case (hex)
0: leds = 7'b0111111;
1: leds = 7'b0000110;
2: leds = 7'b1011011;
3: leds = 7'b1001111;
4: leds = 7'b1100110;
5: leds = 7'b1101101;
6: leds = 7'b1111101;
7: leds = 7'b0000111;
8: leds = 7'b1111111;
9: leds = 7'b1100111;
10: leds = 7'b1110111;
11: leds = 7'b1111100;
12: leds = 7'b0111001;
13: leds = 7'b1011110;
14: leds = 7'b1111001;
15: leds = 7'b1110001;
endcase
end
assign segments = ~leds;
endmodule
//////////////////////////////////////////////////////////////////////////////////////////////////
module Counter_16B(input CLOCK_1, //1KHz clock
output wire[15:0] count);
reg [15:0] r_reg;
wire [15:0] r_next;
initial
begin
r_reg = 0;
end
always #(posedge CLOCK_1)
begin
r_reg <= r_next;
end
assign count = r_reg;
assign r_next = r_reg + 1;
endmodule
//////////////////////////////////////////////////////////////////////////////////////////////////
module One_KHz_Clock(input CLOCK_50, //50MHz clock signal
output reg CLOCK_1);
reg[27:0] counter = 28'd0;
parameter divisor = 28'd50000;
always#(posedge CLOCK_50)
begin
counter <= counter + 28'd1;
if(counter >= (divisor - 1))
counter <= 28'd0;
CLOCK_1 <= (counter < divisor/2)?1'b1:1'b0;
end
endmodule
The count variable needs to be a vector [15:0] was one bit.
Verified using a small testbench.
The design counts now.
module IO_Test3(
input CLK50,
output [6:0] HEX0,
output [6:0] HEX1,
output [6:0] HEX2,
output [6:0] HEX3
);
wire CLOCK1;
wire [15:0] count;
One_KHz_Clock clock(CLK50, CLOCK1);
Counter_16B counter(CLOCK1, count);
Display_Driver_SevenSeg display(CLOCK1,count,HEX0,HEX1,HEX2,HEX3);
endmodule
//////////////////////////////////////////////////////////////////////////////////////////////////
module Display_Driver_SevenSeg(
input CLOCK_1, // 1KHz clock
input wire [15:0] count, //16 bit register
output wire [6:0] HEX0,
output wire [6:0] HEX1,
output wire [6:0] HEX2,
output wire [6:0] HEX3
);
reg[15:0] counter;
always#(*)
begin
counter = count;
end
seg7 Dig0(counter[3:0], HEX0);
seg7 Dig1(counter[7:4], HEX1);
seg7 Dig2(counter[11:8], HEX2);
seg7 Dig3(counter[15:12], HEX3);
endmodule
//////////////////////////////////////////////////////////////////////////////////////////////////
module seg7(input [3:0] hex, output wire [6:0] segments);
reg[6:0] leds;
always #(*) begin
case (hex)
0: leds = 7'b0111111;
1: leds = 7'b0000110;
2: leds = 7'b1011011;
3: leds = 7'b1001111;
4: leds = 7'b1100110;
5: leds = 7'b1101101;
6: leds = 7'b1111101;
7: leds = 7'b0000111;
8: leds = 7'b1111111;
9: leds = 7'b1100111;
10: leds = 7'b1110111;
11: leds = 7'b1111100;
12: leds = 7'b0111001;
13: leds = 7'b1011110;
14: leds = 7'b1111001;
15: leds = 7'b1110001;
endcase
end
assign segments = ~leds;
endmodule
//////////////////////////////////////////////////////////////////////////////////////////////////
module Counter_16B(input CLOCK_1, //1KHz clock
output wire[15:0] count);
reg [15:0] r_reg;
wire [15:0] r_next;
initial
begin
r_reg = 0;
end
always #(posedge CLOCK_1)
begin
r_reg <= r_next;
end
assign count = r_reg;
assign r_next = r_reg + 1;
endmodule
//////////////////////////////////////////////////////////////////////////////////////////////////
module One_KHz_Clock(input CLOCK_50, //50MHz clock signal
output reg CLOCK_1);
reg[27:0] counter = 28'd0;
parameter divisor = 28'd5;
always#(posedge CLOCK_50)
begin
counter <= counter + 28'd1;
if(counter >= (divisor - 1))
counter <= 28'd0;
CLOCK_1 <= (counter < divisor/2)?1'b1:1'b0;
end
endmodule
Here is the SV testbench (runs on edaplayground.com):
module tb ();
bit CLK50;
logic [6:0] HEX0;
logic [6:0] HEX1;
logic [6:0] HEX2;
logic [6:0] HEX3 ;
always
#5 CLK50 = ! CLK50;
initial
begin
#10000;
$finish;
end
initial
begin
$dumpfile("dump.vcd");
$dumpvars;
end
IO_Test3
u1(.*);
endmodule

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

Seven Segment Display outputs are unknown

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

Combining led, switches and buttons in verilog

I'm creating a basys2 board in verilog for a seven segment display to show in binary. I am using switches 0-3 and want to use the 4 buttons so that when button[0] is pushed, the binary number of the switches (up for 1, down for 0) displays. However, I'm stuck on how to integrate the buttons with the binary and the led. I'm new to verilog and having some trouble. Any suggestions?
module final(btn,clk,sw,cathodes,anodes,led,rst);
input clk,rst;
output [6:0] cathodes;
output [7:0] led;
output [3:0] anodes;
input [3:0] sw;
input [3:0] btn;
reg [6:0] cathodes;
reg [15:0] dig;
reg [3:0] anodes;
reg slow_clock;
integer count;
reg [7:0] led;
always # (posedge clk)
create_slow_clock(clk, slow_clock);
Stuck here at how to assign led:
always #(posedge clk)
begin
if (btn[0:3]);
begin
led[0]
led[1]
led[2]
led[3]
Also not sure this is correct:
always # (posedge slow_clock)
begin
led=~led;
if (rst == 0) anodes = 4'b1111;
else
begin
case (btn)
0: anodes = 4'b0111;
1: anodes = 4'b1011;
2: anodes = 4'b1101;
3: anodes = 4'b1110;
default: anodes = 4'b1111;
endcase
cathodes = calc_cathode_value(dig);
end
end
.
function[6:0] calc_cathode_value;
input [15:0] dig;
begin
case (dig)
0: calc_cathode_value = 8'b00000011;
1: calc_cathode_value = 8'b10011111;
2: calc_cathode_value = 8'b00100101;
3: calc_cathode_value = 8'b00001101;
4: calc_cathode_value = 8'b10011001;
5: calc_cathode_value = 8'b01001001;
6: calc_cathode_value = 8'b01000001;
7: calc_cathode_value = 8'b00011111;
8: calc_cathode_value = 8'b00000001;
9: calc_cathode_value = 8'b00001001;
'hA: calc_cathode_value = 8'b00010001;
'hb: calc_cathode_value = 8'b11000001;
'hC: calc_cathode_value = 8'b01100011;
'hd: calc_cathode_value = 8'b10000101;
'hE: calc_cathode_value = 8'b01100001;
'hF: calc_cathode_value = 8'b01110001;
default: calc_cathode_value = 8'b0000001;
endcase
end
endfunction
task create_slow_clock;
input clock;
inout slow_clock;
integer count;
begin
if (count > 250000)
begin
count = 0;
slow_clock = ~slow_clock;
end
count = count + 1;
end
endtask
endmodule
you signal btn is defined as 4-bit meaning that the case statement needs to represent all 16 possibilities from 0 to F. Think about what needs to happen when more then one button is pushed at the same time. If you only care about cases where 1 of the buttons is pushed then your case values would need to be 0,1,2,4 as each bit position represents another 2^n value.

dispalying S on 7 segments

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

Resources