Search code examples
verilogsystem-verilogregister-transfer-levelvlsidigital-design

How do I drive a signal from 2 sources in system 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


Solution

  • 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.