How do I setup a counter to count seconds using Verilog - verilog

I'm trying to make a second counter and millisecond counter using Verilog. The Problem is that whenever I run a simulation, the value of the second counter (clk_1sec) and millisecond counter (clk_1msec) is fixed to 0.
My Simulation shows proper result until 19th line of the code, but the simulation doesn't show the proper result of clk_1sec and clk_1msec (value of those two counters are fixed to 0)
module clk_gen(clk_5k, reset, loopcount, clk_1sec, clk_1msec);
input clk_5k, reset;
output [14:0] loopcount;
output clk_1sec, clk_1msec;
reg [14:0] loopcount;
reg clk_1sec, clk_1msec;
always #(posedge clk_5k or negedge reset)
begin
if (~reset)
begin
clk_1sec <= 0; clk_1msec <= 0; loopcount <= 0;
end
else
loopcount <= loopcount + 2'b10;
begin
if (loopcount += 13'b1001110001000)
clk_1sec = ~clk_1sec;
else if (loopcount += 3'b101)
clk_1msec = ~clk_1msec;
end
end
end
end
endmodule
Expected result is that clk_1sec should change its value when the value of loopcount is loopcount + 5000 (decimal) and clk_1msec should change its value when the value of loopcount is loopcount + 5 (decimal).

There are some misunderstandings in your code:
You are using blocking assignments inside clocked always. You should use only non blocking assignments.
You are using 13 bit constants to operate with a 15 bit register (loopcount). You should use 15 bit constants.
And above all, you are using an improper way to tell if the value of loopcount is multiple of 5 (to count miliseconds). Multiples of something that is not a power of two is difficult to implement in hardware. Either you should use a power of two clock signal (32.768 kHz is a common clock for these applications) or you should use a counter to count cycles to get miliseconds and another one to count miliseconds to get one second.
Assuming a 32.768 kHz clock, your module would go like this:
module clk_gen (
input wire clk32768,
input wire reset,
output reg [15:0] loopcount,
output wire clk_1sec,
output wire clk_1msec
);
assign clk_1sec = loopcount[15]; // 1 exact second (32768 counts)
assign clk_1msec = loopcount[5]; // not quite 1ms, but 0.97ms
always #(posedge clk32768 or negedge reset) begin
if (~reset)
loopcount <= 16'd0;
else
loopcount <= loopcount + 16'd1;
end
endmodule
If you need to stick with a 5KHz clock and/or need precise milisecond measurement (within the limits of your clock oscillator), then you can do as this:
module clk_gen (
input wire clk_5k,
input wire reset,
output reg clk_1sec,
output reg clk_1msec
);
reg [2:0] counter_cycles; // counts from 0 to 4 cycles => 1ms
reg [9:0] counter_msecs; // counts from 0 to 999 msecons => 1s
always #(posedge clk_5k or negedge reset) begin
if (~reset) begin
clk_1sec <= 1'b0;
clk_1msec <= 1'b0;
counter_cycles <= 3'd0;
counter_msecs <= 10'd0;
end
else begin
if (counter_cycles == 3'd4) begin
counter_cycles <= 3'd0;
clk_1msec <= ~clk_1msec;
if (counter_msecs == 10'd999) begin
counter_msecs <= 10'd0;
clk_1sec <= ~clk_1sec;
end
else begin
counter_msecs <= counter_msecs + 10'd1;
end
end
else begin
counter_cycles <= counter_cycles + 3'd1;
end
end
end
endmodule
You can edit/simulate this version at
https://www.edaplayground.com/x/3CjH

The problem is improper nesting of begin/end blocks with the first else. Your indentation does not match what the compiler sees. And I'm sure you meant == instead of +=

Related

Why I can not copy a content of register to another one in "always" block in Verilog?

well, I have this code, that is working perfectly:
module syncRX(clk, signal, detect);
input clk, signal;
output reg [7:0] detect = 0;
reg [7:0] delay = 0;
//wire clk_1khz;
freq_div div(.clk(clk), .clk_1khz(clk_1khz));
always #(posedge signal)
begin
detect <= detect + 1;
delay <= 0;
end
always #(posedge clk_1khz)
begin
delay <= delay + 1;
end
endmodule // top
module freq_div(input clk, output reg clk_1khz);
reg [12:0] count = 0;
always #(posedge clk)
begin
if(count == 6000)
begin
clk_1khz <= ~clk_1khz;
count <= 0;
end
else
count <= count + 1;
end
endmodule
The problem appears when I change the line "detect <= detect + 1;" to "detect <= delay;".
The intention is calculate the period of the signal, but I get this warning message of Icestorm:
Warning: No clocks found in design
And the FPGA stop working...
Please, anyone have an idea what is going bad?
Thanks to all!
By the votes of the question I could see that is not good one, maybe because community consider it that there is already documented, but I still can not find solution to the problem, I did some improvements and I will try again to find help here, I have this code now, that syntethize perfectly:
module syncRX(clk, signal, detect);
input clk, signal;
output [7:0] detect;
reg [7:0] detect_aux = 8'b0;
reg rst;
assign detect = detect_aux & ~rst;
freq_div div(.clk(clk), .clk_1khz(clk_1khz));
always #(posedge signal)
rst <= 1;
always #(posedge clk_1khz)
detect_aux <= detect_aux + 1;
endmodule // top
module freq_div(input clk, output reg clk_1khz);
reg [12:0] count = 0;
always #(posedge clk)
begin
if(count == 6000)
begin
clk_1khz <= ~clk_1khz;
count <= 0;
end
else
count <= count + 1;
end
endmodule
The problem is that
reg rst;
assign detect = detect_aux & ~rst;
Seams do nothingh. Any suggestion?
Thanks
The problem is that delay is multiply driven (driving from multiple always blocks is not allowed in synthesis) which is undefined behaviour (in this case I believe the constant '0' will be used). It should also be at least a warning.

verilog sync issue with counter

i'm trying to create a 8 bit parallel to serial component that send the data and bit number.
the bit number and the transmitted serial data is not sent at the right time,
please see wave form
module counter
(
input clk,rst,
input [7:0]data,
output reg [7:0]cnt,
output reg data_Tx
);
parameter lim = 7;
always #(posedge clk or negedge rst)
if (!rst)
begin
cnt <= 0;
data_Tx <= 1'b1;
end
else
begin
if (clk)
begin
if (cnt < lim)
begin
data_Tx <= data[cnt];
cnt <= cnt +1;
end
else
cnt <= 0;
end
end
endmodule
please see wave form here
i have marked on the waveform (in blue) the bit numbers that supposed to be transmitted, as you can see they are shifted.
also, in red circle, the data_Tx needs to be '0' when transmitting the first bit from the parallel inputs, but i'ts '1'because of the rst line, how can i fix this situation?
should i use a state machine???
thank you
You have fallen into the standard trap all beginners with HDL have: your signals change after the clock edge. Take a few months of coding and dealing with this becomes second nature.
But before I deal with that: follow Greg's advice and remove the if (clk) from the code.
The first, simple solution, is to move the data_Tx <= data[cnt]; outside the clocked section:
assign data_Tx = data[cnt];
But beware that makes that after a reset (when cnt is zero) the data_Tx bit reflects your data[0] bit. So there is no guarantee that it is 1. Also it will change as soon as a new value is assigned to data.
If you want a synchronous data_Tx output and want the cnt to be inline you have to delay your cnt by a clock cycle:
....
reg [2:0] early_cnt;
always #(posedge clk or negedge rst)
if (!rst)
begin
cnt <= 0;
early_cnt <= 8'h00;
data_Tx <= 1'b1;
end
else
begin
cnt <= early_cnt;
if (early_cnt < lim)
begin
data_Tx <= data[early_cnt];
early_cnt <= early_cnt + 8'h01;
end
else
early_cnt <= 0;
end

Verilog Counter - 50MHz to 1Hz clock

How can I use this verilog code to generate a 1Hz clock signal while maintaining the counting functionality? Maxval enables the counter to count up to a certain value and then go back to 0 by reset and start over again. Or, it'll just reset and count again if it hits the maximum value. The thing is, my FPGA has a 50Mhz clock, but I need to use this counter with a 1Hz and a 2Hz clock. Any tips on adapting this code for that purporse?
module clocktime(input clk, freerun, Reset, output, input[7:0] Maxval, output reg[7:0] Count, output reg Carry);
always # (posedge clk or posedge Reset) begin
if ( Reset ) begin
Count <= 0;
Carry <= 0;
end
else
if ( freerun )
if ( Count < Maxval ) begin
Count <= Count + 8'd1;
Carry <= 0;
end
else begin
Count <= 0;
Carry <= 1;
end
end
endmodule
Start with increasing the width of Maxval and Count variables. You'll need 26 bits to fit a number of 50 millions there. Right now with 8 bits you can divide the clock by 255 at most.
To get additional outputs (1hz, 2hz) you can do something like this:
module top(clk50, reset, out_1hz, out_2hz);
input clk50;
input reset;
output out_1hz;
output out_2hz;
reg[25:0] clk50_divisor = 12500000;
reg [1:0] div2_4;
assign out_1hz = div2_4[1];
assign out_2hz = div2_4[0];
wire tmp_4hz;
clocktime div_clk50(
.clk(clk50),
.freerun(1),
.Reset(reset),
.Maxval(clk50_divisor),
.Carry(tmp_4hz));
always #(posedge tmp_4hz)
div2_4 <= div2_4 + 1'd1;
/* another option, might be better in your particular case,
or not different at all
always #(posedge clk50)
if (tmp_4hz)
div2_4 <= div2_4 + 1'd1;
*/
endmodule
module clocktime(clk, freerun, Reset, Maxval, Count, Carry);
input clk;
input freerun;
input Reset;
input [25:0] Maxval;
output reg[25:0] Count;
output reg Carry;
always # (posedge clk or posedge Reset) begin
if ( Reset ) begin
Count <= 0;
Carry <= 0;
end
else
if ( freerun )
if ( Count < Maxval ) begin
Count <= Count + 8'd1;
Carry <= 0;
end
else begin
Count <= 0;
Carry <= 1;
end
end
endmodule

Making Vivado Synthesis "A process triggered every clock cycle will not have functionality every clock cycle"

This is code for ALU that does addition and multiplication only. An addition is handled in same clock cycle but the multiplication result has to be delayed by 3 clock cycles.
module my_addmul(
//control signals
input i_clk,
input i_rst,
input i_en,
//add=01, mul=10
input [1:0] i_op,
//input and output registers
input [31:0] i_A,
input [31:0] i_B,
output [31:0] o_D,
//to signal if output is valid
output o_done
);
//registers to save output
reg [31:0] r_D;
reg [63:0] r_mul;//(*keep="true"*)
reg r_mul_done;
reg r_mul_done2;
reg r_done;
//updating outputs
assign o_D = r_D;
assign o_done = r_done;
always # (posedge i_clk)
begin
r_done <= 0;
r_mul_done <= 0;
if (i_rst) begin
r_D <= 0;
r_mul <= 0;
r_mul_done <= 0;
r_mul_done2 <= 0;
end else if (i_clk == 1) begin
if (i_en == 1) begin
//addition - assignment directly to OP registers
if (i_op == 01) begin
r_done <= 1;
r_D <= i_A + i_B;
//multiplication - indirect assignment to OP registers
end else if (i_op == 2'b10) begin
r_mul <= i_A * i_B;
r_mul_done <= 1;
end
end
//1-clock cycle delay
r_mul_done2 <= (r_mul_done == 1) ? 1 : 0;
//updating outputs in the 3rd cycle
if (r_mul_done2 == 1) begin
r_D <= r_mul[31:0];
r_done <= 1;
end
end
end
endmodule
The problem is that if the keep attribute is not used, the r_mul register that stores the multiplication output until 3rd clock cycle is optimised out. I read on the problem and realised that Vivado is thinking like this: "If the multiplication happens every clock cycle, the r_mul is over-written before it is sent to output. Therefore, it is a register being written but not read, Lets remove it!" Since I insert the 3 clock cycle wait in test bench, the simulation result is always accurate. I want to know what is the "Proper" way of doing this so I don't have to use the keep attribute. It is an ok solution but I think useful techniques should be learned so hacks don't have to be used. Any ideas or discussion welcome.
If I want to delay a signal, I'd probably insert flops for that. You can probably flop your mul_output like the way you do for the mul_done signal. Also, it is better to have different always blocks for doing the same. You can check the code below but it might be buggy since I haven't simulated/synthesized it -
module my_addmul(
//control signals
input i_clk,
input i_rst,
input i_en,
//add=01, mul=10
input [1:0] i_op,
//input and output registers
input [31:0] i_A,
input [31:0] i_B,
output [31:0] o_D,
//to signal if output is valid
output o_done
);
//registers to save output
reg [31:0] r_D;
reg [63:0] r_mul;//(*keep="true"*)
reg r_mul_1;
reg r_mul_2;
reg r_mul_done;
reg r_mul_done2;
reg r_done;
//updating outputs
assign o_D = r_D;
assign o_done = r_done;
always # (posedge i_clk)
begin
r_done <= 0;
r_mul_done <= 0;
if (i_rst) begin
r_D <= 0;
r_mul <= 0;
r_mul_done <= 0;
r_mul_done2 <= 0;
end else if (i_clk == 1) begin
if (i_en == 1) begin
//addition - assignment directly to OP registers
if (i_op == 01) begin
r_done <= 1;
r_D <= i_A + i_B;
//multiplication - indirect assignment to OP registers
end else if (i_op == 2'b10) begin
r_mul <= i_A * i_B;
r_mul_done <= 1;
end
end
end
end
always # (posedge i_clk)
begin
if (i_rst)
begin
r_mul_1 <= 0;
r_mul_done2 <= 0;
end
else
begin
r_mul_1 <= r_mul;
r_mul_done2 <= r_mul_done;
end
end
always # (posedge i_clk)
begin
if (i_rst)
begin
r_D <= 0;
r_done <= 0;
end
else
begin
r_D <= r_mul_1;
r_done <= r_mul_done2;
end
end
endmodule

Verilog: Check, if a signal is 100 ticks active?

I have one input and one output. And I want to turn the output to 1, if the input was 100 ticks active (100 cycles).
module check_100(
input wire clock,
input wire reset,
input wire in_a,
output reg out_a);
reg[10:0] counter;
always #(posedge clock) begin
counter <= counter + 1;
if(in_a && (counter == 100)) begin
out_a <= 1;
end
end
But it doesn't seem to work properly.
Is this a good way to check, whether a signal is 100 ticks/cycles active or not?
Thank you! :)
One way is to use a continuous assignment to set your output when count==100. When the input goes low, the counter is reset. Hold the count value when it hits 100.
module check_100(
input wire clock,
input wire reset,
input wire in_a,
output wire out_a
);
reg [10:0] counter;
assign out_a = counter == 100;
always #(posedge clock) begin
if (reset) begin
counter <= 0;
end else if (!in_a) begin
counter <= 0;
end else if (counter < 100) begin
counter <= counter + 1;
end
end
endmodule

Resources