forwarded clock command
create_generated_clock -name Clkout -source [get_pins ODDR_inst/C] -combinational [get_pins ODDR_inst/Q]
forwarded clock command
create_generated_clock -name Clkout -source [get_pins ODDR_inst/C] -combinational [get_pins ODDR_inst/Q]
This finds all the cells of a certain type but it doesn’t check if the CE is connected to VCC
show_objects -name find_1 [get_cells -hierarchical -filter { PRIMITIVE_TYPE == REGISTER.SDR.FDCE } ]
This however is more through: finds all flops with an enable pin and then verifies that it’s not connected to power (vcc)
set ffs_with_ce {}
foreach ff [get_cells -hier -filter {PRIMITIVE_SUBGROUP == “flop”}] {
if {[get_property TYPE [get_nets -of_objects [get_pins -of_objects $ff -filter IS_ENABLE]]] != “POWER”} {lappend ffs_with_ce $ff}
}
In recent generations of Xilinx FPGAs a new feature has been introduced: HARD_SYNC dedicated synchronization registers.
These are hardwired/dedicated blocks with 3 registers specifically designed with synchronization purposes.
It’s possible to configure a hard_sync synchronizer for 2 or 3 stages of shift registers. These should give the best defence against meta-stability while sampling asynchronous signals.
Here is how they are used in Verilog:
HARD_SYNC #(
.INIT(1’b0), // Initial value
.IS_CLK_INVERTED(1’b0), // configurable inverted clock
.LATENCY(2) // 2-3 stage shift register
)
uhardsync (
.DIN(DIN), // input Data
.DOUT(DOUT), // output Data
.CLK(CLK) // Clock
);
(* ALLOW_COMBINATORIAL_LOOPS = “true”, KEEP = “true” *) wire ring;
Verilog (1364-2001 🙂 allows one generation of array of instances. In order to generate an array of instances, the instance name should be followed by a range:
buf my_bufs[9:0](.I(), .O());
In Vivado, one way to cleanup timing after final place & route is to unplace the cells in the worst negative slack path and just place & route that portion. I have had great success with this in the GUI flow. It’s quite easy there. You just do a timing report (report_timing_summary), right-click on the timing path and say unplace cells. Then you run the cleanup commands.
Of course it’s tedious to do this manually but one has to find all the cells involved in a timing path. Here is what I came up with:
set string [report_timing -no_header -path_type full -return_string]
set items [split string]
foreach item $items {if [regexp {TOP\/.*$} item] {lappend cells [get_cells -filter {IS_PRIMITIVE==1} -of_objects [get_pins $item]]))
So here we get a timing report, find all fields in it then if the item starts with our TOP module name, we assume it’s a pin name and get the cell of that pin. This finds some of the same cells twice but unplacing an already unplaced cell is fine so we don’t have to worry about duplicates.
Finally one can do
unplace_cell $cells
place_design -directive Explore
route_design -directive Explore
route_design -tns_cleanup
phys_opt_design -directive Explore
for final rip & re-route stage. I usually get very good timing results from this.
set_property -name {xsim.simulate.runtime} -value {9000ns} -objects [get_filesets sim_1]
set_param synth.elaboration.rodinMoreOptions {rt::set_parameter minFsmStates 4}
AR #65413 is a really annoying answer record from Xilinx. They are basically saying that a perfectly legitimate piece of code won’t work in Vivado synthesis and they have no intention of fixing it. Alas the following code will not work:
generate
for (g=0; g < D; g++) begin: regs
//string rlocval;
//localparam string rlocpre = "X0Y";
//localparam string rloc = {rlocpre, rlocval.itoa(g/8)};
localparam rlocpre = "X0Y";
localparam byte rlocbyte = g/8 + 48;
localparam rloc = {rlocpre, rlocbyte};
localparam bel[8] = {"AFF", "A5FF", "BFF", "B5FF", "CFF", "C5FF", "DFF", "D5FF"};
(* RLOC = rloc, BEL = bel[g%8] *) FDRE u(.C(clk), .D(d[g]), .Q(q[g]), .CE(1'b1), .R(1'b0));
end
endgenerate
Omnivision Image sensors support a serial control interface called SCCBÂ Omnivision SCCB spec
The main difference between SCCB & I2C is that it’s specified as SCLK being output only and active driver instead of open-drain (or tri-state or open-collector). If one actually wants to remove the pull-up on the SCLK and use this feature, it causes a minor issue with some I2C IP blocks in FPGA as they assume open-drain SCLK. Specifically in Xilinx AXI IIC controller, the IP generates 3Â signals (scl_i, scl_o, scl_t) which are normally used to control a set of IBUF & OBUFT pads to drive scl_io PAD. The way to use this IP in an SCCB setting is to use the scl_t signal to drive the scl_io. Xilinx OBUFT has an active high tri-state so scl_t is high when scl_io needs to be pulled-up and it’s low with scl_o being also low. So scl_t carries the intent of scl_io signal when active driven. Also scl_i should be connected to scl_t for the IP to sense the driven signal.
One final complication is that if one makes the IIC interface external and uses some of the signals in the Vivado block diagram, Vivado makes all remaining signals external too which creates non-existing pins so all scl_x signals (other than scl_t) should be consumed inside the block diagram. scl_i being connected to scl_t takes care of that signal but scl_o should also be consumed. One can use it as an active low source or “or” it to another signal (it’s always zero so it can’t hurt) for it to be not exported out of the top level wrapper.
In Vivado 2015.3Â PTP_ETHERNET Â are removed by design. To get them back the following tcl command needs to be run:
set_property CONFIG.PCW_EN_PTP_ENET0 1 [get_bd_cells processing_system7_0]