Placeholder page for this proposal

For now you can take a look at the attachments

I quickly hacked the modifications into our compiler & both files already pass syntax & semantic checks.

-- LievenLemiengre - 2015-10-26

Comments

Clipped from spi_bus_pkg.vhd and testbench.vhd:

    function select_qspi_slave(master: spi_record; i : ssel_rng)
        return spi_slave is
    begin
        return (master.mosi(0), master.miso(0), master.sclk, master.ssel(i));
    end function select_qspi_slave;
    
    ADC: entity work.spi_adc
        generic map (
            VREF => 3.0
        ) port map (
            spi => select_qspi_slave(spi, 1),
            ain => monitored_voltage
        );

I like the general idea here of creating a named mechanism for association. Treating it as a function has one big pro; it dramatically reduces the number of lines of code necessary to actually use the feature. It does inherantly force the returned group to be a subset of the input group(s), but the more I think about that, the more it feels like it doesn't pose any actual limitations in practice. After all, you'll always have one direction that's going to be acting as a subset.

The idea is extensible too, in that it solves the "How do you deal with directionality of clock and reset separate from the rest of the bundle" problem quite nicely.

    function master_to_slave(mst : master_bus, clk : std_logic, rst : std_logic)
        return slave_bus is
    begin
        return (
            addr => mst.addr,
            data => mst.data,
            cs => mst.cs,
            oe => mst.oe,
            we => mst.we,
            clk => clk,
            rst => rst
        );
    end function master_to_slave;

My concern is that, conceptually, what we're looking at here is really more of an association than it is procedural code. From that standpoint, an argument can be made that it should be more along the lines of:

    block select_spi_slave
        generic (
            i : ssel_rng
        );
        port (
            group master : spi_record;
            group slave  : spi_slave
        );
    begin
        map slave (master.mosi(0), master.miso(0), master.sclk, master.ssel(i));
    end block select_spi_slave;
    
    SELECT_ADC_SPI: block select_spi_slave
        generic map (i => 1)
        port map (master => spi, slave => adc_spi);
        
    ADC: entity work.spi_adc
        generic map (
            VREF => 3.0
        ) port map (
            spi => adc_spi,
            ain => monitored_voltage
        );

The concern with that is, of course, that it needs nearly twice as many lines of code to express the same concept in no clearer a way. Not taking advantage of the "function" style, with the concept of a return, forces an extra named "signal" into the design and all of the syntactic overheads that comes with.

I'm not sure if the functional style is something that can actually be reconciled with the way the rest of the language works; brevity isn't really a VHDL strong suit. The associative block style is more in keeping, but it's undeniably ugly.

Actually, thinking more about it, what about the attribute syntax? It's a bit of an odd choice, but there's precedent for attributes both as things that can take arguments and as things that allow creation of new objects. Think about x'delayed(10 ns) where x is a signal. That attribute call takes an argument and acts to create a new signal. Which means somewhere deep in the bowels of the world exists a concept like:

    attribute delayed(signal self : anything) return signal
    begin
        return self from one delta ago;
    end attribute delayed;
    
    attribute delayed(signal self : anything, constant delay : time) return signal
    begin
        return self from delay ago;
    end attribute delayed;

I think that's pretty much what we want. spi'spi_slave(2), or membus'slave(cs => 2, clk => clk, rst => rst).

-- RobGaddi - 2016-01-07

Topic attachments
I Attachment Action Size Date Who Comment
Unknown file formatvhd PortGroupsIntroduction.vhd manage 8.8 K 2015-10-26 - 22:57 LievenLemiengre Introduction to port groups
Unknown file formatvhd SimpleUseCase.vhd manage 4.9 K 2015-10-26 - 22:58 LievenLemiengre "Simple use case" with port groups
Compressed Zip archivezip spi_bus.zip manage 188.2 K 2015-10-27 - 01:11 LievenLemiengre SPI bus use case
Topic revision: r4 - 2016-11-15 - 18:23:39 - BrentHahoe
 
Copyright © 2008-2019 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback