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

From: Brent Hayhoe <Brent.Hayhoe@Aftonroy.com>
Date: Tue Sep 04 2012 - 12:20:04 PDT
<html>
<font face="new courier">
<pre>

2nd try at reposting to see if I can maintain white-space.
I'm told this should work.

 > 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;

 > --
 >
 > 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.
 >

</pre>
</font>
</html>


-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Tue Sep 4 12:20:44 2012

This archive was generated by hypermail 2.1.8 : Tue Sep 04 2012 - 12:21:15 PDT