On scoping rules: http://www.sigasi.com/content/use-and-library-vhdl

Reducing scope

Reducing scope reduces chances to mis-use a variable in the wrong place. It also allows shorter variable names with assumed context.

Named blocks

http://www.ics.uci.edu/~jmoorkan/vhdlref/blocks.html

  • “A Block may contain any of the declarations possible for an architecture. Items declared within a block are only visible inside it.”
cs: block
    signal control : std_logic_vector(35 downto 0);
begin
    chipscope_icon : chipscope_icon1
        port map (
            CONTROL0 => control);
    chipscope_ila0 : ila16x32x8192
        port map (
            CONTROL  => control,
            CLK      => my_clk,
            ...
            TRIG15   => (others => '0'));
end block cs;

Generate

http://www.ics.uci.edu/~jmoorkan/vhdlref/generate.html

  • In VHDL '93 you can use the begin keyword to add space to put local definitions.
cs: if (USING_SATA_CS) generate
    signal control : std_logic_vector(35 downto 0);
begin
    chipscope_icon : chipscope_icon1
        port map (
            CONTROL0 => control);
    chipscope_ila0 : ila16x32x8192
        port map (
            CONTROL  => control,
            CLK      => my_clk,
            ...
            TRIG15   => (others => '0'));
end generate cs;

CS example

this is something like what I typically use. needs to be adjusted for scoping (see above) and other nice things I've learned since

also there were some intial advanteges when playing around with this form:

TRIG1    => (
        9 => tx_char_is_k_0(1), 8 => tx_char_is_k_0(0),
        7 => rx_char_is_k_0(1), 6 => rx_char_is_k_0(0),
        5 => '0',
        4 => '0', 
        3 => tx_buf_status_0(1), 2 => tx_buf_status_0(0),
        1 => rx_buf_status_0(1), 0 => rx_buf_status_0(0),
        others => '0'),

Mostly this was because it translated some Verilog code a little easier.

But now I do it more the standard way:

TRIG4(31 downto 16)   => (others => '0'),
TRIG4(15 downto 0)    => tx_data_0,

I would still like a way to default everything to 0 without additional declarations (ie keep it compact).

    chipscope_icon : chipscope_icon1
        port map (
            CONTROL0 => tmp_ila_control);

    -- The way that I code these makes xst pretty unhappy but it is short and does seem to synthesize correctly
    -- WARNING:HDLCompiler:946 - "sata_link_layer.vhd" Line 2042: 
    -- Actual for formal port trig0 is neither a static name nor a globally static expression
    -- You are supposed to be able to do TRIG0(31) => X but couldn't get syntax right

    -- For command/transport layer type issues
    chipscope_ila0 : ila16x32x8192
        port map (
            CONTROL  => tmp_ila_control,
            CLK      => tx_rx_usr_clk_2_0,
            TRIG0    => (
                    31 => dbg_boring,
                    30 => '0',
                    ...
                    2 => rx_reset_done_0,
                    1 => tx_reset_done_0,
                    0 => rx_buf_reset_0,
                    others => '0'),
            TRIG1    => (
                    9 => tx_char_is_k_0(1), 8 => tx_char_is_k_0(0),
                    7 => rx_char_is_k_0(1), 6 => rx_char_is_k_0(0),
                    5 => '0',
                    4 => '0', 
                    3 => tx_buf_status_0(1), 2 => tx_buf_status_0(0),
                    1 => rx_buf_status_0(1), 0 => rx_buf_status_0(0),
                    others => '0'),
            TRIG2    => (others => '0'), 
            TRIG3    => (others => '0'),
            TRIG4(31 downto 16)   => (others => '0'),
            TRIG4(15 downto 0)    => tx_data_0,
            TRIG5(31 downto 16)   => (others => '0'),
            TRIG5(15 downto 0)    => rx_data_0,
            ...
            TRIG15   => (others => '0'));

A sylistic note

Note that above is abusing xst a little and might not even synthesize on other tools. You will get a warning like this:

WARNING:HDLCompiler:946 - “my.vhd” Line 1338: Actual for formal port trig0 is neither a static name nor a globally static expression

Why? Apparantly VHDL philosiphy is supposed to have port actual parameters be strictly wiring only. I'm not a fan of this and prefer to inline construct the array

Thus, code like this:

chipscope_ila0 : ila16x32x8192
    ...
    TRIG0    => (
            31 => boring,
            ...
            2 => rx_reset_done_0,
            1 => tx_reset_done_0,
            0 => rx_buf_reset_0),

should really be written more like this:

chipscope_ila0 : ila16x32x8192
    ...
    TRIG0(31) => boring,
    ...
    TRIG0(2) => rx_reset_done_0,
    TRIG0(1) => tx_reset_done_0,
    TRIG0(0) => rx_buf_reset_0),

or “ideally” this:

signal TRIG0 : std_logic_vector(31 downto 0);
...
TRIG0    => (
        31 => boring,
        ...
        2 => rx_reset_done_0,
        1 => tx_reset_done_0,
        0 => rx_buf_reset_0);
chipscope_ila0 : ila16x32x8192
...
TRIG0    => TRIG0

The first case is illegal VHDL but seems to be accepted by the synthesis tools. The second is accepted but is now cluttered with explicit TRIG0 assignments. The third is the worst as now I have to look at the signal definition at the top of the file, the signal assignment, and the formal parameter to undrestand what trig0 is assigned to. If you want to confuse your users with indirection, write Java. If you want users to understand your code, make efforts to flatten the heirarchy and make it clear what code actually does with as little effort as possible.

 
vhdl/start.txt · Last modified: 2014/12/01 18:56 by mcmaster-guest
 
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution 4.0 International
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki