I want to build a Verilog module so that the user can select the sensitivity of some input clock signal by a module parameter. As an example, I wrote the following counter which can either count up on posedge or negedge selected by parameter clockEdge.
module Counter (clk, reset, value);
parameter clockEdge = 1; // react to rising edge by default
input clk;
input reset;
output reg [7:0] value;
generate
if(clockEdge == 1) begin
always #(posedge clk or posedge reset) begin
if (reset) begin
value <= 0;
end else begin
value <= value + 1;
end
end
end else begin
always #(negedge clk or posedge reset) begin
if (reset) begin
value <= 0;
end else begin
value <= value + 1;
end
end
end
endgenerate
endmodule
This principle is working, however I don't like that the implementation is basically copy and paste for both variants. What would be a shorter version without duplication?
Simplest is to invert the clock with an exor gate. Then use that clock in an always section:
wire user_clock;
assign user_clock = clk ^ falling_edge;
always #(posedge user_clock) // or posedge/negedge reset/_n etc.
test_signal <= ~ test_signal;
If falling_edge is 0 then user_clock and clk have the same polarity and the data is clocked at nearly the same time as you have a rising edge of clk.
If falling_edge is 1 then user_clock and clk have the opposite polarity and the data is clocked nearly the same time as the falling edge of clk.
Be careful when you change the polarity of falling_edge as it can generate runt clock pulses! Safest is to use a gated clock: stop the clock, switch polarity, then start it again.
In both cases user_clock will lag the system clk by small amount. The amount depends on the delay of the exor-gate.
Here is a simulation+:
+test_signal was set to zero in an initial statement.
I think that cut-n-paste in this tiny example is ok, though verilog has some instruments to make it easier for more complicated cases, namely functions and macros. You can use them as well, i.e.
function newValue(input reset, input reg[7:0] oldValue);
if (reset) begin
newValue = 0;
end else begin
newValue = value + 1;
end
endfunction
generate
if(clockEdge == 1) begin
always #(posedge clk or posedge reset) begin
value <= newValue(reset, value);
end
end else begin
always #(negedge clk or posedge reset) begin
value <= newValue(reset, value);
end
end
endgenerate
the other possibility is to use macros with or without paramenters. Methodology-wise macros are usually worse than functions, though here is an extreme example, though in my opinion it makes the code less readable and could have issues with debugging tools.
`define NEW_VALUE(clk_edge) \
always #(clk_edge clk or posedge reset) begin\
if (reset) begin\
value <= 0;\
end else begin\
value <= value + 1;\
end\
end
generate
if(clockEdge == 1) begin
`NEW_VALUE(posedge)
end else begin
`NEW_VALUE(negedge)
end
endgenerate
Implementing custom clock reg that follows posedge or negedge of clk might be one way to do it. This seems to work well on my machine :)
reg myclk;
always#(clk) begin
if(clk) begin
myclk = clockEdge? 1 : 0; #1 myclk = 0;
end else begin
myclk = clockEdge? 0 : 1; #1 myclk = 0;
end
end
always#(posedge myclk or posedge reset) begin
if(reset)
cnt <= 0;
else
cnt <= cnt+1;
end
Related
Is following code deterministic? i.e Can it trigger error1 or error2? Is there a recommended way for generating clk2 (same as clk3)
module Test();
reg clk1;
reg clk2;
reg clk3;
reg reset;
initial
begin
clk1 <= 0;
forever
begin
#100;
clk1 <= ~clk1; // 2x freq of clk2/clk3
end
end
always #(posedge clk1)
begin
if(reset) clk2 <= 0;
else clk2 <= ~clk2;
end
initial
begin
clk3 <= 0;
#300;
forever
begin
#200;
clk3 <= ~clk3;
end
end
initial
begin
reset <= 1;
#500;
reset <= 0;
#100;
repeat (20) #(posedge clk1);
$display("Test end");
$finish;
end
always #(posedge clk2)
begin
if(clk1 == 0) $display("Error1");
end
always #(posedge clk3)
begin
if(clk1 == 0) $display("Error2");
end
endmodule;
Your code has problems, but nothing to do with determinism—it is fully deterministic. This is one case where using NBAs <= creates a problem. clk2 gets updated in a delta cycle after clk1 and clk3. That means if you have clock domain crossings from the latter to clk2 like
always_ff #(posedge clk3)
A <= B;
always_ff #(posedge clk2)
C <= A; // A has already been updated with the value of B
So never use NBAs to make assignments to clocks.
I am asked to design simple clock divider circuit for different types of inputs.
I have a enabler [1:0] input and an input clock, and an output named clk_enable.
If enabler=01 then my input clock should be enabled once in 2 clock signals.If enabler=10 then my input should be divided by 4 etc.
I managed to divide my input clock for different cases with using case keyword but for enabler=00 my input clock should be equal to my output clk_enable which i could not manage to do it.
Here is what i tried. I am asking a help for the enabler=00 situation.
module project(input [1:0] enabler,
input clock,
output reg clk_enable);
reg [3:0] count,c;
initial begin
count=4'b0000;
c=4'b0000;
end
always #( posedge clock)
case(enabler)
2'b00:clk_enable<=clock;
2'b01:clk_enable<=~clk_enable;
2'b10:begin
if (count >= 4'b0100-1)
count<=4'b0000;
else begin
count<=count + 4'b0001;
clk_enable<=(count<(4'b0100 / 2));
end
end
2'b11: begin
if (count >= 4'b1000-1)
count<=4'b0000;
else begin
count<=count + 4'b0001;
clk_enable<=(count<(4'b1000 / 2));
end
end
endcase
endmodule
This will generate gated pulsed clock with posedge rate matching the div_ratio input.
div_ratio output
0 div1 clock (clk as it is)
1 div2 (pulse every 2 pulses of clk)
2 div3
3 div4
This is usually preferable when sampling at negedge of divided clock is not needed
If you need 50% duty cycle I can give you another snippet
module clk_div_gated (
input [1:0] div_ratio,
input clk,
input rst_n, // async reset - a must for clock divider
output clk_div
);
reg [1:0] cnt;
reg clk_en;
always #(posedge clk or negedge rst_n)
if (~rst_n)
cnt <= 2'h0;
else
cnt <= (cnt == div_ratio)? 2'h0 : cnt + 1'b1;
// clk_en toggled at negedge to prevent glitches on output clock
// This is ok for FPGA, synthesizeable ASIC design must use latch + AND method
always #(negedge clk)
clk_en <= (cnt == div_ratio);
assign clk_div <= clk & clk_en;
endmodule
This looks like you have a strong background in software development? :)
My suggestion is that you always make a clean cut between combinational and sequential logic. This includes some thoughts on what part of the design actually has to be sequential and what can be combinational.
For your case, the clock division clearly has to be sequential, since you want to invert the generated CLK signal (frequency f/2, case 0'b01) at each positive edge of the incoming CLK signal (frequency f, case 0'b00). Same is valid for f/4 (case 0'b10).
This part needs to be sequential, since you want to invert the previous CLK state...this would cause a cmobinational loop if realized in combinational logic. So triggering on a CLK edge is really necessary here.
However, the actual selection of the correct CLK output signal can be combinational. You just want to assign the correct CLK signal to the output CLK.
An implementation of the sequential part could look like:
// frequency division from input CLK --> frequency: f/2
always #(posedge clk or negedge rst_neg) begin
if (rst_neg = 1'b0) begin
clk_2 <= 1'b0;
end else begin
clk_2 <= ~clk_2;
end
end
// frequency division from first divided CLK --> frequency: f/4
always #(posedge clk_2 or negedge rst_neg) begin
if (rst_neg = 1'b0) begin
clk_ 4 <= 1'b0;
end else begin
clk_4 <= ~clk_4;
end
end
// frequency division from first divided CLK --> frequency: f/8
always #(posedge clk_4 or negedge rst_neg) begin
if (rst_neg = 1'b0) begin
clk_ 8 <= 1'b0;
end else begin
clk_8 <= ~clk_8;
end
end
So this plain sequential logic takes care of generating the divided CLK signals of f/2 and f/4 that you need. I also included reset signals on negative edge, which you usually need. And you spare the counter logic (increments and comparison).
Now we take care of the correct selection with plain combinational logic:
always #(*) begin
case(enabler)
2'b00: clk_enable = clk;
2'b01: clk_enable = clk_2;
2'b10: clk_enable = clk_4;
2'b11: clk_enable = clk_8;
endcase
end
This is quite close to your hardware description (clk_enable needs to be a reg here).
However, another way for the combinational part would be the following (declare clk_enable as wire):
assign clk_enable = (enabler == 2'b00) ? clk
: (enabler == 2'b01) ? clk_2
: (enabler == 2'b10) ? clk_4
: (enabler == 2'b11) ? clk_8;
How to create a simple one stage pipeline in Verilog?
The easiest way to create a single state pipeline is create two always block synchronized with piped input(in_pipe) as given below. This work because of how the events are queued in the simulator time cycle.
module pipeline (reset,in,clock,out)
input reset, input, clock;
output out;`
logic reset, input, clock;
reg out, in_pipe;
always #(posedge clock or negedge reset)
begin
if(reset)
begin
in_pipe <= 0;
end
else
begin
in_pipe <= in;
end
end
always #(posedge clock or negedge reset)
begin
if(reset)
begin
out<= 0;
end
else
begin
out<= in_pipe;
end
end
module pipeline#(
parameter PIPE_NUM = 2,
parameter DATA_WIDTH = 32
)(
input clock,
input [DATA_WIDTH-1:0]data_in,
output [DATA_WIDTH-1:0]data_out
);
//synthesis translate_off
initial begin
if(PIPE_NUM < 1) begin
$fatal("Error: PIPE_NUM must be greater than 0!");
end
end
//synthesis translate_on
reg [DATA_WIDTH-1:0]pipeline_reg[PIPE_NUM-1:0]/*synthesis preserve*/;
assign data_out = pipeline_reg[PIPE_NUM-1];
integer p;
always #(posedge clock)begin
pipeline_reg[0] <= data_in;
for(p = 1;p < PIPE_NUM;p = p+1)begin
pipeline_reg[p] <= pipeline_reg[p-1];
end
end
endmodule
I wrote a behavioral program for booth multiplier(radix 2) using state machine concept. I am getting the the results properly during the program simulation using modelsim, but when I port it to fpga (spartan 3) the results are not as expected.
Where have I gone wrong?
module booth_using_statemachine(Mul_A,Mul_B,Mul_Result,clk,reset);
input Mul_A,Mul_B,clk,reset;
output Mul_Result;
wire [7:0] Mul_A,Mul_B;
reg [7:0] Mul_Result;
reg [15:0] R_B;
reg [7:0] R_A;
reg prev;
reg [1:0] state;
reg [3:0] count;
parameter start=1 ,add=2 ,shift=3;
always #(state)
begin
case(state)
start:
begin
R_A <= Mul_A;
R_B <= {8'b00000000,Mul_B};
prev <= 1'b0;
count <= 3'b000;
Mul_Result <= R_B[7:0];
end
add:
begin
case({R_B[0],prev})
2'b00:
begin
prev <= 1'b0;
end
2'b01:
begin
R_B[15:8] <= R_B[15:8] + R_A;
prev <= 1'b0;
end
2'b10:
begin
R_B[15:8] <= R_B[15:8] - R_A;
prev <= 1'b1;
end
2'b11:
begin
prev <=1'b1;
end
endcase
end
shift:
begin
R_B <= {R_B[15],R_B[15:1]};
count <= count + 1;
end
endcase
end
always #(posedge clk or posedge reset)
begin
if(reset==1)
state <= start;
else
begin
case(state)
start:
state <= add;
add:
state <= shift;
shift:
begin
if(count>7)
state <= start;
else
state <=add;
end
endcase
end
end
endmodule
You have an incomplete sensitivity list in your combinational always block. Change:
always #(state)
to:
always #*
This may be synthesizing latches.
Use blocking assignments in your combinational always block. Change <= to =.
Good synthesis and linting tools should warn you about these constructs.
Follow the following checklist if something does work in the simulation but not in reality:
Did you have initialized every register? (yes)
Do you use 2 registers for one working variable that you transfer after each clock (no)
(use for state 2 signals/wires, for example state and state_next and transfer after each clock state_next to state)
A Example for the second point is here, you need the next stage logic, the current state logic and the output logic.
For more informations about how to proper code a FSM for an FPGA see here (go to HDL Coding Techniques -> Basic HDL Coding Techniques)
You've got various problems here.
Your sensitivity list for the first always block is incomplete. You're only looking at state, but there's numerous other signals which need to be in there. If your tools support it, use always #*, which automatically generates the sensitivity list. Change this and your code will start to simulate like it's running on the FPGA.
This is hiding the other problems with the code because it's causing signals to update at the wrong time. You've managed to get your code to work in the simulator, but it's based on a lie. The lie is that R_A, R_B, prev, count & Mul_Result are only dependent on changes in state, but there's more signals which are inputs to that logic.
You've fallen into the trap that the Verilog keyword reg creates registers. It doesn't. I know it's silly, but that's the way it is. What reg means is that it's a variable that can be assigned to from a procedural block. wires can't be assigned to inside a procedural block.
A register is created when you assign something within a clocked procedural block (see footnote), like your state variable. R_A, R_B, prev and count all appear to be holding values across cycles, so need to be registers. I'd change the code like this:
First I'd create a set of next_* variables. These will contain the value we want in each register next clock.
reg [15:0] next_R_B;
reg [7:0] next_R_A;
reg next_prev;
reg [3:0] next_count;
Then I'd change the clocked process to use these:
always #(posedge clk or posedge reset) begin
if(reset==1) begin
state <= start;
R_A <= '0;
R_B <= '0;
prev <= '0;
count <= '0;
end else begin
R_A <= next_R_A;
R_B <= next_R_B;
prev <= next_prev;
count <= next_count;
case (state)
.....
Then finally change the first process to assign to the next_* variables:
always #* begin
next_R_A <= R_A;
next_R_B <= R_B;
next_prev <= prev;
next_count <= count;
case(state)
start: begin
next_R_A <= Mul_A;
next_R_B <= {8'b00000000,Mul_B};
next_prev <= 1'b0;
next_count <= 3'b000;
Mul_Result <= R_B[7:0];
end
add: begin
case({R_B[0],prev})
2'b00: begin
next_prev <= 1'b0;
end
.....
Note:
All registers now have a reset
The next_ value for any register defaults to it's previous value.
next_ values are never read, except for the clocked process
non-next_ values are never written, except in the clocked process.
I also suspect you want Mul_Result to be a wire and have it assign Mul_Result = R_B[7:0]; rather than it being another register that's only updated in the start state, but I'm not sure what you're going for there.
A register is normally a reg, but a reg doesn't have to be a register.
This is my code to control a RC Servo Motor. The code basically turns the 50MHz frequency to 1KHz.
I am using one of the switches on the FPGA to control the motor. Until the switch is on, none of the program should run.
But that doesn't seem to be happening. I don't know what I'm doing wrong. It's probably a very silly mistake.
module servo(clk,rst,clk_out,switch);
input clk,rst,switch;
output reg clk_out;
reg [15:0] counter;
always #(posedge clk or posedge rst or posedge switch)
if (switch) begin
if(rst) begin
counter <=16'd0;
clk_out <= 1'b0;
end
else if(counter==16'd25000) begin
counter <=16'd0;
clk_out <= ~clk_out;
end
else begin
counter<=counter+1;
end
end
endmodule
Also I tried changing the duty cycle so the motor rotates faster, but this doesn't seem to be working.
module servo (clk,rst,clk_out,switch);
input clk,rst,switch;
output reg clk_out;
reg [15:0] counter;
always #(posedge clk or posedge rst)
if(rst)
begin
counter<=16'd0;
clk_out <= 1'b0;
end
else if (switch)
begin
if(counter==16'd12500)
begin
clk_out <= 1'b1;
counter<=counter+1;
end
else
if(counter==16'd50000)
begin
counter <= 16'd0;
clk_out <= 1'b0;
end
else
begin
counter<=counter+1;
end
end
endmodule
Here's my cut at it - I haven't simulated it, so beware!
module servo(clk,rst,clk_out,switch);
input clk,rst,switch;
output reg clk_out;
reg [15:0] counter;
// clocked blocks should only have the clock and maybe a reset
// in the sensitivity list
always #(posedge clk or posedge rst) begin
if(rst) begin
counter <=16'd0;
clk_out <= 1'b0;
end
else if (switch) begin // 'switch' used as an enable
if(counter==16'd25000) begin
counter <=16'd0;
clk_out <= ~clk_out;
end
else begin
counter<=counter+1;
end
end
else begin
counter <= 16'd0;
end
end
endmodule
First thing I did was to remove the entry for switch in the sensitivity list - for synchronous logic, there should only be a clock and maybe a reset here.
The reset clause for the logic should be first, so I moved the test for switch using it as an enable signal in the main body of the always block. The counter will only run now if switch is high.