Counter through Verilog - 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

Related

Counter that loops through 6 values and then resets

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

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 Error in all assignings

Verilog Error
I am trying to learn verilog . This code is made for seven segment led using counter. But I am not able to assign value to nr it gives error. I made a state machine and wish to get next number on seven segment led after each positive clock.
/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/
module LED ( nr,clk);
input clk;
output [6:0]nr; //output led seven bit number
reg [6:0]nr;
reg [2:0]state;
always #(posedge clk);
begin
state <= 3'b000; // assigning at each clock
case (state)
3'b000:
begin
nr <= 7'b0000001;
state <= 3'b001;
end
3'b001:
begin
nr <= 7'b0011111;
state <= 3'b010;
end
3'b010:
begin
nr <= 7'b0100101;
state <= 3'b011;
end
3'b011:
begin
nr <= 7'b0001100;
state <= 3'b100;
end
3'b100:
begin
nr <= 7'b1011010;
state <= 3'b101;
end
3'b101:
begin
nr <= 7'b1001000;
state <= 3'b110;
end
3'b110:
begin
nr <= 7'b1000000;
state <= 3'b111;
end
3'b111:
begin
nr <= 7'b0011101;
state <= 3'b000;
end
end
endmodule
always #(posedge clk) no semicolon!

I'm having an unavoidable Quartus Syntax error

Here is the code I have written:
reg number;
always #(posedge clk)
begin
case(SW[3:1])
000: number = 32h'A65D;
001: number = 32h'BAB9;
010: number = 32h'9430;
011: number = 32h'8BEB;
100: number = 32h'7CB8;
101: number = 32h'62F1;
110: number = 32h'6EF9;
111: number = 32h'5D5C;
default: number = 32h'0000;
endcase
end
I keep getting an error in quartus for every line saying:
"Error (10170): Verilog HDL syntax error at test.v(181) near text "h";
expecting ";""
How I can resolve this error?
You need to specify a bit width for number; it is currently 1-bit wide and you likely want 32 bits. You need to add a size and a base radix (3'b) to each of the case items:
reg [31:0] number;
always #(posedge clk)
begin
case(SW[3:1])
3'b000: number <= 32'hA65D;
3'b001: number <= 32'hBAB9;
3'b010: number <= 32'h9430;
3'b011: number <= 32'h8BEB;
3'b100: number <= 32'h7CB8;
3'b101: number <= 32'h62F1;
3'b110: number <= 32'h6EF9;
3'b111: number <= 32'h5D5C;
default: number <= 32'h0000;
endcase
end
You should use nonblocking assignments (<=) for sequential logic.
UPDATE: ...and of course after seeing Eugenio Lyatte's answer, fix the 'h syntax error, too.
You need change 32h'A65D for 32'hA65D. This will be resolve your error.
reg [31:0]number
always #(posedge clk)
begin
case(SW[3:1])
3'b000: number <= 32'hA65D;
3'b001: number <= 32'hBAB9;
3'b010: number <= 32'h9430;
3'b011: number <= 32'h8BEB;
3'b100: number <= 32'h7CB8;
3'b101: number <= 32'h62F1;
3'b110: number <= 32'h6EF9;
3'b111: number <= 32'h5D5C;
endcase

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.

Resources