Vhdl 处理中的端口映射的替代方法?

Vhdl 处理中的端口映射的替代方法?,vhdl,Vhdl,就我对vhdl的理解而言,在进程中不可能有到组件的端口映射。我很好奇,是否有其他方法来处理条件情景 下面是我目前正在使用的计算器vhdl代码示例: library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; -- OP CODE TABLE -- -- 00 : LOAD -- -- 01 : ADD/SUB -- -- 10 : Print-- -- 11 :

就我对vhdl的理解而言,在进程中不可能有到组件的端口映射。我很好奇,是否有其他方法来处理条件情景

下面是我目前正在使用的计算器vhdl代码示例:

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;


-- OP CODE TABLE --
-- 00   :   LOAD --
-- 01   :   ADD/SUB  --
-- 10   :   Print--
-- 11   :   BEQ  --

-- li - RS Values --
-- 00 : R0 --
-- 01 : R1 --
-- 10 : R2 --
-- 11 : R3 --


-- //      add     | op, rs, rd, rt       //
-- //      sub     | op, rs, rd, rt       //
-- //      li      | op, rs, immediate    //
-- //      beq     | op, rs, rd, zero     //
-- //      print   | op, rs, zero, one    //


-- Current Problems --

-- need variables?
-- dont know what to do with numInst

entity Calculator is

port (

    Clock       : in std_logic;
    numInst     : in std_logic_vector (7 downto 0);
    --Max Value of PC? 8 bits
    Instruction : in std_logic_vector (7 downto 0);
    --8 bit instruction
    PC          : out std_logic_vector (7 downto 0);
    --8 bit output, used to retrieve next instruction
    PRINTER     : out std_logic_vector (7 downto 0);
    --8 bit output is set to value of register when instruction display is executed
    ENABLE      : in std_logic;
    --when high, instruction execute, when low, hold-no instruction executed
    RESET       : in std_logic
    --on rising edge, reset register value to 0, restart excution of calculator

);

end Calculator;

architecture Behavorial of Calculator is

component ADD is

port (

    A   : in std_logic_vector(7 downto 0);
    B   : in std_logic_vector(7 downto 0);
    Carry   : out std_logic;
    Sum : out std_logic_vector(7 downto 0)

);
end component;


component decode is

port (

    instr   : in std_logic_vector (7 downto 0);
    op  : in std_logic_vector (1 downto 0);
    rs  : in std_logic_vector (1 downto 0);
    rd  : out std_logic_vector (1 downto 0);
    rt  : out std_logic_vector (1 downto 0)

);
end component;

--need variable or signal to store opcode
--maybe need variable to store values identifier of rs, rt, rd
--random comment for something else...idk
--maybe we dont need a separate register vhdl file, make variable?

signal op, rs, rt, rd: std_logic_vector(1 downto 0):=(others=>'0');
signal immediate, AddOut: std_logic_vector(7 downto 0):=(others=>'0');
signal carrybit: std_logic;
--make register signals? R0, R1, R2, R3 
signal R0, R1, R2, R3: std_logic_vector (7 downto 0) := "00000000";

begin


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

calc: process (Clock, ENABLE, RESET)

-- use variables opcode, rs, rt, rd  to break up Instruction


begin

    if (ENABLE = '0') then

        --nothing, calculator is disabled

    else --ENABLE at 1



        if (rising_edge(RESET)) then

            PC <= "00000000"; -- restart execution
            op <= "00";
            rs <= "00";
            rt <= "00";
            rd <= "00";

            --registers go to 0

        elsif (rising_edge(Clock)) then

            --          


        elsif (Clock = '1') then
            if (op = "00") then
            --maybe can be used to load values into registers

                if(rd(1)='1') then
                    immediate(7 downto 4):='1';
                    immediate(3 downto 2)<= rd;
                    immediate(1 downto 0)<= rt;
                else
                    immediate(7 downto 4):='0';
                    immediate(3 downto 2)<= rd;
                    immediate(1 downto 0)<= rt;         
                end if;


            --PC = PC + 1
            elsif (op = "01") then --add

                if(rs = "00") then
                    if(rt = "00") then
                        addi00: ADD port map(R0,R0,carrybit,AddOut);
                    elsif(rt = "01") then
                        addi01: ADD port map(R0,R1,carrybit,AddOut);
                    elsif(rt = "10") then
                        addi02: ADD port map(R0,R2,carrybit,AddOut);
                    else
                        addi03: ADD port map(R0,R3,carrybit,AddOut);
                    end if;
                elsif(rs = "01") then
                    if(rt = "00") then
                        addi10: ADD port map(R1,R0,carrybit,AddOut);
                    elsif(rt = "01") then
                        addi11: ADD port map(R1,R1,carrybit,AddOut);
                    elsif(rt = "10") then
                        addi12: ADD port map(R1,R2,carrybit,AddOut);
                    else
                        addi13: ADD port map(R1,R3,carrybit,AddOut);
                    end if;
                elsif(rs = "10") then
                    if(rt = "00") then
                        addi20: ADD port map(R2,R0,carrybit,AddOut);
                    elsif(rt = "01") then
                        addi21: ADD port map(R2,R1,carrybit,AddOut);
                    elsif(rt = "10") then
                        addi22: ADD port map(R2,R2,carrybit,AddOut);
                    else
                        addi23: ADD port map(R2,R3,carrybit,AddOut);
                    end if; 
                else
                    if(rt = "00") then
                        addi30: ADD port map(R3,R0,carrybit,AddOut);
                    elsif(rt = "01") then
                        addi31: ADD port map(R3,R1,carrybit,AddOut);
                    elsif(rt = "10") then
                        addi32: ADD port map(R3,R2,carrybit,AddOut);
                    else
                        addi33: ADD port map(R3,R3,carrybit,AddOut);
                    end if;
                end if;
                --use component of adder vhdl file?
                --PC = PC + 1 ?


                --use adder (subtractor) component
                --PC = PC + 1 ?

            elsif (op = "10") then 

            -- need rs, rt, rd, variable?

                    if (rs = "00") then

                        PRINTER <= R0;
                        --insert print code here
                        --PC = PC + 1 -- to continue to next instruction

                    elsif (rs = "01") then

                        PRINTER <= R1;
                        --insert print code here
                        --PC = PC + 1 -- to continue to next instruction

                    elsif (rs = "10") then

                        PRINTER <= R2;
                        --insert print code here
                        --PC = PC + 1 -- to continue to next instruction
                    else  --(rs = "11") then

                        PRINTER <= R3;
                        --insert print code here
                        --PC = PC + 1 -- to continue to next instruction    

                    end if;


            elsif (op = "11") then --beq

                --if (register1 != register2) then

                        --PC <= PC + 1;

                --else

                        --PC <= PC + 2;

                --end if;

            end if;

        end if;

        elsif (falling_edge(Clock)) then

            if (op = "00") then

                if (rs = "00") then

                    R0 <= immediate;

                elsif (rs = "01") then

                    R1 <= immediate;

                elsif (rs = "10") then

                    R2 <= immediate;

                else --rs = "11"

                    R3 <= immediate;

                end if;

            elsif (op = "01") then

                if (rd = "00") then

                    R0 <= AddOut;--output of adder;

                elsif (rd = "01") then

                    R1 <= AddOut;--output of adder;

                elsif (rd = "10") then

                    R2 <= AddOut;--output of adder;

                else --rd = 11

                    R3 <= Addout;--output of adder;

                end if;

            end if;

        end if;

    end if;

end process calc;

end architecture Behavorial;
ieee库;
使用ieee.std_logic_1164.all;
使用ieee.numeric_std.all;
--操作码表--
--00:装载--
--01:ADD/SUB--
--10:打印--
--11:BEQ--
--li-RS值--
--00:R0--
--01:R1--
--10:R2--
--11:R3--
--//添加| op、rs、rd、rt//
--//sub | op,rs,rd,rt//
--//li | op,rs,immediate//
--//beq | op,rs,rd,zero//
--//打印| op,rs,零,一//
--当前问题--
--需要变量吗?
--不知道该拿努明斯特怎么办
实体计算器是
港口(
时钟:标准逻辑;
努明斯特:标准逻辑向量(7到0);
--PC的最大值?8位
指令:标准逻辑向量(7到0);
--8位指令
PC:输出标准逻辑向量(7到0);
--8位输出,用于检索下一条指令
打印机:输出标准逻辑向量(7到0);
--执行指令显示时,8位输出设置为寄存器的值
启用:在std_逻辑中;
--高电平时执行指令,低电平时不执行指令
复位:在标准逻辑中
--在上升沿,将寄存器值重置为0,重新启动计算器的执行
);
终端计算器;
计算器的体系结构行为是
组件添加是
港口(
A:标准逻辑向量(7到0);
B:标准逻辑向量(7到0);
执行:执行标准逻辑;
求和:输出标准逻辑向量(7到0)
);
端部元件;
组件解码是
港口(
仪器:标准逻辑向量(7到0);
op:标准逻辑向量(1到0);
rs:标准逻辑向量(1到0);
rd:输出标准逻辑向量(1到0);
rt:out标准逻辑向量(1到0)
);
端部元件;
--需要变量或信号来存储操作码
--可能需要变量来存储rs、rt、rd的标识符值
--其他内容的随机评论…idk
--也许我们不需要一个单独的寄存器vhdl文件,使变量?
信号op、rs、rt、rd:std_逻辑_向量(1到0):=(其他=>'0');
立即信号,输出:标准逻辑向量(7到0):=(其他=>'0');
信号载体:标准逻辑;
--发出寄存器信号?R0,R1,R2,R3
信号R0、R1、R2、R3:std_逻辑_向量(7到0):=“00000000”;
开始
--端口图
解码端口图(指令、op、rs、rd、rt);
计算:过程(时钟、启用、重置)
--使用变量opcode、rs、rt、rd分解指令
开始
如果(启用='0'),则
--无,计算器已禁用
else—在1启用
如果(上升沿(重置)),则

PC正如@BrianDrummond所说,你不能让硬件随意神奇地出现和消失。您无法根据硬件的某些输入来决定硬件块是否存在。因此,您需要实例化硬件一次,然后控制输入到它的内容:

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?
应该是这样的:

deci : decode port map (Instruction, op, rs, rd, rt);
iii)您确实应该在港口地图中使用命名关联。而不是:

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

iv)您的流程不适合合成顺序流程的任何模板:

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
以下是异步重置顺序过程的模板:

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;        
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;   
因此,
启用
不应该在您的敏感度列表中;流程的第一行应该是:

calc: process (Clock, RESET)
测试上升沿(时钟)
后,应测试
启用
信号:

您应该测试重置的绝对值,而不是寻找上升沿。你不需要所有的括号。我不是这样的:

    if (rising_edge(RESET)) then
这:

这条线是多余的:

elsif (Clock = '1') then
v) 您不应该测试时钟的两个边缘。这不是同步设计。不能在一个过程中同时测试两条边。这甚至不能合成。这需要:

    elsif (falling_edge(Clock)) then
vi)我担心您在过程的早期将
R0
驱动到
R3
,然后在以后使用它们的值。很难准确了解您的设计意图,但我怀疑这不会起作用:

在VHDL中,直到进程挂起,信号才会更新。如果您尝试使用进程中先前分配的信号,您将获得先前分配的值

概述

我建议你把你的设计分成许多小流程。对每种产品都有一个清晰的概念,即您希望为每种产品提供什么样的硬件。让每个模块执行特定的功能,例如将输入多路传输到
添加块
。例如,考虑:

  • 过程是顺序逻辑还是组合逻辑

  • 重置是异步的还是同步的

  • 输入是什么

  • 输出是什么

然后选择合适的模板。我已经给出了一个异步复位的顺序过程。以下是一个用于无异步重置的顺序过程:

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;        
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;   

正如@BrianDrummond所说的,你不能随意让硬件神奇地出现和消失。您无法根据硬件的某些输入来决定硬件块是否存在。因此,您需要实例化硬件一次,然后控制输入到它的内容:

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?
应该是这样的:

deci : decode port map (Instruction, op, rs, rd, rt);
iii)您确实应该在港口地图中使用命名关联。而不是:

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

iv)您的流程不适合合成顺序流程的任何模板:

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
以下是异步重置顺序过程的模板:

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;        
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;   
因此,
启用
不应该在您的敏感度列表中;流程的第一行应该是:

calc: process (Clock, RESET)
测试上升沿(时钟)后,应测试
启用
信号: