Search code examples
vhdl

Components not being instantiated properly in VHDL generate statement


I'm working on a VHDL project to design an 8 bit ALU, using a previously designed one bit ALU. To do this, I'm using a generate statement to generate bits 1-6 of the ALU, while bits 0 and 7 are handled outside this block. What's happening is when I go to simulate the ALU, bits 1-6 never change value, no matter what the inputs are. I know the one bit ALU works fine, because instantiating 8 one bit ALUs manually works as expected.

I think what is happening is for whatever reason, the component instantiation inside the generate block is not being compiled properly. When I go to run the simulation in ModelSim, messages appear in the transcript stating that "component instance bit1_6 : bitslice is not bound". In an attempt to illustrate what is going on, the code I posted for the architecture firstGen does not compile, saying that "No statement with label bit1_6 : bitslice was found" (using a FOR ALL : ... masks the bad behavior, as lsb and msb are instantiated fine). Does anyone know what is going on?

ENTITY alu8bit IS
PORT( A, B : IN bit_vector(7 downto 0);
    P,K,R : IN bit_vector(3 downto 0);
    ci : IN bit;
    Z : OUT bit_vector(7 downto 0);
    co : OUT bit);
END;

ARCHITECTURE firstGen of alu8bit IS

COMPONENT bitslice 
    PORT(a, b, ci: IN bit;
        P, K, R : IN bit_vector(3 downto 0);
        ri, cn: OUT bit);
END COMPONENT;

FOR bit1_6: bitslice USE ENTITY work.one_bit_alu(alu_1_bit);
FOR others : bitslice USE ENTITY work.one_bit_alu(alu_1_bit);
signal c : bit_vector(7 downto 1);
BEGIN
    lsb : bitslice PORT MAP(A(0), B(0), ci, P, K, R, Z(0), c(1));
    GEN_MIDDLE_BITS: FOR I IN 1 TO 6 GENERATE
        bit1_6 : bitslice PORT MAP(A(I), B(I), c(I), P, K, R, Z(I), c(I+1));
    end generate;
    msb : bitslice PORT MAP(A(7), B(7), c(7), P, K, R, Z(7), co);
END;

Solution

  • The generate statement adds an additional layer of hierarchy to the namespace. When using an internal configuration specification you are limited to configuring components within the immediate scope. Anything inside a generate (or block) becomes unreachable. You can use the declarative region of a generate statement to specify the configuration binding for the intermediate slices:

    GEN_MIDDLE_BITS: FOR I IN 1 TO 6 GENERATE
      for bit1_6 : bitslice use entity work.one_bit_alu(alu_1_bit);
    begin
        bit1_6 : bitslice PORT MAP(A(I), B(I), c(I), P, K, R, Z(I), c(I+1));
    end generate;
    

    You may also consider using an external configuration declaration to keep everything together. If desired, configurations can be instantiated similarly to VHDL-93 direct entity instantiation.