Мы строим процессор для нашего финального проекта.Блок управления является конечным автоматом, но, похоже, он застревает в состояниях дольше, чем должен, и поэтому он повторяет инструкции.
Мы используем Vivado 2015.4 и плату Nexys4.
Таким образом, с одной строкой инструкций для сохранения значения в 7 сегментах, загруженных в память инструкций, выполняются следующие состояния:
Fetch =>
Fetch =>
Fetch =>
L_S_D (Load/Store Decode) =>
L_S_E (Load/Store Execute) =>
S_Mem (Store Memory Access) =>
Fetch =>
L_S_D =>
L_S_E =>
S_Mem =>
Fetch =>
L_S_D =>
L_S_E =>
Fetch (forever)
На двух полных прогонах отображается семь сегментов,На третьем, неполном прогоне они не выполняются.
Я присоединяю конечный автомат (соответствующие состояния) и код, связанный с программным счетчиком, потому что я думаю, что именно в этом проблема.
Конечный автомат:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Fred is
Port ( Inst : in STD_LOGIC_vector (31 downto 21);
clk : in std_logic;
rst : in std_logic;
Reg2Loc : out std_logic;
ALUSRC : out std_logic;
MemtoReg : out std_logic;
RegWrite : out std_logic;
Branch : out std_logic;
ALUOp : out std_logic_vector (1 downto 0);
UnconB : out std_logic;
en : out std_logic;
wea : out std_logic;
PCWrite : out std_logic;
REGCEA : out std_logic;
LEDCode : out std_logic_vector (4 downto 0));
end Fred;
architecture Behavioral of Fred is
Type type_fstate is (Fetch, L_S_D, L_S_E, L_Mem, S_Mem,
L_WB, R_I_D, I_E, R_E, I_WB, R_WB, B_E, CBZ_D, B_WB, CBZ_E,
CBZ_WB);
attribute enum_encoding : string;
attribute enum_encoding of type_fstate : type is "one-hot";
signal current_state : type_fstate;
signal next_state : type_fstate;
begin
clockprocess : process (clk, rst, current_state)
begin
if rst = '1' then
next_state <= Fetch;
elsif clk'EVENT and clk = '1' then
next_state <= current_state;
end if;
end process clockprocess;
state_logic: process (next_state)
begin
case next_state is
when Fetch => --00001
if ((Inst = "11111000010")) then --LDUR
current_state <= L_S_D;
elsif ((Inst = "11111000000")) then --STUR
current_state <= L_S_D;
--Additional State Logic Here
else
current_state <= Fetch;
end if;
when L_S_D => --00010
current_state <= L_S_E;
when L_S_E => --00011
if ((Inst = "11111000010")) then
current_state <= L_Mem;
elsif ((Inst = "11111000000")) then
current_state <= S_Mem;
end if;
when S_Mem => --00110
current_state <= Fetch;
--Additional States Here
when others =>
current_state <= Fetch;
end case;
end process state_logic;
output_logic : process (next_state)
begin
case next_state is
when Fetch =>
Reg2Loc <= '0';
ALUSRC <= '0';
MemtoReg <= '0';
RegWrite <= '0';
Branch <= '0';
ALUOp <= "00";
UnconB <= '0';
en <= '0';
wea <= '0';
PCWrite <= '0';
REGCEA <= '1';
LEDCode <= "00001";
when L_S_D =>
Reg2Loc <= '1';
ALUSRC <= '0';
MemtoReg <= '0';
RegWrite <= '0';
Branch <= '0';
ALUOp <= "00";
UnconB <= '0';
en <= '0';
wea <= '0';
PCWrite <= '0';
REGCEA <= '0';
LEDCode <= "00010";
when L_S_E =>
Reg2Loc <= '1';
ALUSRC <= '1';
MemtoReg <= '0';
RegWrite <= '0';
Branch <= '0';
ALUOp <= "00";
UnconB <= '0';
en <= '0';
wea <= '0';
PCWrite <= '1';
REGCEA <= '0';
LEDCode <= "00011";
when S_Mem =>
Reg2Loc <= '1';
ALUSRC <= '1';
MemtoReg <= '0';
RegWrite <= '0';
Branch <= '0';
ALUOp <= "00";
UnconB <= '0';
en <= '1';
wea <= '1';
PCWrite <= '0';
REGCEA <= '0';
LEDCode <= "00110";
--Additional State Outputs Here
when others =>
Reg2Loc <= '0';
ALUSRC <= '0';
MemtoReg <= '0';
RegWrite <= '0';
Branch <= '0';
ALUOp <= "00";
UnconB <= '0';
en <= '0';
wea <= '0';
PCWrite <= '0';
REGCEA <= '0';
LEDCode <= "00000";
end case;
end process output_logic;
end Behavioral;
Путь к данным:
entity Datapath is
Port (BTNClock : in STD_LOGIC;
clock : in STD_LOGIC;
UncondBranch : in STD_LOGIC;
CondBranch : in STD_LOGIC;
RRtwoSelect : in STD_LOGIC;
RegWriteSelect : in STD_LOGIC;
ALUSource : in STD_LOGIC;
ALUOpCode : in STD_LOGIC_VECTOR(1 downto 0);
WriteSelect : in STD_LOGIC;
MemWrite : in STD_LOGIC;
REGCEA : in STD_LOGIC;
PCWrite : in STD_LOGIC;
seg_select : out STD_LOGIC_vector(6 downto 0);
anode_select : out STD_LOGIC_vector(7 downto 0);
ins_out : out STD_LOGIC_VECTOR(31 downto 0);
RAMSelect : in STD_LOGIC;
ALUEleven : out STD_LOGIC;
REGEleven : out STD_LOGIC;
SwitchReset : in STD_LOGIC);
end Datapath;
architecture Behavioral of Datapath is
signal PC : STD_LOGIC_VECTOR(9 downto 0);
signal instruction : STD_LOGIC_VECTOR(31 downto 0);
signal BranchSelect : STD_LOGIC;
signal ZeroBranch : STD_LOGIC;
signal RRtwo : STD_LOGIC_VECTOR(4 downto 0);
signal RegDataOut1 : STD_LOGIC_VECTOR(63 downto 0);
signal RegDataOut2 : STD_LOGIC_VECTOR(63 downto 0);
signal ALUMuxOut : STD_LOGIC_VECTOR(63 downto 0);
signal SignExtendOut : STD_LOGIC_VECTOR(63 downto 0);
signal BranchExtend : STD_LOGIC_VECTOR(9 downto 0);
signal ALUOut : STD_LOGIC_VECTOR(63 downto 0);
signal ALUZero : STD_LOGIC;
signal MemoryOut : STD_LOGIC_VECTOR(63 downto 0);
signal WriteMuxOut : STD_LOGIC_VECTOR(63 downto 0);
signal Branch : STD_LOGIC_VECTOR(9 downto 0);
signal PCNext : STD_LOGIC_VECTOR(9 downto 0);
signal PCIncrement : STD_LOGIC_VECTOR(9 downto 0);
signal ALUCommand : STD_LOGIC_VECTOR(3 downto 0);
signal InstEn : STD_LOGIC := '1';
signal OnlySeven : STD_LOGIC_VECTOR(0 downto 0);
signal SevSegReset : STD_LOGIC := '0';
begin
OnlySeven(0) <= MemWrite and not ALUOut(11);
BranchSelect <= UncondBranch or ZeroBranch;
ZeroBranch <= CondBranch and ALUZero;
ins_out <= instruction;
ALUEleven <= ALUout(11);
REGEleven <= RegDataOut1(11);
--Program Counter
PCReg : PCounter port map ( clk => BTNClock,
wea => PCWrite,
newaddress => PCNext,
thisaddress => PC);
--Incremental adder
IncAddr : B_adder port map ( a => PC,
x => PCIncrement);
--Branch Adder
BranchAddr : In_adder port map ( a => PC,
b => BranchExtend,
x => Branch);
--Next Instruction Address Mux
NextPCMux : nine_mux port map ( s => BranchSelect,
in1 => PCIncrement,
in2 => Branch,
output => PCNext);
--Additional Datapath Elements Here
end Behavioral;
Счетчик программ:
entity PCounter is
Port ( clk : in STD_LOGIC; --clock
wea : in STD_LOGIC; --write enable
newaddress : in STD_LOGIC_VECTOR (9 downto 0); --new address coming in
thisaddress : out STD_LOGIC_VECTOR (9 downto 0) --current address to be executed
);
end PCounter;
architecture Behavioral of PCounter is
signal reg: std_logic_vector(9 downto 0); --internal register storage
begin
process(clk) --nothing happens if this register isn't selected
begin
if clk'EVENT and clk = '1' then
thisaddress <= reg; --send out currently saved address
if wea = '1' then
reg <= newaddress; --and set register to next address
end if;
else
reg <= reg; --otherwise, maintain current value
end if;
end process;
end Behavioral;
Этот сумматор просто добавляет единицу к значению, которое в данный момент находится на ПК:
entity B_adder is
Port ( a : in STD_LOGIC_VECTOR (9 downto 0);
x : out STD_LOGIC_VECTOR (9 downto 0));
end B_adder;
architecture Behavioral of B_adder is
begin
x <= a + 1;
end Behavioral;
Этот маленький мультиплексор выберет, будет ли следующий адрес поступать от сумматора филиала (не включен здесь) или от инкрементного сумматора выше:
entity nine_mux is
Port ( s : in STD_LOGIC;
in1 : in STD_LOGIC_VECTOR (9 downto 0);
in2 : in STD_LOGIC_VECTOR (9 downto 0);
output : out STD_LOGIC_VECTOR (9 downto 0));
end nine_mux;
architecture Behavioral of nine_mux is
begin
with s select
output <= in1 when '0',
in2 when others;
end Behavioral;
И вот какблок управления сопоставлен с каналом данных:
entity WholeThing is
Port ( BTNClock : in STD_LOGIC;
BTNReset : in STD_LOGIC;
SwitchReset : in STD_LOGIC;
clock : in STD_Logic;
LEDs : out STD_LOGIC_VECTOR(4 downto 0);
seg : out STD_LOGIC_vector(6 downto 0);
an : out STD_LOGIC_vector(7 downto 0);
alu11 : out STD_LOGIC;
reg11 : out STD_LOGIC
);
end WholeThing;
architecture Behavioral of WholeThing is
signal instruction : STD_LOGIC_VECTOR(31 downto 0);
signal Reg2Loc : STD_LOGIC;
signal ALUSRC : std_logic;
signal MemtoReg : std_logic;
signal RegWrite : std_logic;
signal Branch : std_logic;
signal ALUOp : std_logic_vector (1 downto 0);
signal UnconB : std_logic;
signal en : std_logic;
signal wea : std_logic;
signal PCWrite : std_logic;
signal REGCEA : std_logic;
signal SwRst : STD_LOGIC;
begin
--SwitchReset <= SwRst;
--Control Unit
CU : Fred port map ( Inst => instruction(31 downto 21),
clk => BTNClock,
rst => BTNReset,
Reg2Loc => Reg2Loc,
ALUSRC => ALUSRC,
MemtoReg => MemtoReg,
RegWrite =>RegWrite,
Branch => Branch,
ALUOp => ALUOp,
UnconB => UnconB,
en => en,
wea => wea,
PCWrite => PCWrite,
REGCEA => REGCEA,
LEDCode => LEDs);
--Datapath
DP : Datapath port map (BTNClock => BTNClock,
clock => clock,
UncondBranch => UnconB,
CondBranch => Branch,
RRtwoSelect => Reg2Loc,
RegWriteSelect => RegWrite,
ALUSource => ALUSRC,
ALUOpCode => ALUOp,
WriteSelect => MemtoReg,
MemWrite => wea,
REGCEA => REGCEA,
PCWrite => PCWrite,
seg_select => seg,
anode_select => an,
ins_out => instruction,
RAMSelect => en,
ALUEleven => alu11,
REGEleven => reg11,
SwitchReset => SwitchReset
);
end Behavioral;