1
\$\begingroup\$

I am attempting to perform a CDC from a FIFO Generator IP to AXI registers. Forgive my lack of understanding of Verilog, I'm a VHDL guy.

What I have:

cdc_fifo_64 timer_fifo(
   .rst(reset_p), // active high
   .wr_clk(CNTR_CLK), // MUST be 500MHz
   .rd_clk(S_AXI_ACLK), // MUST be 100MHz
   .din(timer),
   .wr_en(TRIGGER_os),
   .rd_en(1'b1),
   .dout(timer_cdc),
   .full(),
   .empty()
);
  
cdc_fifo_32 interval_fifo(
  .rst(reset_p), // active high
  .wr_clk(CNTR_CLK), // MUST be 500MHz
  .rd_clk(S_AXI_ACLK), // MUST be 100MHz
  .din(interval),
  .wr_en(TRIGGER_os),
  .rd_en(1'b1),
  .dout(interval_cdc),
  .full(),
  .empty()
);
  
always @(S_AXI_ACLK) begin
  slv_reg2  <= interval_cdc;
  slv_reg1  <= timer_cdc[63:32];
  slv_reg0  <= timer_cdc[31:0];
end

I do not want the last block to add a clock cycle of delay for something as simple as renaming signals.

In VHDL I could simply assign bit fields (so I could use slv_reg1 <= timer_cdc(63 downto 32)) and have no issues with sequential/combinatorial assignments. But here, I have reg signals (and I should not be changing slv_regX to a wire or renaming it). How can I assign these so that I simply rename the reg output to a bit field of another reg?

\$\endgroup\$
3
  • \$\begingroup\$ not quite sure what the problem here is? slr_reg1 <= timer_cdc[63:32] does, in fact, directly latch the 32nd to 63rd bit of timer_cdc into slv_reg1, exactly as you want it. \$\endgroup\$ – Marcus Müller Oct 30 '20 at 16:27
  • \$\begingroup\$ if you don't want to latch, but want to things to be the same, why are you placing a latching (<=) in a process (always @...)? \$\endgroup\$ – Marcus Müller Oct 30 '20 at 16:30
  • \$\begingroup\$ Again, forgive my complete lack of understanding of Verilog syntax and design flow. For your first comment, I thought this would behave like putting an assignment in a synchronous process in VHDL - i.e., once S_AXI_ACLK goes high and the signal timer_cdc changes, the slv_* registers only change on the next clock cycle. Due to timing, I need them to change as though I could be able to assign .dout[63:32](slv_reg1). For your second comment, I am doing that because doing assign slv_reg* = doesn't work for a reg signal, right? \$\endgroup\$ – comc cmoc Oct 30 '20 at 16:47
2
\$\begingroup\$

You can use continuous assignment instead of procedural assignment.

For example

wire slv_reg2;

// ...

assign slv_reg2 = interval_cdc;

I should not be changing slv_regX to a wire or renaming it

You should. Declaring a signal as wire or reg in Verilog has nothing to do with whether the signal is actually the output of a register or of combinatorial logic. It has nothing to do with whether registers or combinatorial logic is synthesized. It only determines how you can use that signal name in the Verilog language.

You can assign to wire signals by connecting them to submodule instance outputs, or with continuous assignment statements (assign). You can assign to reg signals in procedural blocks. When writing Verilog, you simply have to get used to changing the signal declaration between reg and wire if you change how you assign to the signal within the Verilog code. Again, this will have very little to do with what logic (combinatorial or sequential) gets inferred when you synthesize your design.

SystemVerilog allows you to avoid this confusing mess (at least if you don't need multiply-driven signals, such as wired-or signals) by allowing you to declare a signal as logic. This allows it to be assigned to in either a procedural or continuous assignment. Some Verilog tools may also allow using the logic signal type.

Some simulation and synthesis tools may also ignore how you declare your signals and allow you to make procedural assignments to wire signals and/or continuous assignments to reg signals, but if you write your code assuming you will be using one of these tools, it is likely to break when you for some reason have to switch to another tool.

\$\endgroup\$
4
  • \$\begingroup\$ This was my first thought as well, but I am using a prebuilt AXI-Lite module and I am concerned whether or not renaming the slv_regX signals to wire could possibly break anything in what was already given to me. \$\endgroup\$ – comc cmoc Oct 30 '20 at 16:45
  • \$\begingroup\$ @comccmoc, if this signal is an output of your code and an input to the AXI module, then it will not matter to the AXI module whether you declare it wire or reg. \$\endgroup\$ – The Photon Oct 30 '20 at 16:48
  • \$\begingroup\$ Thanks for clarifying that this doesn't make a difference! I've changed out my slv_reg signals to wires and directly assigned them \$\endgroup\$ – comc cmoc Oct 30 '20 at 17:14
  • \$\begingroup\$ SV introduced 'logic' just like 'signal' in vhdl, to avoid this whole mess of reg and wire :D \$\endgroup\$ – Mitu Raj Oct 30 '20 at 18:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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