P1076 August 25, 2016 Meeting Minutes

Attendees:

  • Rob Gaddi, Kevin Jennings, Lieven Lemiengre, Patrick Lehmann

Agenda:

Meeting Discussion

What Happened on Kobra.io

------------------------------------------------------------------------
-- Slave-only package defines types and views without generics.
------------------------------------------------------------------------

package spi_slave_pkg is

    type qspi_slave_r is record
        io   : std_logic_vector(3 downto 0);  -- Bidirectional data
        sclk : std_logic;                     -- Serial clock
        ssel : std_logic                      -- Chip select (active-low)
    end record qspi_slave_r;

    type spi_slave_r is record
        mosi : std_logic;                     -- Data from master to slave
        miso : std_logic;                     -- Data from slave to master
        sclk : std_logic;                     -- Serial clock
        ssel : std_logic;                     -- Chip select (active-low)
    end record spi_slave_r;

    port view slave of qspi_slave_r is
        io   => inout;
        sclk => in;
        ssel => in;
    end port view slave;
    
    port view slave of spi_slave_r is
        mosi => in;
        miso => out;
        sclk => in;
        ssel => in;
    end port view slave;
   
end package spi_slave_pkg;

package body spi_slave_pkg is
end package body spi_slave_pkg;

------------------------------------------------------------------------
-- Basic package defines the types and views.
------------------------------------------------------------------------

use work.spi_slave_pkg.all;

package spi_bus_pkg is
    generic(
        CHIP_SELECTS : positive
    );
    
    subtype ssel_rng is natural range CHIP_SELECTS-1 downto 0;
    subtype ssel_vst is std_logic_vector(ssel_rng);

    type qspi_master_r is record
        io   : std_logic_vector(3 downto 0);  -- Bidirectional data
        sclk : std_logic;                     -- Serial clock
        ssel : ssel_vst                       -- Chip selects (active-low)
    end record qspi_master_r;
    
    type spi_master_r is record
        mosi : std_logic;                     -- Data from master to slave
        miso : std_logic;                     -- Data from slave to master
        sclk : std_logic;                     -- Serial clock
        ssel : ssel_vst                       -- Chip selects (active-low)
    end record spi_master_r;

    port view master of qspi_master_r is
        io   => inout;
        sclk => out;
        ssel => out;
    end port view master;
    
    port view master of spi_master_r is
        mosi => out;
        miso => in;
        sclk => out;
        ssel => out;
    end port view master;
    
end package spi_bus_pkg;

package body spi_bus_pkg is
end package body spi_bus_pkg;

------------------------------------------------------------------------
-- Using entities rather than mapfunctions to connect masters/slaves
-- to the physical wiring on the PCB.  Note that there is no entity
-- needed to translate the qspi_master, since that is just a view of
-- the qspi_master_r.
--
-- The use of the spaceship operator (<=>) below is intended to make
-- these connections without introducing delta cycles.
------------------------------------------------------------------------

entity spi_master_link
    generic (
        package pkg is new work.spu_bus_pkg generic map(<>)
    );
    port (
        mst : bus pkg.spi_master_r(master)'reversed;
        pcb : bus pkg.qspi_master_r(master)
    );
end entity spi_master_link;

architecture Behavioral of spi_master_link is
begin
    pcb.io   <=> (0 => mst.mosi, 1 => mst.miso, others => 'Z');
    pcb.sclk <=> mst.sclk;
    pcb.ssel <=> mst.ssel;
end architecture Behavioral;

----------------------------------------------------------------------

use work.spi_slave_pkg.all;

entity spi_slave_link
    generic (
        package pkg is new work.spu_bus_pkg generic map(<>);
        CHIP_SELECT : pkg.ssel_rng;
    );
    port (
        slv : bus spi_slave_r(slave);
        pcb : bus pkg.qspi_master_r(master)
    );
end entity spi_slave_link;

architecture Behavioral of spi_slave_link is
begin
    pcb.io   <=> (0 => slv.mosi, 1 => slv.miso, others => 'Z');
    pcb.sclk <=> slv.sclk;
    pcb.ssel <=> (CHIP_SELECT => slv.ssel, others => 'Z');
end architecture Behavioral;

----------------------------------------------------------------------

use work.spi_slave_pkg.all;

entity qspi_slave_link
    generic (
        package pkg is new work.spu_bus_pkg generic map(<>);
        CHIP_SELECT : pkg.ssel_rng;
    );
    port (
        slv : bus qspi_slave_r(slave);
        pcb : bus pkg.qspi_master_r(master)
    );
end entity qspi_slave_link;

architecture Behavioral of qspi_slave_link is
begin
    pcb.io   <=> slv.io;
    pcb.sclk <=> slv.sclk;
    pcb.ssel <=> (CHIP_SELECT => slv.ssel, others => 'Z');
end architecture Behavioral;


All data bus 32b

Master 1 : 16b address space  (p1)

Slave 1 : 4b address space   (p2)
Slave 2 : 3b address space   (p3)
Slave 3 : 4b address space   (p4)
Slave 4 : 8b address space   (p5)


-- Legal 2008 Stuff

type bus_interface is record
  din : std_logic_vector(31 downto 0);
  dout : std_logic_vector(31 downto 0);
  addr : unsigned;
  write : std_logic;
  read  : std_logic;
  clk : std_logic;
  rst : std_logic;
end record;

signal globalbus : bus_interface( addr(0 to 10)); -- Syntax from LRM p.52(66)

-- Shiny and new

port view master of globalbus is
  din => out,
  dout => in,
  addr => out,
  write => out,
  read => out,
  clk => in,
  rst => in
end port view master;
    
port view slave of globalbus is
  din => in,
  dout => out,
  addr => in,
  write => in,
  read => in,
  clk => in,
  rst => in
end port view slave;

entity BusRam4 is
  port (
    databus : bus globalbus(slave);
  );
end entity BusRam4;

architecture Behavioral of RamBus4 is
  alias myaddr : unsigned(3 downto 0) is databus.addr(3 downto 0);
  
  WARNING: Unused input pin databus.addr(4)!
  WARNING: Unused input pin databus.addr(5)!
  WARNING: Unused input pin databus.addr(6)!
  WARNING: Unused input pin databus.addr(7)!
  WARNING: Unused input pin databus.addr(8)!
  WARNING: Unused input pin databus.addr(9)!
  WARNING: Unused input pin databus.addr(10)!


-- As an input

U1 : Some_Device port map( 
  Some_Bus(15 downto 0) => Some_Signal, 
  Some_Bus(31 downto 16) => open
); 



U1 : Some_Device port map( 
  Some_Bus(15 downto 0) => Some_Signal, 
  Some_Bus(31 downto 16) => open -- this is an error, if it's an output
); 

-- inputs
Some_Bus => (31 downto 16 => 'U') & Some_Signal,

-- outputs
Some_Bus => (31 downto 16 => open) & Some_Signal,


U1 : Some_Device port map( 
  Some_Bus => Some_Intermediate_Signal
); 

alias Some_Signal : std_logic_vector(15 downto 0) is Some_Intermediate_Signal(15 downto 0);



entity Some_Device is
  port (
    Some_Bus : out unsigned(31 downto 0)
  );
end entity;

architecture rtl of Some_Device is
begin
  Some_bus <= "01234567";
  
  sig <= Some_Bus(17)
end architecture;

sig --+--|>---- port
      |
      +----- readback

Review and Approve Meeting Minutes and Decisions by Attendees

Lieven, Kevin

Review and Approve Meeting Minutes and Decisions by non-attendees

-- JimLewis - 2016-09-01: Comments, concerns and questions follow

Putting the kobra.io in here is invaluable as it allowed me to pause and review the code in places not currently on the screen.

In the following (copied from above), I have concerns about the mapping of pcb.ssel:

entity spi_slave_link
    generic (
        package pkg is new work.spu_bus_pkg generic map(<>);
        CHIP_SELECT : pkg.ssel_rng;
    );
    port (
        slv : bus spi_slave_r(slave);
        pcb : bus pkg.qspi_master_r(master)
    );
end entity spi_slave_link;

architecture Behavioral of spi_slave_link is
begin
    pcb.io   <=> (0 => slv.mosi, 1 => slv.miso, others => 'Z');
    pcb.sclk <=> slv.sclk;
    pcb.ssel <=> (CHIP_SELECT => slv.ssel, others => 'Z');
end architecture Behavioral;
Really only the element of pcb.ssel indexed by CHIP_SELECT needs to be associated. All the others are not conneced. Using 'Z' actually puts a driver on it. I think it would be better expressed as one of the following:
    pcb.ssel <=> (CHIP_SELECT => slv.ssel, others => OPEN );
    pcb.ssel <=> (CHIP_SELECT => slv.ssel, others => DISCONNECTED);  -- keyword borrowed from guarded signals
    pcb.ssel(CHIP_SELECT) <=> slv.ssel ;  -- probably wrong since other elements are not associated at all and in this context would have a 'U' driven
                                                                     -- OTOH, if this were done directly in a structural netlist / test harness, then no driver would be on them
                                           

When using unconstrained arrays on ports, the size is determined by the actual, and hence, an alias is only needed to normalize the indices of the input array. Any access outside of the range of the actual (if directly referencing the port) or outside the range of the alias is a bounds error and is runtime fatal.

WRT Partiallyconnectedvectorsonportmap allowing open on inputs implies mapping a constant to type'left. In VHDL-87, mapping a constant to a port was not allowed and VHDL-93 changed this and allows this. This potentially is the origin of this issue. If it is, then it is simply an oversight. Being the LRM, I suspect that we need to add the interpretation of usage of open to be equivalent to mapping to type'left - especially since we are changing the current behavior.

U1 : Some_Device port map( 
  Some_Bus(15 downto 0) => Some_Signal, 
  Some_Bus(31 downto 16) => (31 downto 16 => std_logic'left) 
); 

Since someone can simply do the above, do we need this for inputs? OTOH, is there any reason to disallow it with the above as the interpretation? The [[http://www.eda-twiki.org/isac/IRs-VHDL-2002/IR2041.txt] provides an interesting discussion of what happens with initializations - particularly for partially connected vectors whose elements are initialized with an impure function (may be the answer is don't allow impure functions for initialization of partially connected vectors - ie: do first all elements get calculated or only ones that are not used get calculated - I am surprised that initialization would even allow impure functions and maybe we need to double check that). To minimize complexity when handling initializations, we could require that initializations get discarded with partially connected vectors and if you want something in particular, you need to map that value in the port map and if you use open, you get type'left and not any previously implied initialization.

For outputs, if it is not already allowed, I suspect it is essential. We need to be able to disconnect the driver from the output. The alternative is to wire it up to a dummy signal that is discarded. Usage of a dummy signal does not do a good job of conveying design intent.   What happens for outputs that are a composite and are resolved at the composite level (vs the element level) - I suspect partial mapping of these needs to be illegal - note I have never used one of these.

If there is a language interpretation issue with using the keyword open, perhaps an alternate keyword to convey this meaning, such as disconnected (already a keyword associated with guarded signals/blocks). I doubt this is necessary.

Do the above solve the problem from RTL to FPGA and/or ASIC? Going to FPGA, synthesis tools may be grumpy about unconnected IO, but are generally permissive. OTOH, ASIC tools, particularly place and route are not so forgiving. ASIC tools however provide synthesis techniques to either remove ports or to create and destroy hierarchy (which can also be used to remove pins) so with a little work, it is a feasible methodology.

OTOH, why not just use generics (for synthesis) or unconstrained arrays (for simulation) to allow these sort of ports to be flexibly sized on the entity and avoid all issues in the port map phase? One argument is that some IP is not editable, and hence, end users have to do this sort of thing to use the components.

WRT http://www.eda-twiki.org/isac/IRs-VHDL-2002/IR2041.txt I don't feel too constrained to be required to map all of the elements of an array contiguously. I would also require the use of open for objects that are partially connected.

Next Meeting: Thursday September 1, 2016, 11 am Pacific

Previous Meeting: Thursday August 18, 2016

Topic revision: r3 - 2016-09-01 - 18:00:24 - JimLewis
 
Copyright © 2008-2021 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback