1
\$\begingroup\$

I know that the code I am going a publush is terrible and pointless, just I am playing trying to go deep in verilog, deep to gate behaviour... Well, this is the pain code:

module syncRX(clk, signal, detect);
 input clk, signal;
 output wire [7:0] detect;
 
 reg rst = 0;
 reg [7:0] counter = 0;
 wire [7:0] aux;
 
 freq_div div(.clk(clk), .clk_1khz(clk_1khz));
 
 rsff rs0(.r(rst), .s(aux[0]), .q(detect[0]));
 rsff rs1(.r(rst), .s(aux[1]), .q(detect[1]));
 rsff rs2(.r(rst), .s(aux[2]), .q(detect[2]));
 rsff rs3(.r(rst), .s(aux[3]), .q(detect[3]));
 rsff rs4(.r(rst), .s(aux[4]), .q(detect[4]));
 rsff rs5(.r(rst), .s(aux[5]), .q(detect[5]));
 rsff rs6(.r(rst), .s(aux[6]), .q(detect[6]));
 rsff rs7(.r(rst), .s(aux[7]), .q(detect[7]));
 
 always @(posedge signal or posedge clk_1khz)
 if(signal == 1'b1)
 begin
 rst = 1;
 rst = 0;
 aux <= counter;
 counter <= 0;
 end
 else
 counter <= counter + 1;
 
endmodule // top
module freq_div(input clk, output reg clk_1khz);
 reg [18:0] count = 0;
 always @(posedge clk)
 begin
 if(count == 60000)
 begin
 clk_1khz <= ~clk_1khz;
 count <= 0;
 end
 else
 count <= count + 1;
 end
endmodule
module rsff(r, s, q);
 input r,s;
 output q;
 nand(~s,qbar,q);
 nand(~r,q,qbar);
endmodule

The idea is to take a "snapshot" of the counter before reset it, being this "snapshot" the output of the module (I know there is an other way to do, but I want to solve in gate level). I am using an ICE40 FPGA and it should show a 8 bit binary number in the leds representing the cycle of "signal" counted by "clk_1khz". I got an timming error. But can not find out why... Thanks.

Append: The error:

nextpnr-ice40 --hx8k --package tq144:4k --json syncRX.json --pcf syncRX.pcf --asc syncRX.asc


Info: constrained 'signal' to bel 'X0/Y25/io1'
Info: constrained 'detect[0]' to bel 'X12/Y0/io1'
Info: constrained 'detect[1]' to bel 'X12/Y0/io0'
Info: constrained 'detect[2]' to bel 'X11/Y0/io1'
Info: constrained 'detect[3]' to bel 'X8/Y0/io0'
Info: constrained 'detect[4]' to bel 'X7/Y0/io1'
Info: constrained 'detect[5]' to bel 'X6/Y0/io1'
Info: constrained 'detect[6]' to bel 'X4/Y0/io1'
Info: constrained 'detect[7]' to bel 'X4/Y0/io0'
Info: constrained 'clk' to bel 'X16/Y0/io1'
Info: Packing constants..
Info: Packing IOs..
Info: Packing LUT-FFs..
Info: 0 LCs used as LUT4 only
Info: 0 LCs used as LUT4 and DFF
Info: Packing non-LUT FFs..
Info: 0 LCs used as DFF only
Info: Packing carries..
Info: 0 LCs used as CARRY only
Info: Packing RAMs..
Info: Placing PLLs..
Info: Packing special functions..
Info: Promoting globals..
Info: Constraining chains...
Info: 0 LCs used to legalise carry chains.
Info: Checksum: 0xd7159a06
Info: Annotating ports with timing budgets for target frequency 12.00 MHz
Info: Checksum: 0x8078c586
Info: Device utilisation:
Info: ICESTORM_LC: 1/ 7680 0%
Info: ICESTORM_RAM: 0/ 32 0%
Info: SB_IO: 10/ 256 3%
Info: SB_GB: 0/ 8 0%
Info: ICESTORM_PLL: 0/ 2 0%
Info: SB_WARMBOOT: 0/ 1 0%
Info: Placed 10 cells based on constraints.
Info: Creating initial analytic placement for 0 cells, random placement wirelen = 0.
Info: at initial placer iter 0, wirelen = 0
Info: at initial placer iter 1, wirelen = 0
Info: at initial placer iter 2, wirelen = 0
Info: at initial placer iter 3, wirelen = 0
Info: Running main analytical placer.
Info: HeAP Placer Time: 0.00s
Info: of which solving equations: 0.00s
Info: of which spreading cells: 0.00s
Info: of which strict legalisation: 0.00s
Info: Running simulated annealing placer for refinement.
Info: at iteration #1: temp = 0.000000, timing cost = 0, wirelen = 0
Info: at iteration #2: temp = 0.000000, timing cost = 0, wirelen = 0
Info: SA placement time 0.00s
Warning: No clocks found in design
Info: Checksum: 0xe3e91e09
Info: Routing..
Info: Setting up routing queue.
Info: Routing 0 arcs.
Info: | (re-)routed arcs | delta | remaining
Info: IterCnt | w/ripup wo/ripup | w/r wo/r | arcs
Info: 0 | 0 0 | 0 0 | 0
Info: Routing complete.
Info: Route time 0.00s
Info: Checksum: 0x0a0c3218
Warning: No clocks found in design

Expected waveform

Pretended schematic

I can not underestand why the code with this modification works...

module syncRX(clk, signal, detect);
 input clk, signal;
 output wire [7:0] detect;
 
 reg rst = 0;
 reg [7:0] counter = 0;
 wire [7:0] aux;
 
 assign detect = counter;
 
 freq_div div(.clk(clk), .clk_1khz(clk_1khz));
 
 rsff rs0(.r(rst), .s(aux[0]), .q(detect[0]));
 rsff rs1(.r(rst), .s(aux[1]), .q(detect[1]));
 rsff rs2(.r(rst), .s(aux[2]), .q(detect[2]));
 rsff rs3(.r(rst), .s(aux[3]), .q(detect[3]));
 rsff rs4(.r(rst), .s(aux[4]), .q(detect[4]));
 rsff rs5(.r(rst), .s(aux[5]), .q(detect[5]));
 rsff rs6(.r(rst), .s(aux[6]), .q(detect[6]));
 rsff rs7(.r(rst), .s(aux[7]), .q(detect[7]));
 
 always @(posedge signal or posedge clk_1khz)
 if(signal == 1'b1)
 begin
 rst = 1;
 rst = 0;
 aux <= counter;
 counter <= 0;
 end
 else
 counter <= counter + 1;
 
endmodule // top

Thanks

asked Aug 25, 2020 at 17:06
\$\endgroup\$
6
  • 2
    \$\begingroup\$ Please include the exact text of the error message you got. \$\endgroup\$ Commented Aug 25, 2020 at 17:48
  • \$\begingroup\$ @ThePhoton sure! I add the full log in the question (is too big for a comment). Thanks! \$\endgroup\$ Commented Aug 25, 2020 at 19:32
  • \$\begingroup\$ Where is the timing error? \$\endgroup\$ Commented Aug 25, 2020 at 21:26
  • \$\begingroup\$ One thing I'll point out is that where you have rst = 1; rst = 0; That will probably just synthesize to rst being set to zero. It won't generate a pulse on rst to trigger the RS flops. You probably want to set rst to 1 when the signal goes high, and then find a way to return it to zero after some controlled delay. Exactly how to do that depends on what you're trying to achieve. \$\endgroup\$ Commented Aug 25, 2020 at 21:30
  • \$\begingroup\$ @ThePhoton I am using Icestorm tools and it seams too gentle with errors, it compile but FPGA is doing nothing, but if comment the line 25 "//aux <= counter;" and add bellow line 7 "assign detect = counter;" not only compile, the FPGA works as a counter. Then I take the "Warning: No clocks found in design" as an error (always when I get this warning everything stop working) \$\endgroup\$ Commented Aug 26, 2020 at 11:38

1 Answer 1

1
\$\begingroup\$

The problem is here:

always @(posedge signal or posedge clk_1khz)
 if(signal == 1'b1)
 begin
 rst = 1;
 rst = 0;
 aux <= counter; // Here
 counter <= 0;
 end
 else
 counter <= counter + 1;

You are using signal as a reset for the flip-flops that produce counter, which is perfectly all right.

But for aux you are trying to have two different clock inputs (signal and clk_1khz) trigger it capture the value from counter. As we discussed in your previous question, that isn't synthesizable.

You also have a problem with rst: You can't synthesize two different transitions of the signal on the same clock edge. In synthesis, the net result of rst = 1; rst = 0; will just be to set rst low. Meaning that rst will simply never go high. You should find a way to set it high when the reset (signal) occurs, and then set it low after signal goes low again.

answered Aug 26, 2020 at 14:50
\$\endgroup\$
10
  • \$\begingroup\$ Thanks a lot. Just a question "rst = 0;" is blocking. This dont mean that have to commit the action before happends the next line? because in that case should give a signal. \$\endgroup\$ Commented Aug 26, 2020 at 15:09
  • \$\begingroup\$ about aux is in two different clock, I see counter in two different clock but not aux (is not a critic, just ask because maybe you saw something I didnt), anyway they are handled inside a "IF" stament, then should be synthetizable... I guess. Thanks a lot for your hel, and for be patient with my, I still have to learn a lot about this technology \$\endgroup\$ Commented Aug 26, 2020 at 15:16
  • \$\begingroup\$ @CarlosJ., when either signal or clk_1khz has a rising edge, aux gets the value from counter. That's two different clocks controlling aux and it isn't synthesizable. You can use an if-statement to generate reset logic, but only if you assign the value from a constant (not another signal) inside the if-statement. \$\endgroup\$ Commented Aug 26, 2020 at 15:19
  • \$\begingroup\$ your answer make sense... Do you think that change the "else" to "else if(clk_1khz == 1'b1)" could solve the situation? (with this modification would never "aux" be controlled in the same time). Thanks! \$\endgroup\$ Commented Aug 27, 2020 at 12:31
  • \$\begingroup\$ No, was not good idea, is not even compiling... and also, is not making even logical diference... Anyway, I think I didnt get your point, there is two edges, but also there is an "if - else" structure, is going never a be modificate "aux" in the same time bought edges... Maybe I am missing something... \$\endgroup\$ Commented Aug 27, 2020 at 12:56

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.