Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

tri-state bus inside FPGA.

Hello all.

I have a local bus in my design. (System Verilog).

interface regs_if(input clk, input rstn);
        logic          tx_data;
        logic          rx_data;
        logic          tx_addr;
        logic         rx_addr;
        logic                         wr;
        logic                 be;
endinterface
I have a lots of modules

module artem_regrw_m# (
                        parameter ADDR
                        )(
                        output reg  data,
                        output         be_wr,
                        regs_if regs
                        );
….
endmodule;
So, I can specify address of this module on bus etc.

Now I need add a read delay. If data in this module is not ready I will up signal ws.

But I will one signal ws for all modules. I will not make individual ws signal for each module and connect all of this modules with OR.

Also quartus say for string:

assign regs.tx_data = (ADDR == regs.tx_addr)?data:{64{1'bz}};

--- Quote Start ---

Warning: Tri-state node(s) do not directly drive top-level pin(s).

--- Quote End ---

And. If regs.tx_addr is not compare to any ADDR I'm read {64{1'b1}}; But I will {32'BADADDR0,regs.tx_addr}; How can I make this?

--- Quote Start ---

assign regs.tx_data = (ADDR[19:3] == regs.tx_addr[19:3])?data:regs.tx_data;

assign regs.tx_data |= (ADDR[19:3] == regs.tx_addr[19:3])?data:{64{1'b0}};

--- Quote End ---

is't working.

6 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Warning: Tri-state node(s) do not directly drive top-level pin(s).

    --- Quote End ---

    Internal tri-state busses are only virtual. They are translated to multiplexers by Quartus. You have to take care, that the select condition for inidividual tri-state drivers connected to the "bus" are mutual exclusive, otherwise you get a "multiple net driver" error.

    You'll always get some warnings with internal tri-state, that's the price of convenience. And they consume a lot of LUT and routing resources in a design. But that's basically the same with other bus topologies as the unidirectional bus used by SOPC builder.

    --- Quote Start ---

    But I will {32'BADADDR0,regs.tx_addr};

    --- Quote End ---

    You have to decode the condition, that no other bus interface is activated. It should work somehow, but seems like a kind of wasting resources in my view.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    You'll always get some warnings with internal tri-state, that's the price of convenience. And they consume a lot of LUT and routing resources in a design.

    --- Quote End ---

    Looks like I can use wired or (wor). But looks like it's don't work in quartus.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    gs_if(input clk, input rstn);
            wor          tx_data;
            logic          rx_data;
            logic          tx_addr;
            logic         rx_addr;
            logic                         wr;
            logic                 be;
    endinterface
    assign regs.tx_data = (ADDR == regs.tx_addr)?data:{64{1'b0}};
    

    It's not work. Quartus bug?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    It's not work. Quartus bug?

    --- Quote End ---

    You don't report erroneous behaviour or a compilation error. What are you talking about?

    --- Quote Start ---

    Looks like I can use wired or

    --- Quote End ---

    I'm not aware of "wired or" as a VHDL feature. Where do you see this option? There may be possibly a way by defining resolution functions...
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    http://quartushelp.altera.com/9.1/mergedprojects/hdl/vlog/vlog_support_data_types.htm

    --- Quote Start ---

    Wired Nets (wor, wand,trior, and triand Nets) - Supported

    --- Quote End ---

    By this. I'm change

    logic [63:0] tx_data;

    to

    wor [63:0] tx_data;

    and. (inside other module)

    from

    assign regs.tx_data = (ADDR[19:3] == regs.tx_addr[19:3])?data:{64{1'bz}};

    to

    assign regs.tx_data = (ADDR[19:3] == regs.tx_addr[19:3])?data:{64{1'b0}};

    But quartus

    Error: Net "......", which fans out to " ..... ", cannot be assigned more than one value
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thank you for clarifying. I was erroneously assuming you're working with VHDL. VHDL would require to define explicite resolution functions for wired or, but it's actually a built-in Verilog feature.

    I'm not aware of possible Quartus limitations in using wired net types across module boundaries. From the Verilog specification, it's clear that wired net types are intended to be connected through module ports, see e.g. the table "Net types resulting from dissimilar port connections".

    I would try with a test code, that uses wor inside a module, and then extend it for multiple modules. Either there's a problem in your usage of the wired net constructs, or the claimed support is not valid for module ports.