Counter that loops through 6 values and then resets - verilog

This is a counter that loops through
only 6 values over and over again (0, 1, 2, 3, 4, 5, 0, 1, ...). The counter should include a “reset”
signal that will cause the counter value to reset to 0 when reset goes high (asynchronous reset),
and the counter value should increment on the rising edge of clock.
Here is the code I have. But, how would I make it reset once it reaches the number 5?
always #(posedge CLOCK_50 or negedge reset_n) begin
if (!reset_n)
count <= 0;
else if (enable)
count <= count + 1;
end

Use another if/else to check if count is 5, then set it to 0:
reg [2:0] count;
always #(posedge CLOCK_50 or negedge reset_n) begin
if (!reset_n) begin
count <= 0;
end else if (enable) begin
if (count == 5) begin
count <= 0;
end else begin
count <= count + 1;
end
end
end

simply use
always #(posedge CLOCK_50 or negedge reset_n) begin
if (!reset_n)
count <= 0;
else if (enable)
count <= (count == 5)? 'd0 : count + 1;
end
or split comb and seq
assign count_next = (count == 5)? 0 : count + 1;
always #(posedge CLOCK_50 or negedge reset_n) begin
if (!reset_n)
count <= 0;
else if (enable)
count <= count_next;
end

Related

How to get outputs/pulses when counter reaches two particular values?

I have created a counter that counts up to 30. I have an output signal out. At two particular counts, i.e., when counter reaches 10 (first) and when counter reaches 15 (second), I want the output to become low. Somehow I'm missing a basic logic here as only at one particular count (either at 10 or 15) I'm able to make the output zero.
Here is the code
module user_def_pulse(
output integer counter,
output reg out,
input clk, reset
);
parameter no_of_counts = 30;
parameter first = 10;
parameter second = 15;
initial
begin
counter = 0;
out = 1'b0;
end
always #(posedge clk)
begin
if (reset)
begin
counter <= 1'b0;
end
else if (counter == no_of_counts)
begin
counter <= 1'b0;
out <= 1'b0;
end
else
begin
if ((counter == first) || (counter == second))
out <= 1'b0;
else
begin
counter <= counter + 1;
out <= 1'b1;
$display($time," The value of counter is %d", counter);
end
end
end
endmodule
Here is the test bench
module user_def_pulse_tb(
);
parameter time_period = 10;
wire [31:0] COUNTER;
wire OUT;
reg CLK, RESET;
user_def_pulse udp1 (.counter(COUNTER), .out(OUT), .clk(CLK), .reset(RESET));
initial
begin
CLK = 1'b0;
RESET = 1'b1;
#20 RESET = 1'b0;
end
always
#time_period CLK = ~CLK;
endmodule
Here is the output waveform.
The problem with your code is that is stops incrementing the counter as soon as it hits the first value. You need to keep incrementing the counter. I moved the increment outside of the if ((counter == first) || ... clause.
always #(posedge clk) begin
if (reset) begin
counter <= 1'b0;
end else if (counter == no_of_counts) begin
counter <= 1'b0;
out <= 1'b0;
end else begin
counter <= counter + 1;
$display($time," The value of counter is %d", counter);
if ((counter == first) || (counter == second)) begin
out <= 1'b0;
end else begin
out <= 1'b1;
end
end
end

Counter through Verilog

I'm developing a counter in Verilog that cycles through the following series:
0, 1, 3, 7, 6, 4, 0, 1, ...
and resets to 0 on reset_b.
Here is my code so far, it doesn't seem to make it past 3 in the cycle:
module Counter_1(output reg [2: 0] Count, input clock, reset);
reg [2: 0] last;
always #(posedge clock, negedge reset) begin
if (!reset) begin
Count <= 3'b000;
end
else begin
case (last)
3'b000: Count <= 3'b001;
3'b001: Count <= 3'b011;
3'b011: Count <= 3'b111;
3'b111: Count <= 3'b110;
3'b110: Count <= 3'b100;
3'b100: Count <= 3'b000;
endcase
end
last <= Count;
end
endmodule
It is always useful to look at the sequence:
000
001
011
111
110
100
Analyse the pattern and you find the sequence can be made by:
if (!reset)
Count <= 3'b000;
else
Count <= {Count[1:0],~Count[3]};
To follow your method: you can just use the Count as input for the next value. The usage of 'last' is not needed:
case (Count)
3'b000 : Count <= 3'b001;
3'b001 : Count <= 3'b011;
You should certainly be assigning last in the reset block:
if (!reset) begin
last <= 3'b000;
Count <= 3'b000;
end
I'd imagine that will fix your issue, as I don't see any other problems with your code (assuming your clock and reset inputs work correctly and you're using an active high reset).
Also, why are you including reset in your always condition? I believe that your always condition could simply be:
always #(posedge clock) begin

In verilog, how to double the high signal and keep the low signal same

the picture indicates what I want the output signal is: the high signal double and the low signal keep same.
I wrote the code like:
integer x=0, count_valid=1, count_down=0;
reg valid_1, valid_reg;
always#(posedge clk)
begin
if(tag==1) begin
if(valid) begin
count_valid <= count_valid +1;
x<=x+1;
valid_reg <= 1;
end
else begin
x<=0;
count_down <= count_down+1;
if(count_valid>0) begin
valid_reg <= 1;
count_valid <= count_valid -1;
end
else if(count_down>0) begin
valid_reg <= 0;
count_down <= count_down-1;
end
end
end
else begin
valid_reg <= valid;
if (valid) x<=x+1;
else x<=0;
end
valid_1 <= valid_reg;
end
valid is the original signal in the picture and valid_reg is the modified signal. the count_valid is used to count how many cycles for high and use it to sub one to achieve the doubling. then count_down is for counting the cycles of low signal. but I realized when valid high the valid_reg will high.
can anyone give me some idea how to make the low signal run same cycles in output signal? any idea is also great.
You didn't mention if the input signal was periodic or not. Given the fact that your output is stretched over time, if the input is not periodic, then you would need infinite storage to keep track of what the input signal looked like. If it is periodic, or quasi-periodic, you can do something like below.
Keep track of the high count and low count in one block, and generate the output signal in another block, using the current registered values of the counts. Getting the output's first edge to line up with the input's is kind of tricky, requiring a mux, selected depending on whether it's the first time through the loop or not.
integer count, count_q, countdown, countdown_q, outcount;
logic valid_q, valid_reg, out_q;
logic new;
always #(posedge clk or negedge reset_n)
begin
if(~reset_n)
begin
if(~reset_n)
begin
new <= 1;
valid_q <= 0;
count_q <= 0;
countdown_q <= 0;
end
else
begin
valid_q <= valid;
if(valid & ~valid_q)//rising edge
begin
count <= 1;
countdown_q <= countdown;
end
else if(~valid & valid_q)//falling edge
begin
new <= 0;
count_q <= count;
countdown <= 1;
end
else if(valid)
count <= count+1;
else
countdown <= countdown+1;
end
end
end
always #(posedge clk or negedge reset_n)
begin
if(~reset)
begin
outcount <= 0;
out_q <= 0;
end
else
begin
if(new & valid & ~valid_q)
begin
out_q <= 1;
outcount <= 2;//valid_reg is already high here
end
else
if(out_q && (outcount == (count_q<<1)))
begin
out_q <= 0;
outcount <= 1;
end
else if(~out_q && (outcount == (countdown_q)))
begin
out_q <= 1;
outcount <= 1;
end
else
outcount <= outcount + 1;
end
end
assign valid_reg = new? valid : out_q;//this gets your initial rising edge lined up

How do I toggle a sample clock every n clock cycles?

I am new to Verilog, so I am not sure how to go about doing this. I have a clock, 'samp_clk', that toggles every 10 clock cycles of the system clock, 'clock' (or that's what I tried to do). This is what I have so far:
//'counter' counts the number of rising edges for system clock
//'samp_clk' is the sample clock, 'clock' is system clock
always # (posedge clock)begin
if(~reset)begin
if(counter == 10)begin
samp_clk <= 1;
counter <= 0;
end
else begin
samp_clk <= 0;
counter <= counter + 1;
end
end
end
The way I wrote it, I feel like my samp_clk will only stay asserted for one clock cycle. How can I make it so that it toggles between 1 and 0 every ten clock cycles?
From your code:
if(counter == 10)begin
samp_clk <= 1;
counter <= 0;
end
This will result to 11 clock cycles since we start counting from 0 to 10.
First step, define a counter wherein it resets to a certain
number (clock cycles). For example, you want to detect 10 clock
cycles (n = 10), when counter is more than or equal to 9,
it sets back to 0.
always # (posedge clk)begin
if(~reset)begin
counter <= 0;
end
else begin
if(counter >= 9)begin
counter <= 0;
end
else begin
counter <= counter + 1;
end
end
end
Then simply, toggle samp_clk based from the counter when it's equal to n-1 (10 - 1 = 9).
always #(posedge clk) begin
if (~reset) begin
samp_clk <= 0;
end
else begin
if (counter == 9) begin
samp_clk <= ~samp_clk;
end
end
end
Notice that I've separated two flip-flops to make debugging easy
and clear enough to understand its logic.
Here is the code with a test bench included.
module ten_clock(input clk, reset, output reg samp_clk);
reg [7:0] counter;
//'counter' counts the number of rising edges for system clock
always # (posedge clk)begin
if(~reset)begin
counter <= 0;
end
else begin
if(counter == 10)begin
//samp_clk <= 1;
counter <= 0;
end
else begin
//samp_clk <= 0;
counter <= counter + 1;
end
end
end
//'samp_clk' is the sample clock, 'clock' is system clock
always #(posedge clk) begin
if (~reset) begin
samp_clk <= 0;
end
else begin
if (counter == 9) begin
samp_clk <= ~samp_clk;
end
end
end
endmodule
module test;
reg clk, reset;
wire samp_clk;
ten_clock ten_clock(.*);
initial begin
clk = 0;
forever #1 clk = !clk;
end
initial begin
reset <= 1;
repeat (2) #(posedge clk);
reset <= 0;
repeat (2) #(posedge clk);
reset <= 1;
repeat (100) #(posedge clk);
$finish;
end
initial begin
$dumpfile("dump.vcd"); $dumpvars;
end
endmodule
You can try to run this
code and see the wave form
if this behavior is what you expect.
You want to toggle it, so toggle it.
Also note that to toggle every 10 clocks, you will have to set your counter to 0 when its value is 10-1.
Try this (not tested):
//'counter' counts the number of rising edge s for system clock
//'samp_clk' is the sample clock, 'clock' is sy stem clock
always # (posedge clock)begin
if(~reset)begin
if(counter == 9)begin
samp_clk <= ~samp_clk;
counter <= 0;
end
else begin
counter <= counter + 1;
end
end
else begin
samp_clk <= 0;
end
end
You are correct, this code sets samp_clk to be 1 when the counter is 10 and otherwise sets it to 0. This means you will have a signal which is asserted for 1 clock cycle and low for 10 clock cycles. The basic logic is correct (count for 10 clock cycles) but the value given to samp_clk is incorrect.
What you want to have is that samp_clk is the same value as it was in the previous cycle if counter ins't 10 and to flip samp_clk when it is. To flip a signal you want to assign the signal to the inverse of a signal: samp_clk <= ~samp_clk.
After you have that working you might need to refactor your code because I think it is going to produce latches in its current state.

Place 30-574 Poor placement for routing between an IO pin and BUFG

`timescale 1ns / 1ps
module stopwatch(
input clock,
input reset,
input increment,
input start,
output [6:0] seg,
output dp,
output [3:0] an
);
reg [3:0] reg_d0, reg_d1, reg_d2, reg_d3; //registers that will hold the individual counts
reg [22:0] ticker;
wire click;
//the mod 1kHz clock to generate a tick ever 0.001 second
always # (posedge (clock) or posedge (reset))
begin
if(reset)
begin
ticker <= 0;
end
else
begin
if (start)
begin
if(ticker == (100000 - 1)) //if it reaches the desired max value reset it
ticker <= 0;
else if (increment)
ticker <= ticker;
else
ticker <= ticker + 1;
end
end
end
//increment a second everytime rising edge of down button
reg [3:0] inc_temp;
always # (posedge (increment))
begin
if (reg_d3 == 9)
inc_temp = 0;
else
inc_temp = reg_d3 + 1;
end
assign click = ((ticker == (100000 - 1))?1'b1:1'b0); //click to be assigned high every 0.001 second
//update data start from here
always # (posedge (clock) or posedge (reset))
begin
if(reset)
begin
reg_d0 <= 0;
reg_d1 <= 0;
reg_d2 <= 0;
reg_d3 <= 0;
end
else
begin
if (increment)
begin
reg_d3 <= inc_temp;
reg_d0 <= reg_d0;
reg_d1 <= reg_d1;
reg_d2 <= reg_d2;
end
else if (click) //increment at every click
begin
if(reg_d0 == 9) //xxx9 - 1th milisecond
begin
reg_d0 <= 0;
if (reg_d1 == 9) //xx99 - 10th milisecond
begin
reg_d1 <= 0;
if (reg_d2 == 9) //x999 - 100th milisecond
begin
reg_d2 <= 0;
if(reg_d3 == 9) //9999 - The second digit
reg_d3 <= 0;
else
reg_d3 <= reg_d3 + 1;
end
else
reg_d2 <= reg_d2 + 1;
end
else
reg_d1 <= reg_d1 + 1;
end
else
reg_d0 <= reg_d0 + 1;
end
else
begin
reg_d3 <= reg_d3;
reg_d0 <= reg_d0;
reg_d1 <= reg_d1;
reg_d2 <= reg_d2;
end
end
end
//Mux for display 4 7segs LEDs
localparam N = 18;
reg [N-1:0]count;
always # (posedge clock or posedge reset)
begin
if (reset)
count <= 0;
else
count <= count + 1;
end
reg [6:0]sseg;
reg [3:0]an_temp;
reg reg_dp;
always # (*)
begin
case(count[N-1:N-2])
2'b00 :
begin
sseg = reg_d0;
an_temp = 4'b1110;
reg_dp = 1'b1;
end
2'b01:
begin
sseg = reg_d1;
an_temp = 4'b1101;
reg_dp = 1'b0;
end
2'b10:
begin
sseg = reg_d2;
an_temp = 4'b1011;
reg_dp = 1'b1;
end
2'b11:
begin
sseg = reg_d3;
an_temp = 4'b0111;
reg_dp = 1'b0;
end
endcase
end
assign an = an_temp;
//update the data to display to LEDs
reg [6:0] sseg_temp;
always # (*)
begin
case(sseg)
4'd0 : sseg_temp = 7'b1000000;
4'd1 : sseg_temp = 7'b1111001;
4'd2 : sseg_temp = 7'b0100100;
4'd3 : sseg_temp = 7'b0110000;
4'd4 : sseg_temp = 7'b0011001;
4'd5 : sseg_temp = 7'b0010010;
4'd6 : sseg_temp = 7'b0000010;
4'd7 : sseg_temp = 7'b1111000;
4'd8 : sseg_temp = 7'b0000000;
4'd9 : sseg_temp = 7'b0010000;
default : sseg_temp = 7'b0111111; //dash
endcase
end
assign seg = sseg_temp;
assign dp = reg_dp;
endmodule
I'm trying to design a stop watch, but I'm stuck at the increment thing. The intent is when I press increment(a button), the reg_d3 will increment by one and hold its state until the button is released. I'm able to make the clock stop when the button is pressed, but I can't update the reg_d3. I always receive
[Place 30-574] Poor placement for routing between an IO pin and BUFG
I don't know why; I use increment in the clkdivider just find.
I think the problem is related to this part of your code:
always # (posedge (increment))
begin
if (reg_d3 == 9)
inc_temp = 0;
else
inc_temp = reg_d3 + 1;
end
You are basically using an input signal as a clock, and that is completely discouraged when designing for a FPGA. The P&R tries to re-route an IO pin to a BUFG (global buffer) inside the FPGA so it can be used as a clock.
For FPGA design, you should use one clock signal for all your always #(posedge...) constructions, and use input signals to conditionally load/update the register.
To do that, you have first to synchronize your increment signal to your clk, so avoiding metastability issues:
reg incr1=1'b0, incr2=1'b0;
always #(posedge clk) begin
incr1 <= increment;
incr2 <= incr1;
end
wire increment_synched = incr2;
Then, deglitch increment_synched and detect a rising edge in it:
reg [15:0] incrhistory = 16'h0000;
reg incr_detected = 1'b0;
always #(posedge clk) begin
incrhistory <= { incrhistory[14:0] , increment_synched };
if (incrhistory == 16'b0011111111111111)
incr_detected <= 1'b1;
else
incr_detected <= 1'b0;
end
To detect a valid rising edge, we store a history of the last 16 values of increment_synched. When a valid steady change from 0 to 1 is produced, the history pattern will match the pattern 0011111111111111. Then, and only then, we signal it by raising incr_detected to 1. The next clock cycle, the history pattern won't match the above sequence, and incr_detected will go down to 0 again.
Prior to that, multiple bounces in the push button increment is connected to would cause many transitions, leading to many increments. Using a pattern matching like that eliminates those glitches caused by multiple bounces. With 1Khz clock as you seem to use, this pattern should be enough.
Now you can use incr_detected in your original code, incr_detected wil be 1 for just a single clk cycle.
always # (posedge clk) begin
if (incr_detected) begin
if (reg_d3 == 9)
inc_temp = 0;
else
inc_temp = reg_d3 + 1;
end
end
You can test these additions using the following simulation:
http://www.edaplayground.com/x/AQY
What you will see there is a module that takes your increment input signal from the outside, and generate a glitch-free one-cycle pulse when the input signal makes a final transition from low to high level.
Actually, I've written two versions. The second one tries to mimic the behaviour of a monostable, so the input won't be sampled for a specific period of time after the first low to high transition is detected.
You will see that the second version produces a pulse much sooner than the first version, but it's also prone to take a glitch as valid rising edge, as showed in the simulation. I'd stick with the first version then.

Resources