How do I drive a signal from 2 sources in system verilog - verilog

I'm trying to write a RTL model in which I monitor independent clock sources. These clock sources can have variable frequency (range 5 to 50MHz)
Let us say clk1 and clk2. I'm trying to drive a signal 'toggle' which is set '1' at every posedge of clk1 and is set to '0' at every negedge of clk2. I'm having trouble realizing this model.
I tried using 1 flop triggered at the positive edge of clk1 with inputs of this flop tied to 'high' and another flip flop triggered at the negative edge of clk2 with input tied to 'low'. I sent these outputs to a mux, but I have trouble figuring out how to drive the select signal of this mux
Here is my code snippet :
always_ff #(posedge clk1 or rstb) begin
if(!rstb) begin
flop1_out <= 0;
end else begin
flop1_out <= 1;
end
end
always_ff #(negedge clk2) begin
flop2_out <= 0;
end
assign toggle = sel ? flop1 : flop2;
So, as of now nothing is driving sel and trying to figure this out is where I'm having trouble
If I try to drive the same signal (toggle) from 2 different clock sources, I get an error saying that multiple drivers found for signal toggle, which makes sense.
Please let me know if you have any suggestions
EDIT: fixed a typo and removed rstb from the sensitivity list for flop2

assign rstn = clk2;
always # (posedge clk1 or negedge rstn)
if (~rstn)
toggle = 1'b0;
else
toggle <= 1'b1;
note: depending on the clock frequency and insertion delay relationships this circuit may become metastable. if you can tolerate delay, add a synchronizer on the output. better yet, if you can tolerate distortion, add a reset synchronizer on clk2 to clk1mx, where clk1mx is synchronous to clock1 but x times faster.

Related

two clock ring counter with verilog

I'm trying to write a roll shift/ ring counter that takes two switches as the clocks in verilog.
My code is as follows:
module roll(CLK1, CLK2, LEDS);
input CLK1;
input CLK2;
output [3:0] LEDS;
reg [3:0] LEDS;
initial
begin
LEDS = 4'b0001;
end
always#(posedge CLK1 or posedge CLK2)
begin
if(CLK1)
begin
LEDS[3]<=LEDS[2];
LEDS[2]<=LEDS[1];
LEDS[1]<=LEDS[0];
LEDS[0]<=LEDS[3];
end
// Roll Right
if(CLK2)
begin
LEDS[3]<=LEDS[0];
LEDS[2]<=LEDS[3];
LEDS[1]<=LEDS[2];
LEDS[0]<=LEDS[1];
end
end
endmodule
I tried using two always blocks, but then figured out that I cannot do that. and when I have the posedge CLK2 in the always statement, the leds on my FPGA all stay on.
Remember Verilog is not a programming language it is a hardware description language.
And when coding for synthesis, you will only be successful if you write code that can be instantiated with actual gates. So writing an always block with sensitivity to edges of two different signals can't be synthesized unless the response to one of the two signals has the effect of a RESET or PRESET operation.
Your code also logically doesn't do what it seems you want to. Consider what your code says will happen if there is a rising edge on CLK2 when CLK1 is already high (or vice versa). Your lights will roll left and then immediately roll right gain, resulting in no change.
A more usual approach would be to have a clock running much faster than the UP and DOWN inputs are expected to change, and use that to drive the logic. For example
module roller(input clk, input rst, input UP, input DOWN, output reg LEDS[3:0]);
reg UP1, DOWN1;
always #(posedge clk or posedge rst)
if (rst) begin
LEDS[3:0] <= 4'b0001;
end
else
begin
UP1 <= UP;
DOWN1 <= DOWN;
if (UP & ~UP1) begin
LEDS[3:0] <= {LEDS[2:0], LEDS[3]};
end
else if (DOWN & ~DOWN1) begin
LEDS[3:0] <= {LEDS[0], LEDS[3:1]};
end
end
endmodule;
Notice that this gives priority to UP. If both UP and DOWN are asserted, the pattern will roll "up" rather than down. If you want a different behavior, you'd have to modify the code to achieve it.

Synthesizing a counter with an asynchronous edge-triggered reset

I want to synthesize a clock counter with an asynchronous edge-triggered reset: the counter increments on every clk rising edge, and resets to 0 on the rising edge of a rst signal.
The counter reset to 0 must be edge-triggered since the rst signal may stay high indefinitely.
Here's what I have:
module clk_counter(input clk, input rst, output reg [7:0] count);
always # (posedge rst) begin
count <= 0;
end
always # (posedge clk) begin
if(count < 255) begin
count <= count + 1;
end
end
endmodule
I'm having trouble synthesizing the implementation since count is "connected to multiple drivers" according to the error message my synthesizer spits out. I suspect this is due to a race condition in the design: the value of count is uncertain if both rst and clk rise at the same time.
I believe the race condition can be solved if there is a way to prioritize the edge-triggered reset operation to occur before the typical counter increments.
Is there a way to prioritize between two edge-triggered operations?
The "Connected to multiple drivers" error is not a race condition - values cannot be assigned to the same net in multiple always blocks. Additionally, remember that HDL is not executed sequentially - placing an assignment earlier in a file won't give it any higher priority.
Instead, you'll need multiple sensitivities for your always block. Try this:
reg rst_prev;
always #(posedge clk)
rst_prev <= rst;
always #(posedge clk or posedge rst)
begin
if (rst)
begin
if (!rst_prev)
count <= 0;
end
else begin
if (count < 255)
count <= count + 1;
end
end
The main difference between this and the solution proposed by others is that as desired, it will only trigger on the edge of rst, since rst_prev will be 0, and rst will contain 1. However, this design is more sensitive to timing constraints (and more likely to have setup/hold violations) than the simpler designs.

IF with ternary operator - Verilog

I am trying to write a program in Verilog that should "move" a light LED on an array of LEDs. With a button the light should move to the left, with another one it should move to the right. This is my code:
module led_shift(UP, DOWN, RES, CLK, LED);
input UP, DOWN, RES, CLK;
output reg [7:0] LED;
reg [7:0] STATE;
always#(negedge DOWN or negedge UP or negedge RES)
begin
if(!RES)
begin
STATE <= 8'b00010000;
end
else
begin
STATE <= UP ? STATE>>1 : STATE<<1;
end
end
always # (posedge CLK)
begin
LED <= STATE;
end
endmodule
The problem is in STATE <= UP ? STATE>>1 : STATE<<1; and the error the following:
Error (10200): Verilog HDL Conditional Statement error at led_shift.v(34): cannot match operand(s) in the condition to the corresponding edges in the enclosing event control of the always construct
I tried to modify the code without using that kind of if:
always#(negedge DOWN or negedge UP or negedge RES)
begin
if(!RES)
STATE <= 8'b00010000;
else
begin
if(!DOWN)
STATE <= STATE<<1;
else
begin
if(!UP)
STATE <= STATE>>1;
else
STATE <= STATE;
end
end
end
It compiles, but does not work: the LED "moves" only to the left, when I press the other button all LEDs shut down. Probably there is a problem in my code, but I cannot understand why my first code does not compile at all.
Thank you for any help!
harrym
It is not clear for the synthesizer to know how to control STATE with the 3 asynchronous control signals.
Most likely your your synthesizer is trying to map STATE to a D flip flop with asynchronous active low set and reset. For example it might be trying to synthesize to something like:
dff state_0_(.Q(STATE[0], .CLK(DOWN), .SET_N(UP), .RST_N(RES(, .D(/*...*/));
In a real flop with asynchronous set and reset, the default should be consent and would explain the error in your first code. In your second attempt, UP becomes part of the combination logic cloud along with DOWN. DOWN is also being used as a clock. Since UP is not a clock, shifting continuously happens while UP is low, completely shifting the on bit out instantly. Another error for the second case would actually be more appropriate.
For the synthesizer to do a better job, you first need to synchronize your asynchronous control signals. Use the same technique as CDC (clock domain crossing; A paper by Cliff Cummings goes into detains here). A basic example:
always #(posedge clk) begin
pre_sync_DOWN <= DOWN;
sync_DOWN <= pre_sync_DOWN;
end
Now that the controls signals are synchronized, make STATE the output of your combination logic. Example:
always #* begin
if(!sync_RES)
STATE = 8'b00010000;
else
case({sync_UP,sync_DOWN})
2'b01 : STATE = LED>>1;
2'b10 : STATE = LED<<1;
default: STATE = LED;
endcase
end
With everything running on one clock domain and explicitly defined combination logic, the synthesizer can construct equivalent logic using flops and basic gates.
FYI:
To shift only on a negedge event you need to keep the last sync value and check for the high to low transition. Remember to swap sync_ with do_ in the combination logic that drives STATE.
always #(posedge clk)
keep_DOWN <= sync_DOWN;
always #*
do_DOWN = (keep_DOWN && !sync_DOWN);

verilog always #(posedge) failing in uart

I'm learning verilog and I think there is something that I must not understand about always #* and always (#posedge clk, ...)
Here is a piece of code supposed to send bits via uart. It fails at synthesization.
The error is
" The logic for does not match a known FF or Latch template. The description style you are using to describe a register or latch is not supported in the current software release."
(and 3 other errors for , and )
If I change the always #(...) by always #*, things fail in the next step ("implement design") because things are not connected.
In the book that I have, they implement an fsmd with an always (posedge clk) for the state, and always #* for the other logic, but I don't understand why this doesn't work.
On another forum, I read that the error could come from too complicated conditions. But I have simplified things too (not code the code here but basically I removed the case(state) and the ifs to have single line assignments with ? : or binary conditions, but it didn't work either)
I have seen this error before in other pieces of code that I wrote but I didn't get to the bottom of it, so if you could help me understand the general problem (with this uart thing as a support for a concrete example), I would be very happy.
Thanks
Thomas
P.S : Im using xilinx spartan 3e starter kit and xilinx ise 14.4
module UART_out #(parameter [3:0] NUM_BITS = 8)
(
input wire baud_clk,
input wire send_tick,
input wire[NUM_BITS-1:0] data_in,
output wire tx,
output wire debug_done
);
localparam
IDLE = 0,
TRANSMIT = 1;
reg[NUM_BITS:0] bits_to_send;
reg state;
reg out_bit;
reg[4:0] cnt;
always #(posedge baud_clk, posedge send_tick)
begin
case (state)
IDLE:
if (send_tick)
begin
bits_to_send <= {data_in, 0};
state <= TRANSMIT;
cnt <= 0;
end
TRANSMIT:
begin
if (cnt < NUM_BITS)
cnt <= cnt + 1;
else
state <= IDLE;
bits_to_send <= {1, bits_to_send[NUM_BITS:1]};
out_bit <= bits_to_send[0];
end
endcase
end
assign tx = (state == IDLE ? 1 : out_bit);
assign debug_done = (state == IDLE);
endmodule
The error:
The logic for does not match a known FF or Latch template. The description style you are using to describe a register or latch is not supported in the current software release.
Is referring to the fact that the synthesis tool does not have any hardware cells to use which match your description.
What hardware do you want from :
always #(posedge baud_clk, posedge send_tick)
This looks like you want a flip-flop with an enable signal. The enable signal (send_tick) should be 1 clock period wide. This is then used to select the path of logic on a clock edge. not as an alternative trigger.
I think that this is all you really need:
always #(posedge baud_clk) begin
case (state)
IDLE:
if (send_tick) begin
//...
end
//...
endcase
end
If send_tick is from another clock domain then you will need to do some clock domain crossing to turn it it to a clock wide pulse on the baud_clk.
You may be getting confused with blocks which have multiple triggers, they are normally a clk and reset. A negedge reset_n or posedge reset are often added for reset (initialisation) conditions.
If adding a reset :
always #(posedge baud_clk or negedge reset_n) begin
if (~reset_n) begin
//reset conditions
state <= IDLE;
//...
end
else begin
// Standard logic
end
end
You will notice that there is a very definite structure here, if reset else ... The synthesis tools recognise this as a flip-flop with an asynchronous reset. The data in the reset condition is also static, typically setting everything to zero.

Why use this 2 DFF method every time a button press is involved?

I have been reading verilog code online and have noticed this in many of the code examples. Whenever an input is needed from a hardware source such as a button press, the input is copied to a flip flop and then AND'd with the invert of the input. I dont know if this made much sense but in code here it is:
input btn;
reg dff1, dff2;
wire db_tick;
always # (posedge clock) dff1 <= btn;
always # (posedge clock) dff2 <= dff1;
assign db_tick = ~dff1 & dff2;
And then db_tick is used as the button press.
In some cases this is also used as a rising edge detector, but cant a rising edge detector easily be implemented with always#(posedge signal)
It's called a monostable multivibrator or, specifically for digital circuits, a one-shot. The purpose of the circuit is to change an edge into a single cycle pulse.
When connected directly to a physical switch it can be a way to effect switch debouncing, but that's not really a good use for it. It's hard to say what the intent is in the code without more context.
This is providing edge detection synchronous to your clock domain. I do not see any debouncing happing here, it is quite common to also include 2 meta stability flip flops before the edge detection.
input a;
reg [2:0] a_meta;
always #(posedge clk or negedge rst_n) begin
if (~rst_n) begin
a_meta <= 3'b0 ;
end
else begin
a_meta <= {a_meta[1:0], a};
end
end
// The following signals will be 1 clk wide, Clock must be faster than event rate.
// a[2] is the oldest data,
// if new data (a[1]) is high and old data low we have just seen a rising edge.
wire a_sync_posedge = ~a_meta[2] & a_meta[1];
wire a_sync_negedge = a_meta[2] & ~a_meta[1];
wire a_sync_anyedge = a_meta[2] ^ a_meta[1]; //XOR

Resources