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

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

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.

ModelSim simulation works but FPGA fails. What am I missing?

Sorry if anything in here seems obvious but I am starting out in this new FPGA thing and I really enjoy it so far but this is driving me crazy.
Here is the Verilog code for a block that should in principle do the following to an 8 bit register:
00000001
00000010
00000100
.....
01000000
10000000
01000000
00100000
module bit_bouncer(clock, enable, bouncer_out);
//INPUTS PORTS
input clock;
input enable;
//OUTPUTS PORTS
output bouncer_out;
//INPUT DATA TYPE
wire clock;
wire enable;
//OUTPUT DATA TYPE
reg [7:0] bouncer_out = 8'b00000001;
//Register to store data
reg direction = 0;
//CODE STARTS HERE
always # (posedge clock) begin
if(enable) begin
bouncer_out = direction ? (bouncer_out >> 1) : (bouncer_out << 1);
direction <= (bouncer_out == 8'b00000001 || bouncer_out == 8'b10000000) ? ~direction : direction;
end
end
endmodule
This works perfectly in simulation but fails on the FPGA (DE10-Nano board, if interested).
I should also point out that this gets driven by a clock passed trough a PLL on the FPGA that is then
passed trough a divideByN block.
Here is the code for the divideByN block:
module clk_divn #(
parameter WIDTH = 20,
parameter N = 1000000)
(clk,reset, clk_out);
input clk;
input reset;
output clk_out;
reg [WIDTH-1:0] pos_count = {WIDTH{1'b0}};
reg [WIDTH-1:0] neg_count = {WIDTH{1'b0}};
wire [WIDTH-1:0] r_nxt = {WIDTH{1'b0}};
always #(posedge clk)
if (reset)
pos_count <=0;
else if (pos_count ==N-1) pos_count <= 0;
else pos_count<= pos_count +1;
always #(negedge clk)
if (reset)
neg_count <=0;
else if (neg_count ==N-1) neg_count <= 0;
else neg_count<= neg_count +1;
assign clk_out = ((pos_count > (N>>1)) | (neg_count > (N>>1)));
endmodule
The divideByN has also been tested in simulation and works fine.
I actually made a simulation in which the divideByN is connected to the "bouncer_block" if I can
call it like that and it also works.
Everything simulates but nothing works in real life....but isn't it always like that :P
I hope someone can help me figure this out because I really want to learn more about FPGA and use
them in future projects.
If you read all this you are awesome and I wish you an amazing day :)
Your bit bouncer is not operating synchronously to the system clock and neither does it have a reset condition, which is a recipe for trouble.
A better approach is to use a clock strobe and test for it on edges of the main system clock. Also, all inputs from tactile buttons should be synchronised to the system clock and debounced. Something like this:
Schematic
RTL
BitBouncer
module BitBouncer
(
input wire clock,
input wire reset,
input wire enable,
input wire clock_strobe,
output reg[7:0] bouncer_out
);
// Register to store data
reg direction = 0;
// CODE STARTS HERE
always #(posedge clock)
begin
if (reset)
begin
bouncer_out = 1;
direction = 0;
end
else if (enable && clock_strobe)
begin
bouncer_out = direction ? (bouncer_out >> 1) : (bouncer_out << 1);
direction <= (bouncer_out == 8'b00000001 || bouncer_out == 8'b10000000) ? ~direction : direction;
end
end
endmodule
ClockStrobe
module ClockStrobe
#(
parameter MAX_COUNT = 50000000
)
(
input wire clock,
input wire reset,
output reg clock_strobe
);
reg [$clog2(MAX_COUNT) - 1: 0] counter;
always #(posedge clock)
begin
if (reset)
begin
counter <= 0;
end
else
begin
counter <= counter + 1;
if (counter == MAX_COUNT)
begin
clock_strobe <= 1;
counter <= 0;
end
else
begin
clock_strobe <= 0;
end
end
end
endmodule
Sync
module Sync
(
input wire clock,
input wire in,
output reg out
);
reg [2:0] sync_buffer;
initial
begin
out = 0;
sync_buffer = 3'd0;
end
always #*
begin
out <= sync_buffer[2];
end
always #(posedge clock)
begin
sync_buffer[0] <= in;
sync_buffer[2:1] <= sync_buffer[1:0];
end
endmodule
Debounce
module Debounce
#(
parameter MAX_COUNT = 2500000
)
(
input wire clock,
input wire in,
output reg out
);
reg previous_in;
reg [$clog2(MAX_COUNT) - 1:0] counter;
initial begin
previous_in = 0;
counter = 0;
out = 0;
end
always #(posedge clock)
begin
counter <= counter + 1;
if (counter == MAX_COUNT)
begin
out <= previous_in;
counter <= 0;
end
else if (in != previous_in)
begin
counter <= 0;
end
previous_in <= in;
end
endmodule
I have tried to add a reset with no success but I have made my own divideByN and kept the reset Charles suggested and now it's working flawlessly. I think the code for the divideByN I took online might be unable to synthesize properly. Here is my new code for the divideByN:
module my_div_n #(parameter N = 1_000_000, parameter WIDTH = 20) (clock_in,
clock_out);
input wire clock_in;
output reg clock_out;
reg[WIDTH-2:0] counter; //WIDTH-2 because the last bit is taken care of by the fact that we flip the output (it acts as the last bit)
always # (posedge clock_in) begin
counter <= counter + 19'b1;
if(counter == N>>1) begin
counter <= 0;
clock_out <= !clock_out;
end
end
endmodule
And the code for my bit_bouncer:
module bit_bouncer(clock, enable, reset, bouncer_out);
//INPUTS PORTS
input clock;
input enable;
input reset;
//OUTPUTS PORTS
output [7:0] bouncer_out;
//INPUT DATA TYPE
wire clock;
wire enable;
wire reset;
//OUTPUT DATA TYPE
reg [7:0] bouncer_out;
//Register to store data
reg direction;
//CODE STARTS HERE
always # (posedge clock) begin
if(reset) begin
bouncer_out <= 8'b00000001;
direction <= 0;
end
else if(enable) begin
bouncer_out = direction ? (bouncer_out >> 1) : (bouncer_out << 1);
direction <= (bouncer_out == 8'b00000001 || bouncer_out == 8'b10000000) ? ~direction : direction;
end
end
endmodule
Here how everything is wired:
I would still like to know the purpose of the clock strobe because you make it seem as if I should probably know this if I want to understand my circuit better and all about synchronicity.

How do I setup a counter to count seconds using 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 +=

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

Resources