I'm attempting to model a control unit with a reduced instruction set in VHDL. I've been compiling a lot to ensure that the code still compile, but somewhere along the line, I must have done something wrong. After fleshing out the decode states for many of the instructions, I started getting the following set of errors.
我尝试用VHDL中的减少指令集来建模一个控制单元。我已经编译了很多代码以确保代码仍然被编译,但是在某些方面,我肯定做错了什么。在充实了许多指令的解码状态之后,我开始得到以下一组错误。
Error (10500): VHDL syntax error at controlunit.vhd(164) near text "when"; expecting "end", or "(", or an identifier ("when" is a reserved keyword), or a sequential statement
错误(10500):VHDL语法错误控制。vhd(164)接近文本“when”;期望得到“end”、“(”或标识符(“when”是保留的关键字)或顺序语句
Error (10500): VHDL syntax error at controlunit.vhd(176) near text "when"; expecting "end", or "(", or an identifier ("when" is a reserved keyword), or a sequential statement
错误(10500):VHDL语法错误在control .vhd(176)靠近文本“when”;期望得到“end”、“(”或标识符(“when”是保留的关键字)或顺序语句
Error (10500): VHDL syntax error at controlunit.vhd(183) near text "when"; expecting "end", or "(", or an identifier ("when" is a reserved keyword), or a sequential statement
错误(10500):控件的VHDL语法错误。期望得到“end”、“(”或标识符(“when”是保留的关键字)或顺序语句
Error (10500): VHDL syntax error at controlunit.vhd(190) near text "case"; expecting "if"
错误(10500):在control .vhd(190)靠近文本“case”的VHDL语法错误;期待“如果”
Error (10500): VHDL syntax error at controlunit.vhd(195) near text "Begin"; expecting ":=", or "<="
错误(10500):VHDL语法错误在control .vhd(195)靠近文本“Begin”;期待“:=”、“< =”
Error (10500): VHDL syntax error at controlunit.vhd(203) near text "process"; expecting "if"
错误(10500):VHDL语法错误。vhd(203)接近文本“进程”;期待“如果”
Error (10500): VHDL syntax error at controlunit.vhd(204) near text "behavior"; expecting "if"
错误(10500):VHDL语法错误控制。vhd(204)接近文本“行为”;期待“如果”
Normally, these kinds of errors would be well within my ability to fix, but I've gone through my code multiple time, and as far as I can tell, all of the process blocks and case statements are defined correctly.
通常,这些类型的错误在我的能力范围内是可以修复的,但是我已经多次检查了我的代码,并且据我所知,所有的进程块和case语句都被正确定义了。
I'm afraid that, since I'm rather new to VHDL, I might be missing some syntactic subtlety that I'd never spot on my own. Can any VHDL expert help me isolate the issue in my code? Thank you!
我担心,因为我对VHDL还不熟悉,所以我可能会漏掉一些语法上的微妙之处,这是我自己永远也不会发现的。VHDL专家能帮助我在代码中隔离这个问题吗?谢谢你!
You can find my code in the code block below.
您可以在下面的代码块中找到我的代码。
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity ControlUnit is
port(
clk: IN std_logic;
Mem_rd: OUT std_logic :='1'; --signal to read from RAM/ROM
Mem_wr: OUT std_logic :='1'; --signal to write RAM
Mem_cs: OUT std_logic :='1'; --signal to select either RAM or ROM
Z: IN std_logic; --zero signal from ALU
N: IN std_logic; --negative signal from ALU
R_we: OUT std_logic; --read/write enable signal to register file
ld_op: OUT std_logic; --bus control signal for memory load operations
st_op: OUT std_logic; --bus control signal for memory read operations
ctl_wd: OUT std_logic_vector(14 downto 0); --processor control word
const_out: OUT std_logic_vector(15 downto 0); --constant value from instruction
CU_addr_bus: INOUT std_logic_vector(15 downto 0); --processor address bus connection
CU_data_bus: INOUT std_logic_vector(15 downto 0); --processor data bus connection
run: IN std_logic; --signal allowing processor to execute its program
rst: IN std_logic --system reset signal
);
end ControlUnit;
architecture Behavior of ControlUnit is
-- Control Unit states for multi-cycle instruction execution
type states is (Reset, Fetch, Decode, Execute, WB);
signal CurrState, NextState : states;
-- Instruction set types
type ops is (nop, subx, orx, jmp, addx, andx, notx, srlx, sllx, ld, st, hlt, ret, addi, ba, bn, bz, sethi, call);
signal CurrOp, NextOp : ops;
-- Internal signal declarations
signal CurrPC, CurrSP, CurrIR, CurrDisp : std_logic_vector(15 downto 0);
signal NextPC, NextSP, NextIR, NextDisp : std_logic_vector(15 downto 0);
signal PCaEN, SPEN, PCdEN : std_logic;
signal currStatus, nextStatus : std_logic_vector(1 downto 0); --N & Z
begin
-- tri-state enables:
addr_bus <= CurrPC when PCaEN='1' else
CurrSP when SPEN='1' else
(others=>'Z');
data_bus <= CurrPC when PCdEN='1' else
(others => 'Z');
CombLogic : process(CurrState, run, CurrPC, CurrSP, CurrIR, CurrOp, data_bus)
begin
case CurrState is
when Reset => -------------------------RESET-------------------------
NextPC <= x"0080"; NextSP <= x"04FE";
NextIR <= x"0000"; NextOp <= nop;
NextStatus <= "00"; NextDisp <= x"0000";
PCaEN <= '1'; SPEN <= '0'; PCdEN <= '0'; -- setup fetch
mem_cs <= '0'; mem_rd <= '0'; mem_wr <= '1'; -- active low; setup fetch
if run = '0' then NextState <= Reset; -- active low run
else NextState <= Fetch;
end if;
when Fetch => -------------------------FETCH-------------------------
NextPC <= currPC; NextSP <= currSP;
NextIR <= data_bus; NextOp <= currOP;
PCaEN <= '1'; SPEN <= '0'; PCdEN <= '0';
mem_cs <= '0'; mem_rd <= '0'; mem_wr <= '1'; -- active low
R_we <= '0'; ctl_wd <= (others => '0'); const_out <= x"FFFF";
NextState <= Decode;
when Decode => ------------------------DECODE-------------------------
--fill in decode logic
if currIR(15) = '1' then NextOp <= call;
NextPC <= CurrPC+1; NextSP <= CurrSP; NextIR <= CurrIR; nextStatus <= currStatus; nextDisp <= currDisp;
PCaEN <= '0'; SPEN <= '0'; PCdEN <= '0'; -- store CurrPC to M[SP]
mem_cs <= '1'; mem_rd <= '1'; mem_wr <= '1';
R_we <= '0'; ctl_wd <= "0000"; const_out <= x"0000";
else if currIR(14) = '1' then
case currOP(10 downto 8) is
when "000" => NextOP <= hlt; --set signals for hlt
when "001" => NextOP <= ret; --set signals for ret
when "011" => NextOP <= addi; --set signals for addi
when "100" => NextOP <= ba; --set signals for ba
when "101" => NextOP <= bn; --set signals for bn
when "110" => NextOP <= bz; --set signals for bz
when "111" => NextOP <= sethi; --set signals for sethi
end case;
else
case currOP(10 downto 7) is
when "1010" => NextOP <= nop; --set signals for nop
NextPC <= CurrPC; NextSP <= CurrSP; NextIR <= CurrIR; nextStatus <= currStatus; nextDisp <= currDisp;
PCaEN <= '0'; SPEN <= '0'; PCdEN <= '0';
mem_cs <= '1'; mem_rd <= '1'; mem_wr <= '1';
R_we <= '0'; ctl_wd <= x"0000"; const_out <= x"0000";
when "1001" => NextOP <= subx; --set signals for subx
NextPC <= CurrPC; NextSP <= CurrSP; NextIR <= CurrIR; nextStatus <= currStatus; nextDisp <= currDisp;
PCaEN <= '0'; SPEN <= '0'; PCdEN <= '0';
mem_cs <= '1'; mem_rd <= '1'; mem_wr <= '1';
R_we <= '1'; ctl_wd <= currOP(14 downto 0)&'0'; const_out <= x"0000";
when "1000" => NextOP <= orx; --set signals for orx
NextPC <= CurrPC; NextSP <= CurrSP; NextIR <= CurrIR; nextStatus <= currStatus; nextDisp <= currDisp;
PCaEN <= '0'; SPEN <= '0'; PCdEN <= '0';
mem_cs <= '1'; mem_rd <= '1'; mem_wr <= '1';
R_we <= '1'; ctl_wd <= currOP(14 downto 0)&'0'; const_out <= x"0000";
when "0111" => NextOP <= jmp; --set signals for jmp
NextPC <= CurrPCL; NextSP <= CurrSP; NextIR <= CurrIR; nextStatus <= currStatus; nextDisp <= currDisp;
PCaEN <= '0'; SPEN <= '0'; PCdEN <= '0';
mem_cs <= '1'; mem_rd <= '1'; mem_wr <= '1';
R_we <= '0'; ctl_wd <= currOP(14 downto 0)&'0'; const_out <= x"0000";
when "0110" => NextOP <= addx; --set signals for addx
NextPC <= CurrPC; NextSP <= CurrSP; NextIR <= CurrIR; nextStatus <= currStatus; nextDisp <= currDisp;
PCaEN <= '0'; SPEN <= '0'; PCdEN <= '0';
mem_cs <= '1'; mem_rd <= '1'; mem_wr <= '1';
R_we <= '1'; ctl_wd <= currOP(14 downto 0)&'0'; const_out <= x"0000";
when "0101" => NextOP <= andx; --set signals for andx
NextPC <= CurrPC; NextSP <= CurrSP; NextIR <= CurrIR; nextStatus <= currStatus; nextDisp <= currDisp;
PCaEN <= '0'; SPEN <= '0'; PCdEN <= '0';
mem_cs <= '1'; mem_rd <= '1'; mem_wr <= '1';
R_we <= '1'; ctl_wd <= currOP(14 downto 0)&'0'; const_out <= x"0000";
when "0100" => NextOP <= notx; --set signals for notx
NextPC <= CurrPC; NextSP <= CurrSP; NextIR <= CurrIR; nextStatus <= currStatus; nextDisp <= currDisp;
PCaEN <= '0'; SPEN <= '0'; PCdEN <= '0';
mem_cs <= '1'; mem_rd <= '1'; mem_wr <= '1';
R_we <= '1'; ctl_wd <= currOP(14 downto 0)&'0'; const_out <= x"0000";
when "0011" => NextOP <= srlx; --set signals for srlx
NextPC <= CurrPC; NextSP <= CurrSP; NextIR <= CurrIR; nextStatus <= currStatus; nextDisp <= currDisp;
PCaEN <= '0'; SPEN <= '0'; PCdEN <= '0';
mem_cs <= '1'; mem_rd <= '1'; mem_wr <= '1';
R_we <= '1'; ctl_wd <= currOP(14 downto 0)&'0'; const_out <= x"0000";
when "0010" => NextOP <= sllx; --set signals for sllx
NextPC <= CurrPC; NextSP <= CurrSP; NextIR <= CurrIR; nextStatus <= currStatus; nextDisp <= currDisp;
PCaEN <= '0'; SPEN <= '0'; PCdEN <= '0';
mem_cs <= '1'; mem_rd <= '1'; mem_wr <= '1';
R_we <= '1'; ctl_wd <= currOP(14 downto 0)&'0'; const_out <= x"0000";
when "0001" => NextOP <= ld; --set signals for ld
NextPC <= CurrPC; NextSP <= CurrSP; NextIR <= CurrIR; nextStatus <= currStatus; nextDisp <= currDisp;
PCaEN <= '0'; SPEN <= '0'; PCdEN <= '0';
mem_cs <= '0'; mem_rd <= '0'; mem_wr <= '1';
R_we <= '1'; ctl_wd <= currOP(14 downto 0)&'0'; const_out <= x"0000";
when "0000" => NextOP <= st; --set signals for st
NextPC <= CurrPC; NextSP <= CurrSP; NextIR <= CurrIR; nextStatus <= currStatus; nextDisp <= currDisp;
PCaEN <= '0'; SPEN <= '0'; PCdEN <= '0';
mem_cs <= '0'; mem_rd <= '1'; mem_wr <= '0';
R_we <= '0'; ctl_wd <= currOP(14 downto 0)&'0'; const_out <= x"0000";
end case;
end if;
NextState <= Execute;
when Execute => -------------------------EXECUTE-------------------------
case CurrOp is
when call => --call
NextPC <= CurrPC+1; NextSP <= CurrSP; NextIR <= CurrIR; nextStatus <= currStatus; nextDisp <= currDisp;
PCaEN <= '0'; SPEN <= '1'; PCdEN <= '1'; -- store CurrPC to M[SP]
mem_cs <= '0'; mem_rd <= '1'; mem_wr <= '0';
R_we <= '0'; ctl_wd <= "0000"; const_out <= x"0000";
--for bn and bz, execution of operation is dependent on signals N and Z
when others => null;
end case;
NextState <= WB;
when WB => -------------------------WB-------------------------
NextPC <= '0'&currIR(6 downto 0); NextSP <= CurrSP - 1; NextIR <= CurrIR; NextOp <= CurrOp;
PCaEN <= '0'; SPEN <= '0'; PCdEN <= '0'; -- setup fetch
mem_cs <= '1'; mem_rd <= '1'; mem_wr <= '1'; -- active low; setup fetch
R_we <= '0'; ctl_wd <= "0000"; const_out <= x"0000";
NextState <= Fetch;
when others => -------------------------OTHERS-------------------------
-- Should never be in this state!
NextPC <= x"00"; NextSP <= x"00"; NextIR <= x"00"; NextOp <= call;
PCaEN <= '0'; SPEN <= '0'; PCdEN <= '0';
mem_cs <= '1'; mem_rd <= '1'; mem_wr <= '1'; -- active low
R_we <= '0'; ctl_wd <= "00"; const_out <= x"FF";
NextState <= Reset;
end case;
end process;
-- Sequential Logic (asynchronous reset; registers update at positive-edge clock)
Regs : process(clk,rst)
Begin
if rst = '0' then CurrState <= Reset; -- Active Low Reset
CurrOp <= sethi; CurrPC <= x"80"; CurrSP <= x"FF"; CurrIR <= (others=>'0');
CurrStatus <= "00";
elsif (rising_edge(clk)) then CurrState <= NextState;
CurrOp <= NextOp; CurrPC <= NextPC; CurrSP <= NextSP; CurrIR <= NextIR;
CurrStatus <= NextStatus;
end if;
end process Regs;
end behavior;
1 个解决方案
#1
1
-- Instruction set types
type ops is (nop, subx, orx, jmp, addx, andx, notx, srlx, sllx, ld, st, hlt, ret, addi, ba, bn, bz, sethi, call);
signal CurrOp, NextOp : ops;
For example CurrOp
is an enumerated type with values shown as ops enumerations. Yet you have slices of CurrOp
:
例如,CurrOp是一个枚举类型,其值显示为操作枚举。但你有片片凝乳:
case currOP(10 downto 8) is
case currOP(10 downto 7) is
And your when
expressions for the case statements are string literals respectively with a length of 3 or 4.
而case语句的when表达式分别是长度为3或4的字符串常量。
So CurrOp isn't an array type you can't slice it and compare it to strings.
所以CurrOp不是数组类型你不能将它切片并与字符串进行比较。
Now why analysis get's this far is without telling you this is entertaining. The expression is being evaluated at elaboration time and not analysis time unlike say the target of a signal assignment:
现在,为什么分析得出这个结论,而不是告诉你这很有趣。表达式在精化时进行评估,而不是分析时,不像信号分配的目标:
library ieee;
use ieee.std_logic_1164.all;
entity foo is
end entity;
architecture fum of foo is
-- Instruction set types
type ops is (nop, subx, orx, jmp, addx, andx, notx, srlx, sllx, ld, st, hlt, ret, addi, ba, bn, bz, sethi, call);
signal CurrOp, NextOp: ops;
begin
CurrOp(10 downto 7) <= "1001";
NextOp(10 downto 8) <= "011";
end architecture;
ghdl -a foo.vhdl foo.vhdl:13:11: type of prefix is not an array
foo.vhdl:14:11: type of prefix is not an array
ghdl: compilation errorghdl——foo。硬件描述语言(vhdl)foo。前缀类型不是数组foo。vhdl:14:11:前缀的类型不是数组ghdl:编译错误。
(-a is the ghdl analysis command)
(-a是ghdl分析命令)
Effectively a choice can only be an ops enumeration value. To make it more palatable you're allowed choices:
实际上,一个选项只能是一个ops枚举值。为了让它更美味,你可以选择:
choices ::= choice { | choice }
选择:=选择{|选择}
You can also assign the default for all the signals you are guaranteed to assign in a choice right before a case statement then assign only those with different values in each case statement alternative. In the same simulation delta only the last assignment will be scheduled (there's only one future event).
您还可以为在case语句之前指定的所有信号分配默认值,然后在每个case语句中只分配具有不同值的值。在相同的模拟增量中,只有最后一个任务将被调度(只有一个未来事件)。
Along with a plethora of errors, the major thing stopping the further analysis was an else if
where and `else was appropriate.
除了大量的错误之外,阻止进一步分析的主要因素是“如果”和“其他”是否合适的话。
A found lots or errors while trouble shooting, you'd want to compare these for the same syntactical position in your file:
A发现了很多错误,在解决问题的时候,你应该将它们与文件中相同的语法位置进行比较:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
-- use IEEE.STD_LOGIC_UNSIGNED.all;
use ieee.numeric_std.all;
entity ControlUnit is
port(
clk: IN std_logic;
Mem_rd: OUT std_logic :='1'; --signal to read from RAM/ROM
Mem_wr: OUT std_logic :='1'; --signal to write RAM
Mem_cs: OUT std_logic :='1'; --signal to select either RAM or ROM
Z: IN std_logic; --zero signal from ALU
N: IN std_logic; --negative signal from ALU
R_we: OUT std_logic; --read/write enable signal to register file
ld_op: OUT std_logic; --bus control signal for memory load operations
st_op: OUT std_logic; --bus control signal for memory read operations
ctl_wd: OUT std_logic_vector(14 downto 0); --processor control word
const_out: OUT std_logic_vector(15 downto 0); --constant value from instruction
CU_addr_bus: INOUT std_logic_vector(15 downto 0); --processor address bus connection
CU_data_bus: INOUT std_logic_vector(15 downto 0); --processor data bus connection
run: IN std_logic; --signal allowing processor to execute its program
rst: IN std_logic --system reset signal
);
end ControlUnit;
architecture Behavior of ControlUnit is
-- Control Unit states for multi-cycle instruction execution
type states is (Reset, Fetch, Decode, Execute, WB);
signal CurrState, NextState : states;
-- Instruction set types
type ops is (nop, subx, orx, jmp, addx, andx, notx, srlx, sllx, ld, st, hlt, ret, addi, ba, bn, bz, sethi, call);
signal CurrOp, NextOp : ops;
-- Internal signal declarations
signal CurrPC, CurrSP, CurrIR, CurrDisp : std_logic_vector(15 downto 0);
signal NextPC, NextSP, NextIR, NextDisp : std_logic_vector(15 downto 0);
signal PCaEN, SPEN, PCdEN : std_logic;
signal currStatus, nextStatus : std_logic_vector(1 downto 0); --N & Z
begin
-- tri-state enables:
CU_addr_bus <= CurrPC when PCaEN='1' else
CurrSP when SPEN='1' else
(others=>'Z');
CU_data_bus <= CurrPC when PCdEN='1' else
(others => 'Z');
CombLogic : process(CurrState, run, CurrPC, CurrSP, CurrIR, CurrOp, CU_data_bus)
begin
case CurrState is
when Reset => -------------------------RESET-------------------------
NextPC <= x"0080";
NextSP <= x"04FE";
NextIR <= x"0000";
NextOp <= nop;
NextStatus <= "00";
NextDisp <= x"0000";
PCaEN <= '1';
SPEN <= '0';
PCdEN <= '0'; -- setup fetch
mem_cs <= '0';
mem_rd <= '0';
mem_wr <= '1'; -- active low; setup fetch
if run = '0' then NextState <= Reset; -- active low run
else NextState <= Fetch;
end if;
when Fetch => -------------------------FETCH-------------------------
NextPC <= currPC;
NextSP <= currSP;
NextIR <= CU_data_bus;
NextOp <= currOP;
PCaEN <= '1';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '0';
mem_rd <= '0';
mem_wr <= '1'; -- active low
R_we <= '0';
ctl_wd <= (others => '0');
const_out <= x"FFFF";
NextState <= Decode;
when Decode => ------------------------DECODE-------------------------
--fill in decode logic
if currIR(15) = '1' then
NextOp <= call;
NextPC <= std_logic_vector (unsigned(CurrPC) + 1);
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0'; -- store CurrPC to M[SP]
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '0';
ctl_wd <= (others => '0');
const_out <= x"0000";
elsif currIR(14) = '1' then
case currIR(10 downto 8) is
when "000" => NextOP <= hlt; --set signals for hlt
when "001" => NextOP <= ret; --set signals for ret
when "011" => NextOP <= addi; --set signals for addi
when "100" => NextOP <= ba; --set signals for ba
when "101" => NextOP <= bn; --set signals for bn
when "110" => NextOP <= bz; --set signals for bz
when "111" => NextOP <= sethi; --set signals for sethi
when others => NextOp <= nop;
end case;
else
case currIR(10 downto 7) is
when "1010" =>
NextOP <= nop; --set signals for nop
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '0';
ctl_wd <= (others => '0');
const_out <= x"0000";
when "1001" =>
NextOP <= subx; --set signals for subx
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '1';
ctl_wd <= currIR(14 downto 0) & '0';
const_out <= x"0000";
when "1000" =>
NextOP <= orx; --set signals for orx
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '1';
ctl_wd <= currIR(14 downto 0) & '0';
const_out <= x"0000";
when "0111" =>
NextOP <= jmp; --set signals for jmp
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '0';
ctl_wd <= currIR(14 downto 0) & '0';
const_out <= x"0000";
when "0110" =>
NextOP <= addx; --set signals for addx
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '1';
ctl_wd <= currIR(14 downto 0) & '0';
const_out <= x"0000";
when "0101" =>
NextOP <= andx; --set signals for andx
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '1';
ctl_wd <= currIR(14 downto 0) & '0';
const_out <= x"0000";
when "0100" =>
NextOP <= notx; --set signals for notx
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '1';
ctl_wd <= currIR(14 downto 0) & '0';
const_out <= x"0000";
when "0011" =>
NextOP <= srlx; --set signals for srlx
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '1';
ctl_wd <= currIR(14 downto 0) & '0';
const_out <= x"0000";
when "0010" =>
NextOP <= sllx; --set signals for sllx
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '1';
ctl_wd <= currIR(14 downto 0) & '0';
const_out <= x"0000";
when "0001" =>
NextOP <= ld; --set signals for ld
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '0';
mem_rd <= '0';
mem_wr <= '1';
R_we <= '1';
ctl_wd <= currIR(14 downto 0)&'0';
const_out <= x"0000";
when "0000" =>
NextOP <= st; --set signals for st
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '0';
mem_rd <= '1';
mem_wr <= '0';
R_we <= '0';
ctl_wd <= currIR(14 downto 0) & '0';
const_out <= x"0000";
when others =>
NextOP <= nop; --set signals for nop
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '0';
ctl_wd <= (others => '0');
const_out <= x"0000";
end case;
end if;
NextState <= Execute;
when Execute => -------------------------EXECUTE-------------------------
case CurrOp is
when call => --call
NextPC <= std_logic_vector( unsigned (CurrPC) + 1);
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '1';
PCdEN <= '1'; -- store CurrPC to M[SP]
mem_cs <= '0';
mem_rd <= '1';
mem_wr <= '0';
R_we <= '0';
ctl_wd <= (others => '0');
const_out <= x"0000";
--for bn and bz, execution of operation is dependent on signals N and Z
when others => null;
end case;
NextState <= WB;
when WB => -------------------------WB-------------------------
NextPC <= '0' & currIR(6 downto 0);
NextSP <= std_logic_vector(unsigned(CurrSP) - 1);
NextIR <= CurrIR;
NextOp <= CurrOp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0'; -- setup fetch
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1'; -- active low; setup fetch
R_we <= '0';
ctl_wd <= (others => '0'); -- "0000";
const_out <= x"0000";
NextState <= Fetch;
-- when others => -------------------------OTHERS-------------------------
-- -- Should never be in this state!
-- NextPC <= x"00"; NextSP <= x"00"; NextIR <= x"00"; NextOp <= call;
-- PCaEN <= '0'; SPEN <= '0'; PCdEN <= '0';
-- mem_cs <= '1'; mem_rd <= '1'; mem_wr <= '1'; -- active low
-- R_we <= '0'; ctl_wd <= "00"; const_out <= x"FF";
-- NextState <= Reset;
end case;
end process;
-- Sequential Logic (asynchronous reset; registers update at positive-edge clock)
Regs : process(clk,rst)
Begin
if rst = '0' then CurrState <= Reset; -- Active Low Reset
CurrOp <= sethi;
CurrPC <= x"0080";
CurrSP <= x"FFFE";
CurrIR <= (others=>'0');
CurrStatus <= "00";
elsif (rising_edge(clk)) then CurrState <= NextState;
CurrOp <= NextOp;
CurrPC <= NextPC;
CurrSP <= NextSP;
CurrIR <= NextIR;
CurrStatus <= NextStatus;
end if;
end process Regs;
end behavior;
#1
1
-- Instruction set types
type ops is (nop, subx, orx, jmp, addx, andx, notx, srlx, sllx, ld, st, hlt, ret, addi, ba, bn, bz, sethi, call);
signal CurrOp, NextOp : ops;
For example CurrOp
is an enumerated type with values shown as ops enumerations. Yet you have slices of CurrOp
:
例如,CurrOp是一个枚举类型,其值显示为操作枚举。但你有片片凝乳:
case currOP(10 downto 8) is
case currOP(10 downto 7) is
And your when
expressions for the case statements are string literals respectively with a length of 3 or 4.
而case语句的when表达式分别是长度为3或4的字符串常量。
So CurrOp isn't an array type you can't slice it and compare it to strings.
所以CurrOp不是数组类型你不能将它切片并与字符串进行比较。
Now why analysis get's this far is without telling you this is entertaining. The expression is being evaluated at elaboration time and not analysis time unlike say the target of a signal assignment:
现在,为什么分析得出这个结论,而不是告诉你这很有趣。表达式在精化时进行评估,而不是分析时,不像信号分配的目标:
library ieee;
use ieee.std_logic_1164.all;
entity foo is
end entity;
architecture fum of foo is
-- Instruction set types
type ops is (nop, subx, orx, jmp, addx, andx, notx, srlx, sllx, ld, st, hlt, ret, addi, ba, bn, bz, sethi, call);
signal CurrOp, NextOp: ops;
begin
CurrOp(10 downto 7) <= "1001";
NextOp(10 downto 8) <= "011";
end architecture;
ghdl -a foo.vhdl foo.vhdl:13:11: type of prefix is not an array
foo.vhdl:14:11: type of prefix is not an array
ghdl: compilation errorghdl——foo。硬件描述语言(vhdl)foo。前缀类型不是数组foo。vhdl:14:11:前缀的类型不是数组ghdl:编译错误。
(-a is the ghdl analysis command)
(-a是ghdl分析命令)
Effectively a choice can only be an ops enumeration value. To make it more palatable you're allowed choices:
实际上,一个选项只能是一个ops枚举值。为了让它更美味,你可以选择:
choices ::= choice { | choice }
选择:=选择{|选择}
You can also assign the default for all the signals you are guaranteed to assign in a choice right before a case statement then assign only those with different values in each case statement alternative. In the same simulation delta only the last assignment will be scheduled (there's only one future event).
您还可以为在case语句之前指定的所有信号分配默认值,然后在每个case语句中只分配具有不同值的值。在相同的模拟增量中,只有最后一个任务将被调度(只有一个未来事件)。
Along with a plethora of errors, the major thing stopping the further analysis was an else if
where and `else was appropriate.
除了大量的错误之外,阻止进一步分析的主要因素是“如果”和“其他”是否合适的话。
A found lots or errors while trouble shooting, you'd want to compare these for the same syntactical position in your file:
A发现了很多错误,在解决问题的时候,你应该将它们与文件中相同的语法位置进行比较:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
-- use IEEE.STD_LOGIC_UNSIGNED.all;
use ieee.numeric_std.all;
entity ControlUnit is
port(
clk: IN std_logic;
Mem_rd: OUT std_logic :='1'; --signal to read from RAM/ROM
Mem_wr: OUT std_logic :='1'; --signal to write RAM
Mem_cs: OUT std_logic :='1'; --signal to select either RAM or ROM
Z: IN std_logic; --zero signal from ALU
N: IN std_logic; --negative signal from ALU
R_we: OUT std_logic; --read/write enable signal to register file
ld_op: OUT std_logic; --bus control signal for memory load operations
st_op: OUT std_logic; --bus control signal for memory read operations
ctl_wd: OUT std_logic_vector(14 downto 0); --processor control word
const_out: OUT std_logic_vector(15 downto 0); --constant value from instruction
CU_addr_bus: INOUT std_logic_vector(15 downto 0); --processor address bus connection
CU_data_bus: INOUT std_logic_vector(15 downto 0); --processor data bus connection
run: IN std_logic; --signal allowing processor to execute its program
rst: IN std_logic --system reset signal
);
end ControlUnit;
architecture Behavior of ControlUnit is
-- Control Unit states for multi-cycle instruction execution
type states is (Reset, Fetch, Decode, Execute, WB);
signal CurrState, NextState : states;
-- Instruction set types
type ops is (nop, subx, orx, jmp, addx, andx, notx, srlx, sllx, ld, st, hlt, ret, addi, ba, bn, bz, sethi, call);
signal CurrOp, NextOp : ops;
-- Internal signal declarations
signal CurrPC, CurrSP, CurrIR, CurrDisp : std_logic_vector(15 downto 0);
signal NextPC, NextSP, NextIR, NextDisp : std_logic_vector(15 downto 0);
signal PCaEN, SPEN, PCdEN : std_logic;
signal currStatus, nextStatus : std_logic_vector(1 downto 0); --N & Z
begin
-- tri-state enables:
CU_addr_bus <= CurrPC when PCaEN='1' else
CurrSP when SPEN='1' else
(others=>'Z');
CU_data_bus <= CurrPC when PCdEN='1' else
(others => 'Z');
CombLogic : process(CurrState, run, CurrPC, CurrSP, CurrIR, CurrOp, CU_data_bus)
begin
case CurrState is
when Reset => -------------------------RESET-------------------------
NextPC <= x"0080";
NextSP <= x"04FE";
NextIR <= x"0000";
NextOp <= nop;
NextStatus <= "00";
NextDisp <= x"0000";
PCaEN <= '1';
SPEN <= '0';
PCdEN <= '0'; -- setup fetch
mem_cs <= '0';
mem_rd <= '0';
mem_wr <= '1'; -- active low; setup fetch
if run = '0' then NextState <= Reset; -- active low run
else NextState <= Fetch;
end if;
when Fetch => -------------------------FETCH-------------------------
NextPC <= currPC;
NextSP <= currSP;
NextIR <= CU_data_bus;
NextOp <= currOP;
PCaEN <= '1';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '0';
mem_rd <= '0';
mem_wr <= '1'; -- active low
R_we <= '0';
ctl_wd <= (others => '0');
const_out <= x"FFFF";
NextState <= Decode;
when Decode => ------------------------DECODE-------------------------
--fill in decode logic
if currIR(15) = '1' then
NextOp <= call;
NextPC <= std_logic_vector (unsigned(CurrPC) + 1);
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0'; -- store CurrPC to M[SP]
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '0';
ctl_wd <= (others => '0');
const_out <= x"0000";
elsif currIR(14) = '1' then
case currIR(10 downto 8) is
when "000" => NextOP <= hlt; --set signals for hlt
when "001" => NextOP <= ret; --set signals for ret
when "011" => NextOP <= addi; --set signals for addi
when "100" => NextOP <= ba; --set signals for ba
when "101" => NextOP <= bn; --set signals for bn
when "110" => NextOP <= bz; --set signals for bz
when "111" => NextOP <= sethi; --set signals for sethi
when others => NextOp <= nop;
end case;
else
case currIR(10 downto 7) is
when "1010" =>
NextOP <= nop; --set signals for nop
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '0';
ctl_wd <= (others => '0');
const_out <= x"0000";
when "1001" =>
NextOP <= subx; --set signals for subx
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '1';
ctl_wd <= currIR(14 downto 0) & '0';
const_out <= x"0000";
when "1000" =>
NextOP <= orx; --set signals for orx
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '1';
ctl_wd <= currIR(14 downto 0) & '0';
const_out <= x"0000";
when "0111" =>
NextOP <= jmp; --set signals for jmp
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '0';
ctl_wd <= currIR(14 downto 0) & '0';
const_out <= x"0000";
when "0110" =>
NextOP <= addx; --set signals for addx
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '1';
ctl_wd <= currIR(14 downto 0) & '0';
const_out <= x"0000";
when "0101" =>
NextOP <= andx; --set signals for andx
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '1';
ctl_wd <= currIR(14 downto 0) & '0';
const_out <= x"0000";
when "0100" =>
NextOP <= notx; --set signals for notx
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '1';
ctl_wd <= currIR(14 downto 0) & '0';
const_out <= x"0000";
when "0011" =>
NextOP <= srlx; --set signals for srlx
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '1';
ctl_wd <= currIR(14 downto 0) & '0';
const_out <= x"0000";
when "0010" =>
NextOP <= sllx; --set signals for sllx
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '1';
ctl_wd <= currIR(14 downto 0) & '0';
const_out <= x"0000";
when "0001" =>
NextOP <= ld; --set signals for ld
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '0';
mem_rd <= '0';
mem_wr <= '1';
R_we <= '1';
ctl_wd <= currIR(14 downto 0)&'0';
const_out <= x"0000";
when "0000" =>
NextOP <= st; --set signals for st
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '0';
mem_rd <= '1';
mem_wr <= '0';
R_we <= '0';
ctl_wd <= currIR(14 downto 0) & '0';
const_out <= x"0000";
when others =>
NextOP <= nop; --set signals for nop
NextPC <= CurrPC;
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0';
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1';
R_we <= '0';
ctl_wd <= (others => '0');
const_out <= x"0000";
end case;
end if;
NextState <= Execute;
when Execute => -------------------------EXECUTE-------------------------
case CurrOp is
when call => --call
NextPC <= std_logic_vector( unsigned (CurrPC) + 1);
NextSP <= CurrSP;
NextIR <= CurrIR;
nextStatus <= currStatus;
nextDisp <= currDisp;
PCaEN <= '0';
SPEN <= '1';
PCdEN <= '1'; -- store CurrPC to M[SP]
mem_cs <= '0';
mem_rd <= '1';
mem_wr <= '0';
R_we <= '0';
ctl_wd <= (others => '0');
const_out <= x"0000";
--for bn and bz, execution of operation is dependent on signals N and Z
when others => null;
end case;
NextState <= WB;
when WB => -------------------------WB-------------------------
NextPC <= '0' & currIR(6 downto 0);
NextSP <= std_logic_vector(unsigned(CurrSP) - 1);
NextIR <= CurrIR;
NextOp <= CurrOp;
PCaEN <= '0';
SPEN <= '0';
PCdEN <= '0'; -- setup fetch
mem_cs <= '1';
mem_rd <= '1';
mem_wr <= '1'; -- active low; setup fetch
R_we <= '0';
ctl_wd <= (others => '0'); -- "0000";
const_out <= x"0000";
NextState <= Fetch;
-- when others => -------------------------OTHERS-------------------------
-- -- Should never be in this state!
-- NextPC <= x"00"; NextSP <= x"00"; NextIR <= x"00"; NextOp <= call;
-- PCaEN <= '0'; SPEN <= '0'; PCdEN <= '0';
-- mem_cs <= '1'; mem_rd <= '1'; mem_wr <= '1'; -- active low
-- R_we <= '0'; ctl_wd <= "00"; const_out <= x"FF";
-- NextState <= Reset;
end case;
end process;
-- Sequential Logic (asynchronous reset; registers update at positive-edge clock)
Regs : process(clk,rst)
Begin
if rst = '0' then CurrState <= Reset; -- Active Low Reset
CurrOp <= sethi;
CurrPC <= x"0080";
CurrSP <= x"FFFE";
CurrIR <= (others=>'0');
CurrStatus <= "00";
elsif (rising_edge(clk)) then CurrState <= NextState;
CurrOp <= NextOp;
CurrPC <= NextPC;
CurrSP <= NextSP;
CurrIR <= NextIR;
CurrStatus <= NextStatus;
end if;
end process Regs;
end behavior;