Generic for port with array type

Discussion in 'VHDL' started by nivparsons, May 19, 2012.

  1. nivparsons

    nivparsons Guest

    I have a package that declares an array of STD_LOGIC, so I can use a
    generic to declare the port width and internal signal width(s).

    However, this is used on a 32 bit processor bus with separate byte
    enables.

    So, how can assign writes (& reads) to signals on a byte by byte
    allocation when the width is generic?

    I thought of something like: (ignoring write & read strobes etc).

    IF byte_en_0 THEN
    IF generic > 7 THEN
    my_signal(7:0) <= cpu_bus(7:0);
    ELSE
    my_signal(generic - 1:0) <= cpu_bus(generic-1 :0);
    END IF;

    IF byte_en_1 THEN
    IF generic > 15 THEN
    my_signal(15:8) <= cpu_bus(15:8);
    ELSIF generic > 8 THEN
    my_signal(generic - 1:8) <= cpu_bus(generic-1 :8);
    ELSE
    NULL;
    END IF;

    -- and similarly for byte_enable 2 & 3.
    I believe the above works, but seems very messy, is there a neater way
    please?
     
    nivparsons, May 19, 2012
    #1
    1. Advertising

  2. nivparsons

    KJ Guest

    On Saturday, May 19, 2012 6:54:29 AM UTC-4, nivparsons wrote:
    > I have a package that declares an array of STD_LOGIC, so I can use a
    > generic to declare the port width and internal signal width(s).
    >
    > However, this is used on a 32 bit processor bus with separate byte
    > enables.
    >
    > So, how can assign writes (& reads) to signals on a byte by byte
    > allocation when the width is generic?
    >
    > I thought of something like: (ignoring write & read strobes etc).
    >
    > IF byte_en_0 THEN
    > IF generic > 7 THEN
    > my_signal(7:0) <= cpu_bus(7:0);
    > ELSE
    > my_signal(generic - 1:0) <= cpu_bus(generic-1 :0);
    > END IF;
    >
    > IF byte_en_1 THEN
    > IF generic > 15 THEN
    > my_signal(15:8) <= cpu_bus(15:8);
    > ELSIF generic > 8 THEN
    > my_signal(generic - 1:8) <= cpu_bus(generic-1 :8);
    > ELSE
    > NULL;
    > END IF;
    >
    > -- and similarly for byte_enable 2 & 3.
    > I believe the above works, but seems very messy, is there a neater way
    > please?


    First recognize that the byte enables are a vector of width 'generic/8'. So the byte enable and data should be declared as:

    generic(data_width: in natural)
    ....
    cpu_bus(datawidth-1 downto 0);
    byte_enable(datawidth/-1 downto 0);

    Now you modify your code to index through the byte enables like this...

    for i in byte_en'range loop
    IF byte_en(i) THEN
    my_signal(8*i+7 downto 8*i) <= cpu_bus(8*i+7 downto 8*i);
    END IF;
    end loop;

    Kevin Jennings
     
    KJ, May 19, 2012
    #2
    1. Advertising

  3. nivparsons

    nivparsons Guest

    On Saturday, May 19, 2012 6:04:46 PM UTC+1, KJ wrote:
    > On Saturday, May 19, 2012 6:54:29 AM UTC-4, nivparsons wrote:
    > > I have a package that declares an array of STD_LOGIC, so I can use a
    > > generic to declare the port width and internal signal width(s).
    > >
    > > However, this is used on a 32 bit processor bus with separate byte
    > > enables.
    > >
    > > So, how can assign writes (& reads) to signals on a byte by byte
    > > allocation when the width is generic?
    > >
    > > I thought of something like: (ignoring write & read strobes etc).
    > >
    > > IF byte_en_0 THEN
    > > IF generic > 7 THEN
    > > my_signal(7:0) <= cpu_bus(7:0);
    > > ELSE
    > > my_signal(generic - 1:0) <= cpu_bus(generic-1 :0);
    > > END IF;
    > >
    > > IF byte_en_1 THEN
    > > IF generic > 15 THEN
    > > my_signal(15:8) <= cpu_bus(15:8);
    > > ELSIF generic > 8 THEN
    > > my_signal(generic - 1:8) <= cpu_bus(generic-1 :8);
    > > ELSE
    > > NULL;
    > > END IF;
    > >
    > > -- and similarly for byte_enable 2 & 3.
    > > I believe the above works, but seems very messy, is there a neater way
    > > please?

    >
    > First recognize that the byte enables are a vector of width 'generic/8'. So the byte enable and data should be declared as:
    >
    > generic(data_width: in natural)
    > ...
    > cpu_bus(datawidth-1 downto 0);
    > byte_enable(datawidth/-1 downto 0);
    >
    > Now you modify your code to index through the byte enables like this...
    >
    > for i in byte_en'range loop
    > IF byte_en(i) THEN
    > my_signal(8*i+7 downto 8*i) <= cpu_bus(8*i+7 downto 8*i);
    > END IF;
    > end loop;
    >
    > Kevin Jennings


    I see what you mean, but this doesn't handle things when the bus is,say, 19 bit s wide. OK for byte enables 0 & 1, but it wont really handl ebyte enable 2, which needs to handle just 3 bits.

    Niv
     
    nivparsons, May 20, 2012
    #3
  4. nivparsons

    KJ Guest

    On Sunday, May 20, 2012 3:54:47 PM UTC-4, nivparsons wrote:
    > On Saturday, May 19, 2012 6:04:46 PM UTC+1, KJ wrote:
    >
    > I see what you mean, but this doesn't handle things when the bus is,say, 19 bit s wide. OK for byte enables 0 & 1, but it wont really handl ebyte enable 2, which needs to handle just 3 bits.
    >

    A 'byte' enable would imply 8 bits, which is the solution I provided. For your new problem, there is only a slight modification required which is contained in the innermost 'if' statement.

    for i in byte_en'range loop
    IF byte_en(i) THEN
    if 8*i+7 > my_signal'high then
    my_signal(my_signal'high downto 8*i) <= cpu_bus(my_signal'high downto 8*i);
    else
    my_signal(8*i+7 downto 8*i) <= cpu_bus(8*i+7 downto 8*i);
    end if;
    END IF;
    end loop;

    Kevin Jennings
     
    KJ, May 21, 2012
    #4
  5. nivparsons

    nivparsons Guest

    On Monday, May 21, 2012 1:00:31 AM UTC+1, KJ wrote:
    > On Sunday, May 20, 2012 3:54:47 PM UTC-4, nivparsons wrote:
    > > On Saturday, May 19, 2012 6:04:46 PM UTC+1, KJ wrote:
    > >
    > > I see what you mean, but this doesn't handle things when the bus is,say, 19 bit s wide. OK for byte enables 0 & 1, but it wont really handl ebyte enable 2, which needs to handle just 3 bits.
    > >

    > A 'byte' enable would imply 8 bits, which is the solution I provided. For your new problem, there is only a slight modification required which is contained in the innermost 'if' statement.
    >
    > for i in byte_en'range loop
    > IF byte_en(i) THEN
    > if 8*i+7 > my_signal'high then
    > my_signal(my_signal'high downto 8*i) <= cpu_bus(my_signal'high downto 8*i);
    > else
    > my_signal(8*i+7 downto 8*i) <= cpu_bus(8*i+7 downto 8*i);
    > end if;
    > END IF;
    > end loop;
    >
    > Kevin Jennings


    I sorted what I wanted with a hint from your code.
    I needed my port width and associated registers to have the generic width, anywhere between 1 & 32, but writes to regs were from a CPU bus with separate byte write enable, so here is what I did: (code obfuscated a bit).

    write_to_registers : PROCESS (clk_66)
    BEGIN
    IF rising_edge(clk_66) THEN
    IF reset = '1' THEN
    sig_1 <= (OTHERS => '0');
    sig_2 <= (OTHERS => '0');
    ELSE

    sig_1 <= (OTHERS => '0'); -- Default condition.

    FOR i IN 0 TO 3 LOOP
    IF write_strb(i) = '1' THEN
    CASE address_bus IS
    WHEN addr_sig_1 =>

    IF GENERIC >= (8*i + 7) THEN
    sig_1(8*i+7 DOWNTO 8*i) <= write_data_bus(8*i+7 DOWNTO 8*i);
    ELSE
    IF GENERIC >= (8*i + 1) THEN
    sig_1(GENERIC-1 DOWNTO 8*i) <= write_data_bus(GENERIC-1 DOWNTO 8*i);
    ELSE
    NULL;
    END IF;
    END IF;

    WHEN addr_sig_2 =>
    sig_2(8*i+7 DOWNTO 8*i) <= write_data_bus(8*i+7 DOWNTO 8*i); -- Full 32 bit allocation

    WHEN OTHERS => NULL;

    END CASE;
    END IF;
    END LOOP;

    END IF;
    END IF;
    END PROCESS write_to_registers;
     
    nivparsons, May 24, 2012
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    9
    Views:
    8,041
    Ralf Hildebrandt
    Jan 19, 2005
  2. Replies:
    5
    Views:
    1,017
    Ralf Hildebrandt
    May 27, 2005
  3. Brandon
    Replies:
    5
    Views:
    1,413
    combinational.logic $ soc-ip.com
    Aug 6, 2005
  4. minlearn
    Replies:
    2
    Views:
    466
    red floyd
    Mar 13, 2009
  5. Daniel Thoma
    Replies:
    12
    Views:
    1,997
    markspace
    Jul 31, 2009
Loading...

Share This Page