Verilog code for down counting in 7 segment display from 9999 to 0630 - verilog

I want to write a code that counts backward from 9999 to 0630 and a reset button on FPGA Nexys3 when pressed the initial value will appear (9999).
Here is my block diagram:
I have finished the slow-clock module but I don't know in which module should I write the reset code? and what should it be?
If I knew the code of the counter (project module) I would be able to write the rest modules.
Please help me in writing the counter code and the reset code.

The reset functionality should be such that the outputs and internal registers are assigned initial counter values.
The reset value is 9999. The counter should count down from 9999 to 0630 on every clock pulse. After reaching 0630, it gets reset and it can optionally give an out pulse indication.
Following is a sample code, this may not be the optimum version.
module ctr(counter,reset,clk)//out
output reg [13:0] counter;
// output reg out;
input reset;
input clk;
always #(posedge clk, negedge reset) begin
if(!reset) begin
counter <= 14'd9999;
// out<=0;
end
else begin
if (counter == 14'd0630) begin
counter <= 14'd9999;
// out <= ~out;
end
else begin
counter <= counter -1;
end
end
end
endmodule

Related

Data bit not incremented during one clock cycle in mod16 counter

I am a beginner in Verilog designing and following is the design and test bench code I wrote for mod16 counter with load.
Design.v
module counter(
input clk,
input reset,
input load,
input [3:0] data);
always #(posedge clk)
begin
if(reset)
data<=4'b0000;
else if(load)
data<=load_input;
else
data<=data+1'b1;
end
endmodule
Testbench.v
module counter_tb ;
reg clk;
reg reset;
reg load;
reg[3:0] load_input;
reg[3:0]data;
counter ct_1(.*);
initial begin
clk = 1'b1;
load = 1'b0;
load_input = 4'b0000;
end
always begin #1 clk=~clk;end
initial begin
reset=1'b1;
#20;
reset=1'b0;
#10;
load=1'b1;
load_input=4'b0011;
#10;
load=1'b0;
load_input=4'b0000;
end
initial begin
$monitor("time=%0d,reset=%b,data=%d,load=%d,load_input=%d\n",$time,reset,data,load,load_input);
end
endmodule:counter_tb
The output I obtained with the monitor:
time=29,reset=0,data=5,load=0,load_input=0
time=30,reset=0,data=5,load=1,load_input=3
time=31,reset=0,data=3,load=1,load_input=3
..
The question is inspite of clock completing one cycle from time=29 to time=30, the data has remained constant = 5 and not incremented by 1 as per the design code.
Everything else is as expected.
What have I missed?
Can anyone help me out!
Thanks in advance.
I agree that initially there were some syntax errors but they all were minute typos while typing the question.
Answering my own question :
The logic of my design code was that at every posedge of the clock the data needs to be incremented by 1. At the time=30 the clk=0 which is negative edge and hence the data is not incremented by 1. Hence the data remained constant at time=30 and at time=31 it incremented by 1.
Thanks to everyone who tried to answer my question..

How to program a delay in Verilog?

I'm trying to make a morse code display using an led. I need a half second pulse of the light to represent a dot and a 1.5 second pulse to represent a dash.
I'm really stuck here. I have made a counter using an internal 50MHz clock on my FPGA. The machine I have to make will take as input a 3 bit number and translate that to a morse letter, A-H with A being 000, B being 001 and so on. I just need to figure out how to tell the FPGA to keep the led on for the specified time and then turn off for about a second (that would be the delay between a dot pulse and a dash pulse).
Any tips would be greatly appreciated.
Also, it has to be synthesizable.
Here is my code. It's not functioning yet. The error message it keeps giving me is:
Error (10028): Can't resolve multiple constant drivers for net "c3[0]"
at part4.v(149)
module part4 (SELECT, CLK, CLOCK_50, RESET, led);
input [2:0]SELECT;
input RESET, CLK, CLOCK_50;
output reg led=0;
reg [26:0] COUNT=0; //register that keeps track of count
reg [1:0] COUNT2=0; //keeps track of half seconds
reg halfsecflag=0; //goes high every time half second passes
reg dashflag=0; //goes high every time 1 and half second passes
reg [3:0] code; //1 is dot and 0 is dash. There are 4 total
reg [1:0] c3; //keeps track of the index we are on in the code.
reg [3:0] STATE; //register to keep track of states in the state machine
reg done=0; //a flag that goes up when one morse pulse is done.
reg ending=0; //another flag that goes up when a whole morse letter has flashed
reg [1:0] length; //This is the length of the morse letter. It varies from 1 to 4
wire i; // if i is 1, then the state machine goes to "dot". if 0 "dash"
assign i = code[c3];
parameter START= 4'b000, DOT= 4'b001, DASH= 4'b010, DELAY= 4'b011, IDLE=
4'b100;
parameter A= 3'b000, B=3'b001, C=3'b010, D=3'b011, E=3'b100, F=3'b101,
G=3'b110, H=3'b111;
always #(posedge CLOCK_50 or posedge RESET) //making counter
begin
if (RESET == 1)
COUNT <= 0;
else if (COUNT==8'd25000000)
begin
COUNT <= 0;
halfsecflag <= 1;
end
else
begin
COUNT <= COUNT+1;
halfsecflag <=0;
end
end
always #(posedge CLOCK_50 or posedge RESET)
begin
if (RESET == 1)
COUNT2 <= 0;
else if ((COUNT2==2)&&(halfsecflag==1))
begin
COUNT2 = 0;
dashflag=1;
end
else if (halfsecflag==1)
COUNT2= COUNT2+1;
end
always #(RESET) //asynchronous reset
begin
STATE=IDLE;
end
always#(STATE) //State machine
begin
done=0;
case(STATE)
START: begin
led = 1;
if (i) STATE = DOT;
else STATE = DASH;
end
DOT: begin
if (halfsecflag && ~ending) STATE = DELAY;
else if (ending) STATE= IDLE;
else STATE=DOT;
end
DASH: begin
if ((dashflag)&& (~ending))
STATE = DELAY;
else if (ending)
STATE = IDLE;
else STATE = DASH;
end
DELAY: begin
led = 0;
if ((halfsecflag)&&(ending))
STATE=IDLE;
else if ((halfsecflag)&&(~ending))
begin
done=1;
STATE=START;
end
else STATE = DELAY;
end
IDLE: begin
c3=0;
if (CLK) STATE=START;
else STATE=IDLE;
end
default: STATE = IDLE;
endcase
end
always #(posedge CLK)
begin
case (SELECT)
A: length=2'b01;
B: length=2'b11;
C: length=2'b11;
D: length=2'b10;
E: length=2'b00;
F: length=2'b11;
G: length=2'b10;
H: length=2'b11;
default: length=2'bxx;
endcase
end
always #(posedge CLK)
begin
case (SELECT)
A: code= 4'b0001;
B: code= 4'b1110;
C: code= 4'b1010;
D: code= 4'b0110;
E: code= 4'b0001;
F: code= 4'b1011;
G: code= 4'b0100;
H: code= 4'b1111;
default: code=4'bxxxx;
endcase
end
always #(posedge CLK)
begin
if (c3==length)
begin
c3<=0; ending=1;
end
else if (done)
c3<= c3+1;
end
endmodule
I have been reading your code and there are many issues:
The code is not formatted.
You did not provide a test-bench. Did you write one?
"Can't resolve multiple constant drivers for net" Search on stack exchange for the error message. It has been asked many times.
Use always #(*) not e.g. always #(STATE) you are missing signals like i, halfsecflag, ending. But see point 6: You want the STATE in a clocked section.
Where you use always #(posedge CLK) you must use non-blocking assignments: <=.
There are many places where you use always #(posedge CLK) where you want to use always #(*) (e.g. where you set length and code) Opposite you want to use a posedge CLK where you work with your STATE.
Use one clock and one clock only. Do not use CLK and CLOCK_50. Use either one or the other.
Take care of your vector sizes. This 8'd25000000 is wrong as you can no fit 25000000 in 8 bits.
Your usage of halfsecflag is excellent! I have see many times where people think they can use always #(halfsecflag) which is a recipe for disaster!
Below you find a small piece of your code which I have re-written.
All assignments are non-blocking <=
halfsecflag is essential to operate the code only every half a second, so I put that by itself in a separate if at the top. I would use that throughout the code.
All register are reset, both COUNT2 and dashflag.
dashflag was set to 1 but never set back to 0. I fixed that.
I specified the vector sizes. It makes the code "Lint proof".
Here is it:
always #(posedge CLOCK_50 or posedge RESET)
begin
if (RESET == 1'b1)
begin
COUNT2 <= 2'd00;
dashflag <= 1'b0;
end // reset
else if (halfsecflag) // or if (halfsecflag==1'b1)
begin
if (COUNT2==2'd2))
begin
COUNT2 <= 2'd0;
dashflag <=1'b1;
end
else
begin
COUNT2 <= COUNT2+2'd1;
dashflag <=1'b0;
end
end // clocked
end // always
Start fixing the rest of your code the same way. Write a test-bench, simulate and trace on a waveform display where things go wrong.
Normally you would build the finite state machine to produce the output. That machine would have some stages, like reading the input, mapping it to a sequence of morse code element, shifting out the elements to output buffer, waiting for conditions to move to the next morse element. You will need some timer that would produce one morse time unit intervals, and depending on the FSM stage you will wait one, three or seven time units. The FSM will spin in the waiting stage, it doesn't "magically" sleeps in some fpga-produced delay, there's no such things.
Okay a year later, I know exactly what one should do if they want to create a delay in their verilog program! Essentially, what you should do is create a timer using one of the clocks on your FPGA. For me on my Altera DE1-SoC, the timer I could use is the 50MHz clock known as CLOCK_50. What you do is make a timer module that triggers on the positive (or negative, doesn't matter) edge of the 50MHz clock. Set up a count register that holds a constant value. For example, reg [24:0] timer_limit = 25'd25000000; This is a register that can hold 25 bits. I've set this register to hold the number 25 million. The idea is to flip a bit every time the value in this register is exceeded. Here's some pseudocode to help you understand:
//Your variable declarations
reg [24:0] timer_limit = 25'd25000000; //defining our timer limit register
reg [25:0] timer_count = 0; //See note A
reg half_sec_clock;
always#(posedge of CLOCK_50) begin
if timer_count >= timer_limit then begin
reset timer_count to 0;
half_sec_clock = ~half_sec_clock; //toggle your half_sec_clock
end
Note A: Setting it to zero may or may not initialize count, it's always best to include a reset function that clears your count to zero because you don't know what the initial state is when you're dealing with hardware.
This is the basic idea of how to introduce timing into your hardware. You need to use an onboard clock on your device, trigger on the edge of that clock and create your own slower clock to measure things like seconds. The example above will give you a clock that triggers periodically every half second. For me, this allowed me to easily make a morse code light that could flash on either 1 half second count, or 3 half seconds. My best advice to you beginners is to work in a modular fashion. For example build your half second clock and then test it out to see if you can get a light on your FPGA to toggle once every half second (or whatever interval you want). :) I really hope this is the answer that helps you. I know this is what I was looking for when I originally posted this question so long ago.

registering and resetting the convolution output in verilog

so I have a module that does convolution, it takes a data input and the filter input , where input is array of 9 numbers , every posedge of the clk these two inputs are being multiplied and then added accumulatively, i.e I save every new multiplication product into a register. after each 9 iterations I have to save the result and reset it , but I have to do it in one clock cycle, since my new data is coming on the next posedge. So the issue that I am facing is how to not save data and reset the out without losing data? Please help if you have any suggestions. It also need to be mentioned that my conv_module is a sub-module and I will be instantiating it in a top module , so I have to access all the inputs and outputs from uptop.
This is the code that I've written so far, but it does not work the way I want it, cause I cannot tap the array of output numbers from the top module.
module mult_conv( input clk,
input rst,
input signed [4:0] a,
input signed[2:0] b,
output reg signed[7:0] out
);
wire signed [7:0] mult;
reg signed [7:0] sum;
reg [3:0] counter;
reg do_write;
reg [7:0] out_top;
assign mult = {{3{a[4]}},a} * {{5{b[2]}},b};
always #(posedge clk or posedge rst)
begin
if (rst)
begin
counter <= 4'h0;
addr <= 'h0;
sum <= 0;
do_write <= 1'b0;
end // rst
else
begin
if (counter == 4'h8)
begin // we have gathered 9 samples
counter <= 4'h0;
// start again so ignore old sum
sum <= mult;
out <= sum;
out_top <= out;
end
else
begin
counter <= counter + 4'h1;
// Add results
sum <= sum + mult;
out <= 0;
out_top <= out_top;
end
// Write signal has to be set one cycle early
do_write = (counter==4'h7);
end // clocked
end // always
endmodule
You have a plethora of errors in that code.
Apart from that you have a 3Mega bit memory from which you use only 1 in 9 locations.
You write out in two places. That does not work.
You use a %9. That can not be mapped onto hardware.
You have a sel signal which somehow controls your sum.
On top of that I understand you want to bring the whole memory out.
Your code because it needs to be drastically re-written.
But your biggest problem is that you definitely can't make the memory come out. What ever post-processing you want to do you have two choices:
Process the output data as it appears.
Store the data outside the module in a memory and have another process read that memory.
I think only (1) is the correct way because your signal can have infinite length.
As to fixing this code a bit:
Replace the %9 with a counter to count from 0 to 8.
Process out in in clocked section. See below
Move the addr and sel generating logic in here. Keep it all together.
Below is the basic code of how to do a 9-sequence convolution. I have to ignore 'sel' as I have no idea of the timing. I have also added address generation and a write signal so the result can be store in an external memory. But I still think you should process the result on the fly.
always #(posedge clk or posedge rts)
begin
if (rst)
begin
counter <= 4'h0;
addr <= 'h0;
sum <= 0;
do_write <= 1'b0;
end // rst
else
begin
if (counter == 4'h8)
begin // we have gathered 9 samples
counter <= 4'h0;
addr <= addr + 1;
// start again so ignore old sum
sum <= mult;
end
else
begin
counter <= counter + 4'h1;
// Add results
sum <= sum + mult;
end
// Write signal has to be set one cycle early
do_write = (counter==4'h7);
end // clocked
end // always
(Code above was entered on-the fly, may contain syntax, typing or other errors!!)
As you can see the trick is to know when to add the old result or when to ignore the old sum and start again.
(I spend about 3/4 of an hour on that so on my normal tariff you would have to pay me $93.75 :-)
I provided the basic code to let you work out the specifics. I did nothing with out but left that to you.
do_write and addr where for a possible memory to pick up the result. Without memory you can drop addr but do_write should tell you when a new convolution result is available, in which case you might want to give a it a different name. e.g. 'sum_valid'.

1second down counter with initial value verilog code

I want to write the code of 1-second down counter that get the initial value from outside and count it down till 0. but there is a problem. How can I get the initial value. i tried some ways but ....
here is the code:
module second_counter ( input clk,
input top_num,
output reg [3:0] sec_num
);
parameter clk_frequency = 25;
reg [31:0]cnt;
wire [3:0]sec;
/// how can get the top_num and count it down.
assign sec=top_num;
always #(posedge clk)
begin
if (cnt==clk_frequency)
begin
sec <= sec -1;
cnt<=0;
end
else
cnt <=cnt+1;
end
What you basically need is a reset signal. Just like clock, reset is to be added in the sensitivity list.
After instantiation of module, you must apply a reset signal to initialize all the internal variables and registers of design.
Following code gives you initial value of cnt by reset application. This is an active low reset.
module second_counter ( input clk, input reset, input top_num, output reg [3:0] sec_num );
parameter clk_frequency = 25;
reg [31:0]cnt;
// wire [3:0]sec;
reg [3:0] sec;
///
// assign sec=top_num;
always #(posedge clk, negedge reset)
begin
if(!reset)
begin
cnt<=0; // initialize all internal variables and registers
sec<=0;
end
else
begin
if(sec == 0) // latch input when previous count is completed
sec<=top_num;
if (cnt==clk_frequency)
begin
sec <= sec -1;
cnt<=0;
end
else
cnt <=cnt+1;
end
end
Note that this is an asynchronous reset, means it does not depend on clocking signal. Synchronous reset is the one which only affects the registers at the clock pulse.
Edit:
Regarding to sec, I have modified the code. Now the design latches the inputs for one clock cycle and counts down to zero. Once the counter reaches zero, it again latches the input to re-count to zero.
Note that you cannot do like latching top_num at every clock and counting through zero (since top_num can change at every pulse). For latching at every clock pulse, you need more complex logic implementation.

Please help identify the mistake in this clock divider code

Clock divider from 50mhz (verilog code). I am trying to burn this on fpga but its not working properly. I am using model sim from mentor graphics. Please help identify my mistake.
module clk_div(
clk,
rst,
count);
parameter count_width=27;
parameter count_max=25000000;
output [count_width-1:0] count;
reg [count_width-1:0] count;
input clk,rst;
initial
count=0;
always#(posedge clk)
if (rst)
begin
count<=0;
end
else if (count<count_max-1)
begin
count<=count+1;
end
else if (count==count_max)
begin
count <=~count;
end
else if (count>count_max)
begin
count<=0;
end
endmodule
Three things. First, you need begin and end for your always block. Second, why are you doing count <= ~count when the count hits the max? Shouldn't you just set it back to 0? Third, you can't give the internal count register the same name as the count output. You will need to call one of them something else. Actually, why do you want to output count? If this is a clock divider, you want to output another clock, right? The following should work.
module clk_div(
clk,
rst,
outclk);
parameter count_width=27;
parameter count_max=25000000;
reg [count_width-1:0] count;
input clk,rst;
output outclk;
reg intern_clk;
assign outclk = intern_clk;
initial begin
count=0;
intern_clk=1'b0;
end
always #(posedge clk) begin
if (rst)
count <= 0;
else if (count == count_max) begin
count <= 0;
intern_clk <= !intern_clk;
end else
count <= count + 1'b1;
end
endmodule
But it seems like you are trying to divide the clock down to 1 Hz. That's quite a lot. I recommend you use a PLL instead of making your own clock divider. Since you mention a 50 MHz clock, I'm guessing you are using an Altera FPGA? If so, open up the MegaWizard plugin manager and create a PLL.

Resources