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
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
1 Answer 1
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.
-
\$\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\$Carlos J.– Carlos J.2020年08月26日 15:09:35 +00:00Commented 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\$Carlos J.– Carlos J.2020年08月26日 15:16:02 +00:00Commented Aug 26, 2020 at 15:16
-
\$\begingroup\$ @CarlosJ., when either
signal
orclk_1khz
has a rising edge,aux
gets the value fromcounter
. That's two different clocks controllingaux
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\$The Photon– The Photon2020年08月26日 15:19:00 +00:00Commented 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\$Carlos J.– Carlos J.2020年08月27日 12:31:40 +00:00Commented 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\$Carlos J.– Carlos J.2020年08月27日 12:56:17 +00:00Commented Aug 27, 2020 at 12:56
rst = 1; rst = 0;
That will probably just synthesize torst
being set to zero. It won't generate a pulse onrst
to trigger the RS flops. You probably want to setrst
to 1 when thesignal
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\$