Look in the Message folder (tab) on the Console pane after running Synthesis. It is unlikely that your code isn't generating a bunch of warnings.
Under RTL Analysis, Open Elaborated Design, open the Schematic and see what logic has been generated. This will require successful synthesis.
Sampling and signal change do not occur simultaneously on the clock edge. The signal is sampled no closer than tsetup before the clock and the output is stable no sooner than thold after the clock. That's why asynchronous logic is so hard to create. All of the potential transitions have to be covered in the Karnaugh Map and these small undefined regions generate glitches. We get around this problem by designing synchronous logic.
https://www.nandland.com/articles/setup-and-hold-time-in-an-fpga.html
ERROR: [VRFC 10-3180] cannot find port 'SD_OBUF' on this module [C:/Users/Documents/RA_3_9600/RA_3_9600.sim/sim_1/synth/func/xsim/ra3_9600_tb_func_synth.v:1344]
ERROR: [VRFC 10-3180] cannot find port 'Q' on this module [C:/Users/Documents/RA_3_9600/RA_3_9600.sim/sim_1/synth/func/xsim/ra3_9600_tb_func_synth.v:1343]
ERROR: [VRFC 10-3180] cannot find port 'DB_IBUF' on this module [C:/Users/Documents/RA_3_9600/RA_3_9600.sim/sim_1/synth/func/xsim/ra3_9600_tb_func_synth.v:1342]
ERROR: [VRFC 10-3180] cannot find port 'CLK' on this module [C:/Users/Documents/RA_3_9600/RA_3_9600.sim/sim_1/synth/func/xsim/ra3_9600_tb_func_synth.v:1341]
ERROR: [VRFC 10-3180] cannot find port 'BUSAK_IBUF' on this module [C:/Users/Documents/RA_3_9600/RA_3_9600.sim/sim_1/synth/func/xsim/ra3_9600_tb_func_synth.v:1340]
ERROR: [XSIM 43-3322] Static elaboration of top level Verilog design unit(s) in library work failed.
CPUBUSDECODER decoder
(.BUSAK_IBUF(BUSAK_IBUF),
.CLK(intak),
.DB_IBUF(DB_IBUF[13:0]),
.Q(\RING_reg[19] ),
.SD_OBUF(SD_OBUF));
module CPUBUSDECODER
(SD_OBUF,
DB_IBUF,
Q,
CLK,
BUSAK_IBUF);
output [13:0]SD_OBUF;
input [13:0]DB_IBUF;
input [13:0]Q;
input CLK;
input BUSAK_IBUF;
wire BUSAK_IBUF;
wire CLK;
wire [13:0]DB_IBUF;
wire [13:0]Q;
wire [13:0]SD_OBUF;
wire mode;
wire mode_i_2_n_0;
Well, I haven't fixed anything and it's still going wrong. Is there a way to force a complete re-synthesis from nothing?
Follow this with Generate Bitstream to get all the errors and warnings.
You do have a Constraints file to define the pinout of your project, right?
Secondly, I now see in one module that it warns of a non-clock source driving clock inputs. The non-clock source is, of course, SR3. It is definitely a trigger for the case of advancing an address counter, but it's also an asynchronous level trigger for the purpose of making SD an output, and an asynchronous clear for another counter. It is NOT a clock. If I specify it as one, then the timing constraints cry about cross-domain interaction. It seems that Vivado hates asynchronous triggers. Are there any tricks for telling it that you definitely want an input to be asynchronous and you'll take your lumps from any race conditions?
Secondly, I now see in one module that it warns of a non-clock source driving clock inputs. The non-clock source is, of course, SR3. It is definitely a trigger for the case of advancing an address counter, but it's also an asynchronous level trigger for the purpose of making SD an output, and an asynchronous clear for another counter. It is NOT a clock. If I specify it as one, then the timing constraints cry about cross-domain interaction. It seems that Vivado hates asynchronous triggers. Are there any tricks for telling it that you definitely want an input to be asynchronous and you'll take your lumps from any race conditions?
It's not that Vivado hates asynchronous triggers. It's that that FPGA fabric hates having flip-flop clock inputs driven regular logic signals not on a global clock net.
Remember any signal on the sensitivity list with a negedge or posedge decoration is considered to be either an async reset or a clock, and the discussion above tells how the two are distinguished. So you wrote your code to infer an edge-triggered flip-flop.
Try putting a BUFG macro on the signal which you are using as that clock. That will put the signal on the global clock net and satisfy the tools. Note that you might incur a routing delay penalty for doing so.
module CARDADDR(
(* CLOCK_BUFFER_TYPE = "BUFG" *) input SR3,
input P2,
input BUSAK,
input mode,
output reg [7:0] card_addr,
output reg loading_values
);
...
always@(posedge P2, posedge SR3) begin
if(SR3) begin
card_load_count <= 0;
LD_EN <= 0;
end else if(P2) begin
if(!LD_EN) begin
{LD_EN, card_load_count} <= { 1'b0, card_load_count } + 1;
end
end
end
I should note that if this is the only code, all clears are asynchronous. But with the follow-on code, it apparently freaks out about the possibility of loading a transitional value from LD_EN and converts it to a synchronous clear.always@(posedge P2, posedge BUSAK) begin
if(BUSAK) begin
loading_values <= 0;
end else if(P2) begin
loading_values <= 1;
end
end
It generates a little more circuitry for this part than I'd deem necessary, but whatever.always@(negedge SR3, negedge mode)
begin
if(!mode) begin
card_addr <= 0;
end else begin
if(loading_values) begin
card_addr <= card_addr + 1;
end
end
end
Secondly, I now see in one module that it warns of a non-clock source driving clock inputs. The non-clock source is, of course, SR3. It is definitely a trigger for the case of advancing an address counter, but it's also an asynchronous level trigger for the purpose of making SD an output, and an asynchronous clear for another counter. It is NOT a clock. If I specify it as one, then the timing constraints cry about cross-domain interaction. It seems that Vivado hates asynchronous triggers. Are there any tricks for telling it that you definitely want an input to be asynchronous and you'll take your lumps from any race conditions?
It's not that Vivado hates asynchronous triggers. It's that that FPGA fabric hates having flip-flop clock inputs driven regular logic signals not on a global clock net.
Remember any signal on the sensitivity list with a negedge or posedge decoration is considered to be either an async reset or a clock, and the discussion above tells how the two are distinguished. So you wrote your code to infer an edge-triggered flip-flop.
Try putting a BUFG macro on the signal which you are using as that clock. That will put the signal on the global clock net and satisfy the tools. Note that you might incur a routing delay penalty for doing so.
Well, I tried that. The schematic shows it appearing on a BUFG buffer, but it still gives me the same message: "The clock pin card_addr_reg[0].C is not reached by a timing clock" and in the timing report it says "Register/Latch pins with no clock driven by root clock pin: SR3" and lists card_addr_reg[0..7]/C. In "no_input_delay" it complains with high severity about a lack of timing constraints on my asynchronous inputs (yeah, that's part of being asynchronous).
Well, here's what I have currently:Code: [Select]module CARDADDR(
I should note that if this is the only code, all clears are asynchronous. But with the follow-on code, it apparently freaks out about the possibility of loading a transitional value from LD_EN and converts it to a synchronous clear.
(* CLOCK_BUFFER_TYPE = "BUFG" *) input SR3,
input P2,
input BUSAK,
input mode,
output reg [7:0] card_addr,
output reg loading_values
);
...
always@(posedge P2, posedge SR3) begin
if(SR3) begin
card_load_count <= 0;
LD_EN <= 0;
end else if(P2) begin
if(!LD_EN) begin
{LD_EN, card_load_count} <= { 1'b0, card_load_count } + 1;
end
end
end
always @(posedge clk, negedge rst) begin
if (!rst)
q <= 1'b0;
else
q <=d;
end
if(!LD_EN) begin
{LD_EN, card_load_count} <= { 1'b0, card_load_count } + 1;
end
Code: [Select]always@(posedge P2, posedge BUSAK) begin
if(BUSAK) begin
loading_values <= 0;
end else if(P2) begin
loading_values <= 1;
end
end
It generates a little more circuitry for this part than I'd deem necessary, but whatever.
Finally, the section that it panics about clocking without a timed clock (and also freaks out about all the other inputs to its generated FFs being possibly unconstrained):Code: [Select]always@(negedge SR3, negedge mode)
begin
if(!mode) begin
card_addr <= 0;
end else begin
if(loading_values) begin
card_addr <= card_addr + 1;
end
end
end
Code: [Select]module CARDADDR(
I should note that if this is the only code, all clears are asynchronous. But with the follow-on code, it apparently freaks out about the possibility of loading a transitional value from LD_EN and converts it to a synchronous clear.
(* CLOCK_BUFFER_TYPE = "BUFG" *) input SR3,
input P2,
input BUSAK,
input mode,
output reg [7:0] card_addr,
output reg loading_values
);
...
always@(posedge P2, posedge SR3) begin
if(SR3) begin
card_load_count <= 0;
LD_EN <= 0;
end else if(P2) begin
if(!LD_EN) begin
{LD_EN, card_load_count} <= { 1'b0, card_load_count } + 1;
end
end
end
Well, you described a synchronous clear.
Actually, it's more confusing than that. In the above block, which is the "clock" and which is the "asynchronous reset?" Looks to me like SR3 is the reset and P2 is the clock. What might be confusing the tools (and you, and me) is that you check the state of P2 for your clock edge detector. Now, I'm a VHDL guy, and this is one of the "features" of Verilog that still makes me wonder what they were thinking. (VHDL is absolutely clear on this: you'd use rising_edge(P2) to clearly indicate "I want to infer a rising-edge-triggered flip-flop with the clock as P2." But I digress.)
You might wish to simulate that block and see what it's actually doing. Because it looks to me like LD_EN is permanently low. Look at the assignment:Code: [Select]if(!LD_EN) begin
{LD_EN, card_load_count} <= { 1'b0, card_load_count } + 1;
end
LD_EN is always assigned 1'b0, so it's always low and on every rising edge of P2 card_load_count increments. What happens when that incremented overloads? I have no idea. I don't know what you intend with this code.
QuoteCode: [Select]always@(posedge P2, posedge BUSAK) begin
if(BUSAK) begin
loading_values <= 0;
end else if(P2) begin
loading_values <= 1;
end
end
Here you're doing a simpler flop with async clear. Get rid of the check if (P2). It is implied that if BUSAK has not seen a rising edge, then the only thing that triggers the block is the rising edge of P2. And that should infer a proper edge-triggered flip-flop with P2 as the clock and BUSAK as the async clear.
always@(posedge P2, posedge BUSAK) begin
if(BUSAK) begin
loading_values <= 0;
end else begin
if(LD_EN) begin
loading_values <= 1;
end
end
end
For clarity: the complaints you get come from the timing analyzer or the synthesizer?
In any case, you've used SR3 as a reset way up above and now you're using it as a clock, so there's no surprise that the tools can't make heads or tail of what you want to do.
that synthesizes to:
which is exactly as the circuit you posted, will do the job
always@(posedge P2, posedge SR3_RST) begin
if(SR3_RST) begin
card_load_count <= 0;
LD_EN <= 0;
end else if(P2) begin
if(!LD_EN) begin
{LD_EN, card_load_count} <= { 1'b0, card_load_count } + 1;
end
end
end
always@(posedge P2, posedge BUSAK) begin
if(BUSAK) begin
loading_values <= 0;
end else begin
if(LD_EN) begin
loading_values <= 1;
end
end
end
// Advance the address if LD is active
always@(negedge SR3_CLK, negedge mode)
begin
if(!mode) begin
card_addr <= 0;
end else begin
if(loading_values) begin
card_addr <= card_addr + 1;
end
end
end
set_property IOSTANDARD LVTTL [get_ports {card_addr[7]}]
set_property IOSTANDARD LVTTL [get_ports {card_addr[6]}]
set_property IOSTANDARD LVTTL [get_ports {card_addr[5]}]
set_property IOSTANDARD LVTTL [get_ports {card_addr[4]}]
set_property IOSTANDARD LVTTL [get_ports {card_addr[3]}]
set_property IOSTANDARD LVTTL [get_ports {card_addr[2]}]
set_property IOSTANDARD LVTTL [get_ports {card_addr[1]}]
set_property IOSTANDARD LVTTL [get_ports {card_addr[0]}]
set_property IOSTANDARD LVTTL [get_ports BUSAK]
set_property IOSTANDARD LVTTL [get_ports loading_values]
set_property IOSTANDARD LVTTL [get_ports mode]
set_property IOSTANDARD LVTTL [get_ports P2]
create_clock -period 500.000 -name P2 -waveform {0.000 250.000} [get_ports P2]
# set_false_path -from [get_clocks SR3] -to [get_clocks P2]
create_clock -period 2000.000 -name SR3 -waveform {0.000 1000.000} [get_ports SR3_CLK]
set_input_delay 0.000 [get_ports {BUSAK mode SR3_RST}]
set_false_path -from [get_ports mode] -to [get_pins -hierarchical *card_addr_reg*/CLR*]
set_output_delay -clock [get_clocks SR3] -min 300.000 [get_ports {{card_addr[0]} {card_addr[1]} {card_addr[2]} {card_addr[3]} {card_addr[4]} {card_addr[5]} {card_addr[6]} {card_addr[7]}}]
set_output_delay -clock [get_clocks P2] -min 300.000 [get_ports loading_values]
set_output_delay -clock [get_clocks SR3] -max 400.000 [get_ports {{card_addr[0]} {card_addr[1]} {card_addr[2]} {card_addr[3]} {card_addr[4]} {card_addr[5]} {card_addr[6]} {card_addr[7]}}]
set_output_delay -clock [get_clocks P2] -max 400.000 [get_ports loading_values]
For clarity: the complaints you get come from the timing analyzer or the synthesizer?
In any case, you've used SR3 as a reset way up above and now you're using it as a clock, so there's no surprise that the tools can't make heads or tail of what you want to do.Yeah and that's the problem: It is both. Is there a way to "clone" the signal in a way that fools Verilog into thinking one is a clock and the other is a reset signal?
module test(
input a,
input b,
input c,
input d,
input e,
output y,
output reg z);
always@(posedge c) begin
z <= a | b;
end
assign y = z & (c | d) ^ (c & e);
end
always@ (c) begin
z <= a | b;
end
It does not create a circuit that clocks on either change of c. It just creates a combinational circuit a|b and wires it to z.create_clock -period 100.000 -waveform {0.000 50.000} [get_ports c]
set_input_delay -clock [get_clocks c] -min -add_delay -25.000 [get_ports a]
set_input_delay -clock [get_clocks c] -max -add_delay 50.000 [get_ports a]
set_input_delay -clock [get_clocks c] -min -add_delay -25.000 [get_ports b]
set_input_delay -clock [get_clocks c] -max -add_delay 50.000 [get_ports b]
This results in a hold violation. It seems mad that the data arrived before it was needed. Why? Furthermore, it only complained about input "a" and not "b". Why? They are both placed on adjacent pads and are both sent on a whirlwind winding route throughout the entire chip before finally making it to the LUT. So if there are skewed arrival times, it's the router's fault. But either way, it appears that the timing check has decided that "a" arrived -11ns before the required time of 0. Why is that a problem?
You systematically refuse to adhere to the synchronous design paradigm, so the tools systematically complain. The always block means c is a clock. You cannot use a clock in a combinational circuit, as you do in the assign.