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
Related
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
I'm somewhat new to verilog. So this question might be very simple.
I'm trying to simulate an finite state machine using verilog.
Brief description:
There are three states: 0,1 & 2. By default, State is 0.
The state changes to 1 only if input is 01.
The state changes to 2 only if input is 10.
The state changes back to 0 only if input is 00.
The code is getting simulated successfully, but I.m getting no output. Please help me with the problem.
Code: (State.v)
module State(
input clk,
input reset,
input [3:0] in,
output [3:0] out,
output [3:0] state
);
wire clk,reset;
wire [3:0] in;
reg [3:0] out;
reg [3:0] state;
always #(posedge clk or posedge reset)
begin
if (reset == 1)
begin
state = 0;
end
else
begin
case (state)
0: if(in == 2'b01)
state = 1;
else
state = 0;
1: if(in == 2'b10)
state = 2;
else
state = 1;
2: if(in == 2'b00)
state = 0;
else
state = 2;
default: state = 0;
endcase
end
end
always #(*)
begin
case (state)
0: out = 2'b00;
1: out = 2'b01;
2: out = 2'b10;
default: out = 2'b00;
endcase
end
endmodule
Testbench: (StateTestBench.v)
module StateTestBench;
// Inputs
reg clk;
reg reset;
reg [3:0] in;
// Outputs
reg [3:0] out;
reg [3:0] state;
always
begin
#1 clk = !clk;
end
// Instantiate the Unit Under Test (UUT)
State uut (
.clk(clk),
.reset(reset),
.in(in),
.out(out),
.state(state)
);
initial begin
// Initialize Inputs
clk = 0;
reset = 0;
#1 reset = 1;
#10 reset = 0;
#5 in = 2'b00;
#10 in = 2'b01;
#10 in = 2'b10;
end
endmodule
I guess you simulate state.v instead of StateTestBench.v. Because your testbench has a bug! Outputs out and state MUST be wires.
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
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.
Hi i am using the folowing code to design a n-bit counter.
Depending on the start and end i want to instantiate up or down counter.
But i am getting "Malformed statement". Please help.
module nbitUpCounter(startc,endc , clk, rst_n,actlow,count);
parameter n = 7;
output reg [n:0] count;
input [n:0] startc;
input [n:0] endc;
input clk;
input rst_n;
input actlow;
// Increment count on clock
always #(actlow or posedge clk or negedge rst_n)
begin
if (actlow == 0)
begin
if (rst_n==0)
count = startc;
else if (count==endc) count=startc;
else count = count + 1;
end
end
endmodule
module nbitDownCounter(startc,endc , clk, rst_n,actlow,count);
parameter n = 7;
output reg [n:0] count;
input [n:0] startc;
input [n:0] endc;
input clk;
input rst_n;
input actlow;
// Increment count on clock
always #(actlow or posedge clk or negedge rst_n)
begin
if (actlow == 0)
begin
if (rst_n==0)
count = startc;
else if (count==endc) count=startc;
else count = count - 1;
end
end
endmodule
module Init(startc,endc , clk, rst_n,actlow,count);
parameter n = 7;
output wire [n:0] count;
input [n:0] startc;
input [n:0] endc;
input clk;
input rst_n;
input actlow;
generate
initial
begin
if(startc>endc)
nbitDownCounter c(startc, endc, C_t,rst_t,actlow,count);
end
endgenerate
endmodule
module Testbench;
reg [7:0] startc, endc;
reg C_t, rst_t;
reg actlow;
wire [7:0] outc;
initial
begin
//case 0
startc <= 8'b00000011; endc <= 8'b0000001;
//Init i(startc,endc,C_t,rst_t,actlow,count);
actlow<=0;
C_t <=1; rst_t <=0;
#1 $display("count = %b",outc );
//case1
rst_t<=1;C_t<=0;C_t<=1;
#1 $display("count = %b",outc );
//Case3
C_t<=0;C_t<=1;
#1 $display("count = %b",outc );
//Case3
C_t<=0;C_t<=1;
#1 $display("count = %b",outc );
end
endmodule
You're trying to instantiate your module in an initial block, which is illegal. Removing the initial begin inside module Init should solve the problem. Have a look at this page for an example: http://asic-soc.blogspot.de/2012/06/verilog-hdl-generate-blocks.html