URL
https://opencores.org/ocsvn/xucpu/xucpu/trunk
Subversion Repositories xucpu
[/] [xucpu/] [trunk/] [src/] [system/] [uctrl.vhdl] - Rev 13
Go to most recent revision | Compare with Previous | Blame | View Log
-- Copyright 2015, Jürgen Defurne -- -- This file is part of the Experimental Unstable CPU System. -- -- The Experimental Unstable CPU System Is free software: you can redistribute -- it and/or modify it under the terms of the GNU Lesser General Public License -- as published by the Free Software Foundation, either version 3 of the -- License, or (at your option) any later version. -- -- The Experimental Unstable CPU System is distributed in the hope that it will -- be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -- General Public License for more details. -- -- You should have received a copy of the GNU Lesser General Public License -- along with Experimental Unstable CPU System. If not, see -- http://www.gnu.org/licenses/lgpl.txt. ARCHITECTURE Mealy OF uctrl IS TYPE uCtrl_state IS ( S_RST, S_DECODE, S_FETCH, S_UOP_P1, S_UOP_P2, S_BOP_P1, S_BOP_P2, S_LD_RV, S_LD_RV_2, S_LD_RR, S_LD_RR_2, S_LD_RM, S_LD_RM_2, S_LD_MR, S_LD_MR_2, S_GO_ADR, S_GO_ADR_2, S_GO_REG, S_GO_REG_2, S_JZ_P0, S_JZ_P1, S_JZ_P2, S_JNZ_P0, S_JNZ_P1, S_JNZ_P2, S_HALT, S_RETI, S_RETI_2, S_ILL ); SIGNAL NEXT_STATE : uCtrl_state; SIGNAL CURR_STATE : uCtrl_state; SIGNAL LD_INSTR : STD_LOGIC; SIGNAL DECODING : STD_LOGIC; SIGNAL OPERATION : STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL REG_ADDR_A : STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL REG_ADDR_B : STD_LOGIC_VECTOR(3 DOWNTO 0); BEGIN -- ARCHITECTURE Mealy -- purpose: Next state functionality -- type : combinational -- inputs : IR_IN,ZERO,INT,RST,CURR_STATE -- outputs: NEXT_ST1 : PROCESS (CURR_STATE, IR_IN, INT, RST, ZERO) VARIABLE I_ADDR : uCtrl_state; BEGIN -- PROCESS uCTRL IF RST = '1' THEN NEXT_STATE <= S_RST; ELSE CASE IR_IN(15 DOWNTO 12) IS WHEN "0000" => I_ADDR := S_HALT; WHEN "0001" => I_ADDR := S_GO_ADR; WHEN "0010" => I_ADDR := S_GO_REG; WHEN "0011" => I_ADDR := S_LD_RV; WHEN "0100" => I_ADDR := S_LD_RR; WHEN "0101" => I_ADDR := S_LD_RM; WHEN "0110" => I_ADDR := S_LD_MR; WHEN "0111" => I_ADDR := S_BOP_P1; WHEN "1000" => I_ADDR := S_UOP_P1; WHEN "1001" => I_ADDR := S_JZ_P0; WHEN "1010" => I_ADDR := S_JNZ_P0; WHEN "1011" => I_ADDR := S_RETI; WHEN "1100" => I_ADDR := S_ILL; WHEN "1101" => I_ADDR := S_ILL; WHEN "1110" => I_ADDR := S_ILL; WHEN "1111" => I_ADDR := S_ILL; WHEN OTHERS => I_ADDR := S_ILL; END CASE; CASE CURR_STATE IS WHEN S_RST => NEXT_STATE <= S_FETCH; WHEN S_FETCH => NEXT_STATE <= S_DECODE; WHEN S_DECODE => NEXT_STATE <= I_ADDR; WHEN S_UOP_P1 => NEXT_STATE <= S_UOP_P2; WHEN S_UOP_P2 => NEXT_STATE <= I_ADDR; WHEN S_BOP_P1 => NEXT_STATE <= S_BOP_P2; WHEN S_BOP_P2 => NEXT_STATE <= I_ADDR; WHEN S_LD_RV => NEXT_STATE <= S_LD_RV_2; WHEN S_LD_RV_2 => NEXT_STATE <= I_ADDR; WHEN S_LD_RR => NEXT_STATE <= S_LD_RR_2; WHEN S_LD_RR_2 => NEXT_STATE <= I_ADDR; WHEN S_LD_RM => NEXT_STATE <= S_LD_RM_2; WHEN S_LD_RM_2 => NEXT_STATE <= I_ADDR; WHEN S_LD_MR => NEXT_STATE <= S_LD_MR_2; WHEN S_LD_MR_2 => NEXT_STATE <= I_ADDR; WHEN S_GO_ADR => NEXT_STATE <= S_GO_ADR_2; WHEN S_GO_ADR_2 => NEXT_STATE <= I_ADDR; WHEN S_GO_REG => NEXT_STATE <= S_GO_REG_2; WHEN S_JZ_P0 => NEXT_STATE <= S_JZ_P1; WHEN S_JZ_P1 => IF ZERO = '1' THEN NEXT_STATE <= S_FETCH; ELSE NEXT_STATE <= S_JZ_P2; END IF; WHEN S_JZ_P2 => NEXT_STATE <= I_ADDR; WHEN S_JNZ_P0 => NEXT_STATE <= S_JNZ_P1; WHEN S_JNZ_P1 => IF ZERO = '1' THEN NEXT_STATE <= S_FETCH; ELSE NEXT_STATE <= S_JNZ_P2; END IF; WHEN S_JNZ_P2 => NEXT_STATE <= I_ADDR; WHEN S_HALT => NEXT_STATE <= S_HALT; WHEN S_RETI => NEXT_STATE <= S_RETI_2; WHEN S_RETI_2 => NEXT_STATE <= S_DECODE; WHEN S_ILL => NEXT_STATE <= S_ILL; WHEN OTHERS => NEXT_STATE <= S_DECODE; END CASE; END IF; END PROCESS NEXT_ST1; -- State register logic STATE_REG1 : PROCESS (CLK, RST) BEGIN IF rising_edge(CLK) THEN IF RST = '1' THEN CURR_STATE <= S_RST; ELSE CURR_STATE <= NEXT_STATE; END IF; END IF; END PROCESS STATE_REG1; -- Instruction values INSTR_REG1 : PROCESS (CLK, RST) BEGIN IF rising_edge(CLK) THEN IF RST = '1' THEN OPERATION <= "0000"; REG_ADDR_A <= "0000"; REG_ADDR_B <= "0000"; ELSE IF LD_INSTR = '1' THEN OPERATION <= IR_IN(11 DOWNTO 8); REG_ADDR_A <= IR_IN(7 DOWNTO 4); REG_ADDR_B <= IR_IN(3 DOWNTO 0); END IF; END IF; END IF; END PROCESS; ALU_OP <= OPERATION; RFA_A <= REG_ADDR_A; RFA_B <= REG_ADDR_B; -- Mealy output function logic OUT1 : PROCESS (CURR_STATE, RST, INT, IR_IN, DECODING, ZERO) BEGIN -- Make sure that all control signals are initialised PC_SRC <= "011"; -- Default to PC output LD_PC <= '0'; LD_IR <= '0'; LD_DP <= '0'; REG_SRC <= "101"; REG_WR <= '0'; LD_REG_A <= '0'; LD_REG_B <= '0'; LD_MAR <= '0'; LD_MDR <= '0'; MEM_WR <= '0'; LD_INSTR <= '0'; DECODING <= '0'; CASE CURR_STATE IS WHEN S_RST => IF RST = '0' THEN PC_SRC <= "100"; LD_PC <= '1'; LD_IR <= '0'; END IF; WHEN S_FETCH => PC_SRC <= "001"; LD_PC <= '1'; LD_IR <= '1'; LD_DP <= '1'; LD_INSTR <= '1'; DECODING <= '0'; WHEN S_DECODE => PC_SRC <= "001"; LD_PC <= '1'; LD_IR <= '1'; LD_DP <= '1'; LD_INSTR <= '1'; DECODING <= '1'; WHEN S_UOP_P1 => LD_REG_A <= '1'; WHEN S_UOP_P2 => REG_SRC <= "000"; REG_WR <= '1'; PC_SRC <= "001"; LD_PC <= '1'; LD_IR <= '1'; LD_DP <= '1'; LD_INSTR <= '1'; DECODING <= '1'; WHEN S_BOP_P1 => LD_REG_A <= '1'; LD_REG_B <= '1'; WHEN S_BOP_P2 => REG_SRC <= "000"; REG_WR <= '1'; PC_SRC <= "001"; LD_PC <= '1'; LD_IR <= '1'; LD_DP <= '1'; LD_INSTR <= '1'; DECODING <= '1'; WHEN S_LD_RR => LD_REG_B <= '1'; WHEN S_LD_RR_2 => REG_SRC <= "000"; REG_WR <= '1'; PC_SRC <= "001"; LD_PC <= '1'; LD_IR <= '1'; LD_DP <= '1'; LD_INSTR <= '1'; DECODING <= '1'; WHEN S_LD_RV => PC_SRC <= "001"; LD_PC <= '1'; LD_IR <= '1'; LD_DP <= '0'; WHEN S_LD_RV_2 => REG_SRC <= "010"; REG_WR <= '1'; PC_SRC <= "001"; LD_PC <= '1'; LD_IR <= '1'; LD_DP <= '1'; LD_INSTR <= '1'; DECODING <= '1'; -- Write data from reg A to address reg B WHEN S_LD_MR => LD_MAR <= '1'; LD_MDR <= '1'; WHEN S_LD_MR_2 => MEM_WR <= '1'; PC_SRC <= "001"; LD_PC <= '1'; LD_IR <= '1'; LD_DP <= '1'; LD_INSTR <= '1'; DECODING <= '1'; WHEN S_LD_RM => LD_MAR <= '1'; WHEN S_LD_RM_2 => REG_SRC <= "001"; REG_WR <= '1'; PC_SRC <= "001"; LD_PC <= '1'; LD_IR <= '1'; LD_DP <= '1'; LD_INSTR <= '1'; DECODING <= '1'; WHEN S_JZ_P0 => WHEN S_JNZ_P0 => NULL; WHEN S_JZ_P1 => IF ZERO = '1' THEN PC_SRC <= "010"; ELSE PC_SRC <= "001"; END IF; LD_PC <= '1'; LD_IR <= '1'; LD_DP <= '0'; WHEN S_JZ_P2 => PC_SRC <= "001"; LD_PC <= '1'; LD_IR <= '1'; LD_DP <= '1'; LD_INSTR <= '1'; DECODING <= '1'; WHEN S_JNZ_P1 => IF ZERO = '0' THEN PC_SRC <= "010"; ELSE PC_SRC <= "001"; END IF; LD_PC <= '1'; LD_IR <= '1'; LD_DP <= '0'; WHEN S_JNZ_P2 => PC_SRC <= "001"; LD_PC <= '1'; LD_IR <= '1'; LD_DP <= '1'; LD_INSTR <= '1'; DECODING <= '1'; WHEN S_HALT => NULL; WHEN OTHERS => PC_SRC <= "001"; LD_PC <= '1'; LD_IR <= '1'; LD_DP <= '1'; END CASE; CASE IR_IN(15 DOWNTO 12) IS WHEN "0001" => IF DECODING = '1' THEN PC_SRC <= "111"; LD_PC <= '1'; END IF; WHEN "0011" => WHEN "1001" => WHEN "1010" => IF DECODING = '1' THEN LD_IR <= '0'; END IF; WHEN OTHERS => NULL; END CASE; END PROCESS OUT1; END ARCHITECTURE Mealy;
Go to most recent revision | Compare with Previous | Blame | View Log