1
\$\begingroup\$

I'm trying to do the seq system as the picture, I'm sure it's simple but I don't remember the "gate" of this.

picture

This clock cond will be used for sending bit in UART.

reg cond;
always @(posedge clk or negedge clk) begin
    if (enable == 1) begin
        if (clk == 1)
            cond = 1; // ############ ERROR this line
        else if (clk == 0)
            cond = 0;
    end
end

This code is working in simulation but I got an error when I'm trying to synthesize it: The logic for <cond> 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.

cond is only use for this just below the previous code:

always @(posedge cond or negedge enable) begin
***

I'm beginner at Verilog, please help me.

Thank you.

Edit:

I have every 100us data from an ADC. I want to convert to BCD and send in ASCII with UART/Serial communication.

The frequency of data and the frequency of the baudrate are different. I got some problems because for example for the second sending, it won't detect D but C, then it will send C and not D. Since it's my first verilog project/FPGA, I tried to do it as my brain is used to. Means with event, start, enable, finish signals etc... I think it's more how a uC/uP works than a FPGA. But I'm learning.

I am sure it's simple but I've been in for 2 weeks...

pictureexplanation

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

This would not give what Alexis wants.

module and_clk (
                input wire clk,
                input wire rst_n,
                input wire enable,
                output reg cond
              );

   always @(posedge clk or negedge rst_n) 
   begin
     if(~rst_n) begin
       cond <= 1'b0;
     end else begin
       cond <= enable & clk;
     end
   end

endmodule

As the FF captures a data only on posedge of clock, cond <= enable & clk will always put 1'b1 in cond(when enable is high btw).

I can see two solutions to do what you want :

  1. Add logic in the clock (which can result in serious problems in synthesis)

    module and_clk (
                input wire clk,
                input wire rst_n,
                input wire enable,
                output wire cond
              );
    
    reg enable_q;
    
    always @(posedge clk or negedge rst_n) 
    begin
     if(~rst_n) begin
       enable_q <= 1'b0;
     end else begin
       enable_q <= enable;//stores enable value in a FF
     end
    end
    
    assign cond = enable_q & clk; //it is not safe to add combinatorial cells on the clock path. It will complicate the generation of the clock tree
    endmodule
    
  2. Use a negedge triggered FF, a bit more complicated but much more safe for synthesis

    module and_clk (
                input wire clk,
                input wire rst_n,
                input wire enable,
                output wire cond
              );
    
    reg enable_q;
    
    always @(posedge clk or negedge rst_n) 
    begin
     if(~rst_n) begin
       enable_q <= 1'b0;
     end else begin
       enable_q <= enable & ~enable_qn;//stores enable value in a FF
       //set to 0 when enable_qn is high to generate the cycles you want
     end
    end
    
    always @(negedge clk or negedge rst_n) 
    begin
     if(~rst_n) begin
       enable_qn <= 1'b0;
     end else begin
       enable_qn <= enable_q;
       //will take the value of enable_q half a cycle later
     end
    end
    
    assign cond = enable_q ^ enable_qn; 
    //xoring the output will give you what you want
    
    endmodule
    

    Not a so simple question finally :)

EDIT:

Issues about adding logic on clock path:
Adding logic on clock path adds two things:

  1. Delay to the output of the logic: which can create metastability as the resulting signal will certainly change in a close window of the clock edges. (This site explains quite clearly the problem of metastability)
  2. Capacitance to the input: This results in unbalancing the clock tree i.e. ruining the work that the synthesis tool made to ensure that all FF, with the same clock, are triggered at the same time.(This ppt explains how a clock tree is generated)

This interesting pdf regroups a bunch of things that should be avoided to design reliable circuits.

Issues about adding enable in the output path:
(To understand what I will try to explain in the next lines, you have to carefully read, and understand, my first reference)

I do not know from where your enable signal comes but as your drawn it seems to be asynchronous. The issue with asynchronous signals in synchronous designs is that they can violate the setup/hold constraints of the FF and then create metastability which will results in unpredictable value of the output FF which constraints had been violated.

If you understood the article about metastability, you should have figured that even putting enable in enable_q can create metastability. To be (more) covered about that, one solution is to add a negedge triggered FF "between" enable and enable_q.

As it is a matter of probability metastability can occur everywhere. A safer version of you design would be:

    module and_clk (
                input wire clk,
                input wire rst_n,
                input wire enable,
                output wire cond
              );

    reg enable_q, enable_meta;

    //This FF store on negedge the value of enable
    always @(negedge clk or negedge rst_n) 
    begin
     if(~rst_n) begin
       enable_meta <= 1'b0;
     end else begin
       enable_meta <= enable;//stores enable value in a FF
     end
    end

    //By doubling this FF the risk of metastability is greatly reduced
    always @(posedge clk or negedge rst_n) 
    begin
     if(~rst_n) begin
       enable_q <= 1'b0;
     end else begin
       enable_q <= enable_meta & ~enable_qn;//stores enable value in a FF
       //set to 0 when enable_qn is high to generate the cycles you want
     end
    end

    always @(negedge clk or negedge rst_n) 
    begin
     if(~rst_n) begin
       enable_qn <= 1'b0;
     end else begin
       enable_qn <= enable_q;
       //will take the value of enable_q half a cycle later
     end
    end

    assign cond = (enable_q ^ enable_qn) & enable_meta; 
    //adding "& enable_meta" can replace "enable"
    //This should be safe as the result of the xor will have a very low probability of metastability
    endmodule

This solution will be safer, but also bigger and quite more complicated. There also will be configurations of event that will lead an extra cycle on cond or a 1 clock cycle delay depending on the rise/fall arrival of enable.

Hope this helps.

\$\endgroup\$
5
  • \$\begingroup\$ I used the second one, by adding an AND gate withenable : assign cond = (enable_q ^ enable_qn) & enable; it's exactly what I want ! Is this can result in an error for synthesize ? Could you tell me more about the clock in a combinatorial cell ? \$\endgroup\$
    – Alexis
    Mar 17, 2016 at 10:37
  • \$\begingroup\$ I thought about adding enable in the cond, it can however cause problems as apparently enable is not synchronous. If enable falls when cond is high then cond will fall too. This can create problems about hold constraints and then metastability issues. I will edit my answer and put some references. It will be easier than in comments. \$\endgroup\$
    – Krouitch
    Mar 17, 2016 at 10:43
  • \$\begingroup\$ Indeed, enable is not synchronous (enable is made with finish signals). I don't have much time to do in a problem free way. I need something which is working quickly. But I'm sure I could make the enable signal synchronous later. Anyway, thank you very much, you really helped me ! \$\endgroup\$
    – Alexis
    Mar 17, 2016 at 10:50
  • \$\begingroup\$ @Alexis_FR_JP If it is really asynchronous, it could be interesting to use double the enable FF to avoid metastability (c.f. my edit). It is my pleasure to help curious people :) \$\endgroup\$
    – Krouitch
    Mar 17, 2016 at 11:40
  • \$\begingroup\$ A lot of reading ! That's good and interesting ! Indeed, I'm trying to send data (115 200 bps) from data (10KS/s). Thank you again. I'll post a new question if I have some. I edited my question in order to show you what I'm doing. \$\endgroup\$
    – Alexis
    Mar 17, 2016 at 12:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.