Alternate way for port map in process?

前端 未结 1 1021
花落未央
花落未央 2020-12-20 07:46

As far as my understanding in vhdl, it is not possible to have port mappings to components within a process. and i was curious whether there is an alternative way to approac

相关标签:
1条回答
  • 2020-12-20 08:14

    As @BrianDrummond says, you can't make hardware magically appear and disappear at will. You cannot decide whether a lump of hardware exists and doesn't exist based on some inputs to the hardware. So, instead, you need to instantiate the hardware once and then control what is being input to it:

    signal L, R : std_logic_vector (7 downto 0);
    
    -- snip
    
    addi: ADD port map(L,R,carrybit,AddOut);   -- here is the ADD instance
    
    calc: process (Clock, ENABLE, RESET)
    
    -- snip
    
            --PC = PC + 1
            elsif (op = "01") then --add
    
                if(rs = "00") then
                    if(rt = "00") then
                        L <= R0; R <= R0;
                    elsif(rt = "01") then
                        L <= R0; R <= R1;
                    elsif(rt = "10") then
                        L <= R0; R <= R2;
                    else
                        L <= R0; R <= R3;
                    end if;
                elsif(rs = "01") then
                    if(rt = "00") then
                        L <= R0; R <= R0;
                    elsif(rt = "01") then
                        L <= R1; R <= R1;
                    elsif(rt = "10") then
                        L <= R1 R <= R2;
                    else
                        L <= R1; R <= R3;
                    end if;
                elsif(rs = "10") then
                    if(rt = "00") then
                        L <= R2; R <= R0;
                    elsif(rt = "01") then
                        L <= R2; R <= R1;
                    elsif(rt = "10") then
                        L <= R2; R <= R2;
                    else
                        L <= R3; R <= R3;
                    end if; 
                else
                    if(rt = "00") then
                        L <= R3; R <= R0;
                    elsif(rt = "01") then
                        L <= R3; R <= R1;
                    elsif(rt = "10") then
                        L <= R3; R <= R2;
                    else
                        L <= R3; R <= R3;
                    end if;
                end if;
                --use component of adder vhdl file?
    

    So, you can see I have declared two new signals L and R and I am using your process to control what is driving them. The ADD block will then add some combination of R0, R1, R2 and R3.

    I have answered you question below, but I see many other problems in your code, even though there's quite a lot of it and I only gave it a quick glance. In order they appear, not in order of seriousness:

    i) signal R0, R1, R2, R3: std_logic_vector (7 downto 0) := "00000000";

    Think very carefully why you are initialising these signals. This might work in an FPGA, but (coming from an IC design background) it seems dangerous to rely on initialising signals.

    ii) You are missing the instance name (strictly a label) for your decoder:

    decode port map (Instruction, op, rs, rd, rt);
    

    It should be something like:

    deci : decode port map (Instruction, op, rs, rd, rt);
    

    iii) You really ought to use named assoication in your port maps. Instead of:

    deci : decode port map (Instruction, op, rs, rd, rt);
    

    do:

    deci : decode port map (instr => Instruction, op => op, rs => rs, rd = rd, rt => rt);
    

    iv) Your process doesn't fit any template for a synthesisable sequential process:

    calc: process (Clock, ENABLE, RESET)
    begin    
    
        if (ENABLE = '0') then    
    
        else --ENABLE at 1
    
            if (rising_edge(RESET)) then
    
            elsif (rising_edge(Clock)) then
    
            elsif (Clock = '1') then
    

    Here is a template for a sequential process with an asynchronous reset:

    process(clock, async_reset)  -- nothing else should go in the sensitivity list
    begin
        -- never put anything here
        if async_reset ='1' then  -- or '0' for an active low reset
            -- set/reset the flip-flops here
            -- ie drive the signals to their initial values
        elsif rising_edge(clock) then  -- or falling_edge(clock)
            -- put the synchronous stuff here
            -- ie the stuff that happens on the rising or falling edge of the clock
        end if;
         -- never put anything here
    end process;        
    

    So, ENABLE should not be in your sensitivity list; the first line of your process should be:

    calc: process (Clock, RESET)
    

    You should test the ENABLE signal after the test for rising_edge(Clock):

            elsif (rising_edge(Clock)) then
               if (ENABLE = '0') then     
    

    You should test the absolute value of reset, not look for a rising edge. And you don't need all those parentheses. ie Not this:

        if (rising_edge(RESET)) then
    

    this:

        if RESET = '1' then
    

    This line is redundant:

    elsif (Clock = '1') then
    

    v) You should not be testing both edges of the clock. This is not synchronous design. You cannot test both edges in a single process. That is not even synthesisable. This needs to go:

        elsif (falling_edge(Clock)) then
    

    vi) I am concerned that you are driving R0 to R3 earlier in the process and then using their values later. It is difficult to see your design intent exactly, but I suspect this will not work:

    In VHDL signals are not updated until a process suspends. If you try to use a signal assigned earlier in a process, you will get the previously assigned value.

    General

    I suggest you break your design into many smaller processes. Have a clear idea for each what kind of hardware you expect for each. Have each perform a specific function, eg multiplexing the inputs to the ADD block. For example, consider:

    • Is the process sequential or combinational logic?

    • is the reset asynchronous or synchronous?

    • What are the inputs?

    • What are the outputs?

    And then pick the appropriate template. I have given one for a sequential process with an asynchronous reset. Here is one for a sequential process without an asynchronous reset:

    process(clock)  -- nothing else should go in the sensitivity list
    begin
        -- never put anything here
        if rising_edge(clock) then    -- or falling_edge(clock)
            -- put the synchronous stuff here
            -- ie the stuff that happens on the rising or falling edge of the clock
        end if;
         -- never put anything here
    end process;   
    
    0 讨论(0)
提交回复
热议问题