Re: [vhdl-200x] Records with diectional subtypes - Repost

From: Brent Hayhoe <Brent.Hayhoe@Aftonroy.com>
Date: Thu Aug 30 2012 - 23:30:17 PDT

Reposting to see if I can maintain white-space.

<html>
<pre>
> On 30/08/2012 14:15, Peter Flake wrote:
>> Hi Brent,
>>
>> It turns out that SystemVerilog would be better if modports could be defined
>> outside interfaces (which maybe should have been called channels). It is
>> too late to change this, but we should not make the same mistake in VHDL.
>>
>> I think that the interface construct in your example can be removed, and we
>> can just use the port config. I have done this below.
>>
>> BTW I do not understand exactly what comp is doing.
>>
>> Regards,
>>
>> Peter Flake
>
> Hi Peter,
>
> To answer your question backwards: the 'comp' is a suggested additional syntax
> to the port modes of 'in', 'out', 'inout', 'buffer' and 'linkage' (of which the
> later I've never come across any usage). It is used to define an extra mode (not
> a replacement) for ports connected to composite data types (records and arrays),
> which is then sub-defined in a hierarchical manner as shown in the example.
>
> The 'interface' mechanism postulated was just a stab at providing a VHDL'ish
> mechanism for user-named port modes in order to simplify the port definitions in
> entities and procedures.
>
> Now, I am not very familiar with SystemVerilog, but as far as I understand it,
> its interface structure is an instantiateable object. I'm not sure I like that,
> because from a hardware perspective, interfaces are just interconnects. From a
> system and test bench level, it would be useful to add pseudo-object structures
> in order to check/provide protocol stimuli, etc. In the real world, one doesn't
> instantiate an interface, instead it is used to interconnect objects.
>
> I'd be interested to know why the SystemVerilog guys want to define modports
> outside of the interface. As I see it, they should be integral to the interface.
>
> The other point that I was concerned about was the way (in SystemVerilog
> examples as well) that we discuss options in 2 port terms, normally master/slave
> and this was one of the reasons I raised the complexity to include the arbiter
> port. As far as I understand SystemVerilog, it does permit multi-port interface
> modport definitions.
>
> Having just read the minutes of today's meeting and noting Jim's request for a
> block diagram, I am very, very tempted to shout "NO" because it was one of my
> main issues which directional records would help solve. However, I soon realized
> that I must have done this example very late at night and that it was riddled
> with errors! Thank you Jim.
>
> So here is a block diagram and the corrected VHDL example below:
>
> -------------------------------------------------------------------
> | top_level |
> | ------------- --------------------- |
> | | | ---- | ---- |
> | | ----| S6 | ----| S1 | |
> | | | ---- | ---- |
> | ------------|---- ----|------------ ----|------------ |
> | | m_plus_s | | | | a_m_and_s | | | s_only | |
> | | | | | | | | | | |
> | | ---- | | | | --- | | | ---- | |
> | | | M0 |---- | | ----| A | | | ----| S5 | | |
> | | ---- | | | | --- | | | ---- | |
> | | ---- | | | | ---- | | | ---- | |
> | | | S2 |---- | | ----| M1 | | | ----| S0 | | |
> | | ---- | | | | ---- | | ---- | |
> | | ---- | | | | ---- | ----------------- |
> | | | S4 |---- | | ----| S3 | | |
> | | ---- | | | ---- | |
> | ----------------- | | ---- | |
> | | ----| S7 | | |
> | | ---- | |
> | ----------------- |
> -------------------------------------------------------------------
>
> The HTML archive may mangle this, but the reflected Emails should be OK. If
> not, change the font to 'new courier' and hopefully all will be revealed.
>
> The first time I worked on this example, I got a bit worried about the
> structural block level interfaces with multiple drivers occurring from within
> different blocks. However, upon further thought I realized that what should
> happen is that the 'null' port assignments should propagate through as
> no-connects and therefore there should be no problems. From this it became
> obvious that a slave-only block should have a slave interface (with no
> generic), a block with a master but no arbiter should have a master interface
> (again with no generics, master or slave) and that a block with an arbiter
> has an arbiter interface.
>
> Package first:
>
> package cpu_bus_pkg is
> constant master_max_jc : positive := 2;
> subtype master_cs_jrt is natural range master_max_jc-1 downto 0;
>
> constant slave_max_jc : positive := 8+master_max_jc+1; --+1 for arbiter slave return
> subtype slave_cs_jrt is natural range slave_max_jc-1 downto 0;
>
> subtype adr_vst is std_logic_vector(15 downto 0);
> subtype dat_vst is std_logic_vector(15 downto 0);
> subtype m_en_vst is std_logic_vector(master_cs_jrt);
> subtype s_en_vst is std_logic_vector(slave_cs_jrt);
>
> type master_rt is --Master record
> record
> adr_vl : adr_vst; --Address
> dat_vl : dat_vst; --Data from master to slave
> we_l : std_logic; --Write enable from master
> en_vl : s_en_vst; --Slave enable from master
> end record master_rt;
>
> type master_at is
> array(master_cs_jrt) of master_rt; --Array of master signals to arbiter
>
> type arbiter_rt is --Arbiter control record
> record
> master_al : master_at; --Array of hierarchical master records to arbiter
> bus_req_vl : m_en_vst; --Bus requests from masters
> bus_grnt_vl : m_en_vst; --Bus grants to masters
> end record arbiter_rt;
>
> type slave_rt is --Slave record
> record
> sdt_vl : dat_vst; --Data from slave to master
> ack_l : std_logic; --Acknowledge from slave
> err_l : std_logic; --Error from slave
> end record slave_rt;
>
> type slave_at is
> array(slave_cs_jrt) of slave_rt; --Array of slave return records
>
> type cpu_bus_rt is
> record
> arbiter_rl : arbiter_rt; --Arbiter master control record
> master_rl : master_rt; --Bus master record from arbiter
> slave_al : slave_at; --Array of hierarchical slave records
> end record cpu_bus_rt;
>
> interface cpu_bus_if of cpu_bus_rt is
> port config slave_cfg is (
> generic (
> slave_cs_jg : slave_cs_jrt
> );
> port (
> arbiter_rl : null;
> master_rl : in;
> slave_al(slave_cs_jg) : buffer;
> slave_al(others) : null
> );
> end port config slave_cfg;
>
> port config master_cfg is (
> generic (
> master_cs_jg : master_cs_jrt
> );
> port (
> arbiter_rl : comp (
> master_al(master_cs_jrt),
> breq_vl(master_cs_jrt) : buffer;
> bgrnt_vl(master_cs_jrt) : in;
> master_al(others),
> breq_vl(others),
> bgrnt_vl(others) : null
> );
> master_rl : in;
> slave_sl : in
> );
> end port config master_cfg;
>
> port config arbiter_cfg is (
> port (
> arbiter_rl : comp (
> master_al, --Array of hierarchical master records into arbiter
> breq_vl : in; --Bus requests from masters
> bgrnt_vl : buffer; --Bus grants to masters
> );
> master_rl : out; --Bus master interface output
> slave_al : in --Bus slave interface input
> );
> end port config arbiter_cfg;
>
> port config blk_master_cfg is (
> port (
> arbiter_rl : comp (
> master_al,
> breq_vl : buffer;
> bgrnt_vl : in
> );
> master_rl : in;
> slave_sl : in
> );
> end port config blk_master_cfg;
>
> port config blk_slave_cfg is (
> port (
> arbiter_rl : null;
> master_rl : in;
> slave_al : buffer
> );
> end port blk_config slave_cfg;
> end interface cpu_bus_if;
> end package cpu_bus_pkg;
>
> Next entities:-
>
> --Arbiter entity
> use work.cpu_bus_pkg.all
> entity arbiter is
> generic (
> slave_cs_jg : slave_cs_jrt
> );
> port (
> clk_i : in std_logic;
> a_cpu_bus_h : cpu_bus_if(arbiter_cfg) --Arbitration output port
> cpu_bus_rt;
> s_cpu_bus_h : cpu_bus_if(slave_cfg) --Slave access port
> cpu_bus_rt;
> rst_i : in std_logic
> );
> end entity arbiter;
>
> --Master entity
> use work.cpu_bus_pkg.all
> entity master is
> generic (
> master_cs_jg : master_cs_jrt;
> slave_cs_jg : slave_cs_jrt
> );
> port (
> clk_i : in std_logic;
> m_cpu_bus_h : cpu_bus_if(master_cfg) --Master I/O port
> cpu_bus_rt(
> master_cs_jg => master_cs_jg);
> s_cpu_bus_h : cpu_bus_if(slave_cfg) --Slave access port
> cpu_bus_rt;
> rst_i : in std_logic
> );
> end entity master;
>
> --Slave entity
> use work.cpu_bus_pkg.all
> entity slave is
> generic (
> slave_cs_jg : slave_cs_jrt
> );
> port (
> clk_i : in std_logic;
> cpu_bus_h : cpu_bus_if(slave_cfg)
> cpu_bus_rt(
> slave_cs_jg => slave_cs_jg);
> rst_i : in std_logic
> );
> end entity slave;
>
> Structural block with master(s) with/without slaves:-
>
> --master plus slaves block
> use work.cpu_bus_pkg.all
> entity m_plus_s is
> port (
> clk_i : in std_logic;
> cpu_bus_h : cpu_bus_if(blk_master_cfg)
> cpu_bus_rt;
> rst_i : in std_logic
> );
> end entity master;
>
> architecture rtl of m_plus_s is
> begin
> i_master_0 : master
> generic map (
> master_cs_jg => 0,
> slave_cs_jg => 8
> )
> port map (
> clk_i => clk_i,
> m_cpu_bus_h => cpu_bus_h,
> s_cpu_bus_h => cpu_bus_h,
> rst_i => rst_i
> );
> i_slave_2 : slave
> generic map (
> slave_cs_jg => 2 --internally 'cpu_bus_h.en(id)' is the
> ) --only enable port that exists
> port map (
> clk_i => clk_i,
> cpu_bus_h => cpu_bus_h, --and is mapped to cpu_bus.en(2)
> rst_i => rst_i
> );
> i_slave_4 : slave
> generic map (
> slave_cs_jg => 4 --internally 'cpu_bus_h.en(id)' is the
> ) --only enable port that exists
> port map (
> clk_i => clk_i,
> cpu_bus_h => cpu_bus_h, --and is mapped to cpu_bus.en(4)
> rst_i => rst_i
> );
> end architecture rtl;
>
> Structural block with arbiter with/without masters and/or slaves:-
>
> --slaves only block
> use work.cpu_bus_pkg.all
> entity a_m_and_s is
> port (
> clk_i : in std_logic;
> cpu_bus_h : cpu_bus_if(arbiter_cfg)
> cpu_bus_rt;;
> rst_i : in std_logic
> );
> end entity a_m_and_s;
>
> architecture rtl of a_m_and_s is
> begin
> i_master : arbiter --arbiter at top level
> generic map (
> slave_cs_jg => 10
> )
> port map (
> clk_i => clk_i,
> a_cpu_bus_h => cpu_bus_h,
> s_cpu_bus_h => cpu_bus_h,
> rst_i => rst_i
> );
> i_master_1 : master --2nd master at top level
> generic map (
> master_cs_jg => 1,
> slave_cs_jg => 9
> )
> port map (
> clk_i => clk_i,
> m_cpu_bus_h => cpu_bus_h,
> s_cpu_bus_h => cpu_bus_h,
> rst_i => rst_i
> );
> i_slave_3 : slave
> generic map (
> slave_cs_jg => 3 --internally 'bus.en(id)' is the
> ) --only enable port that exists
> port map (
> clk_i => clk_i,
> cpu_bus_h => cpu_bus_h, --and is mapped to cpu_bus.en(3)
> rst_i => rst_i
> );
> i_slave_7 : slave
> generic map (
> slave_cs_jg => 7 --internally 'bus.en(id)' is the
> ) --only enable port that exists
> port map (
> clk_i => clk_i,
> cpu_bus_h => cpu_bus_h, --and is mapped to cpu_bus.en(7)
> rst_i => rst_i
> );
> end architecture rtl;
>
> Structural block with slave(s) only:-
>
> --slaves only block
> use work.cpu_bus_pkg.all
> entity s_only is
> port (
> clk_i : in std_logic;
> cpu_bus_h : cpu_bus_if(blk_slave_cfg)
> cpu_bus_rt;
> rst_i : in std_logic
> );
> end entity s_only;
>
> architecture rtl of s_only is
> begin
> i_slave_5 : slave
> generic map (
> slave_cs_jg => 5 --internally 'bus.en(id)' is the
> ) --only enable port that exists
> port map (
> clk_i => clk_i,
> cpu_bus_h => cpu_bus_h, --and is mapped to cpu_bus.en(5)
> rst_i => rst_i
> );
> i_slave_0 : slave
> generic map (
> slave_cs_jg => 0 --internally 'bus.en(id)' is the
> ) --only enable port that exists
> port map (
> clk_i => clk_i,
> cpu_bus_h => cpu_bus_h, --and is mapped to cpu_bus.en(0)
> rst_i => rst_i
> );
> end architecture rtl;
>
> Top level structure:-
>
> --Top level
> use work.cpu_bus_pkg.all
> entity top_level is
> port (
> clk_i : in std_logic;
> rst_i : in std_logic
> );
> end entity top_level;
>
> architecture rtl of top_level is
> signal cpu_bus_rs : cpu_bus_rt;
> begin
> i_m_plus_s : m_plus_s
> port map (
> clk_i => clk_i,
> cpu_bus_h => cpu_bus_rs,
> rst_i => rst_i
> );
> i_slave_6 : slave
> generic map (
> slave_cs_jg => 6 --internally 'bus.en(id)' is the
> ) --only enable port that exists
> port map (
> clk_i => clk_i,
> cpu_bus_h => cpu_bus_rs, --and is mapped to cpu_bus.en(6)
> rst_i => rst_i
> );
> i_a_m_and_s : a_m_and_s
> port map (
> clk_i => clk_i,
> cpu_bus_h => cpu_bus_rs,
> rst_i => rst_i
> );
> i_slave_1 : slave
> generic map (
> slave_cs_jg => 1 --internally 'bus.en(id)' is the
> ) --only enable port that exists
> port map (
> clk_i => clk_i,
> cpu_bus_h => cpu_bus_rs, --and is mapped to cpu_bus.en(1)
> rst_i => rst_i
> );
> i_s_only : s_only
> port map (
> clk_i => clk_i,
> cpu_bus_h => cpu_bus_rs,
> rst_i => rst_i
> );
> end architecture rtl;

</pre>
</html>

> --
>
> Regards,
>
> Brent Hayhoe.
>
> Aftonroy Limited Telephone: +44 (0)20-8449-1852
> 135 Lancaster Road,
> New Barnet, Mobile: +44 (0)79-6647-2574
> Herts., EN4 8AJ, U.K. Email: Brent.Hayhoe@Aftonroy.com
>
> Registered Number: 1744190 England.
> Registered Office:
>
> 4th Floor, Imperial House,
> 15 Kingsway,
> London, WC2B 6UN, U.K.
>

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Thu Aug 30 23:30:52 2012

This archive was generated by hypermail 2.1.8 : Thu Aug 30 2012 - 23:31:17 PDT