-- indi16 vhdl -- indi16.4.0 -- (C)2007 K Ring Technologies Semiconductor -- designed for 66MHz operation -- TODO: mem hand shake, main 8 cycle sequence, video gen/sound & refresh, generics (16n bit) LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; USE work.indi.all; ENTITY indi16 IS PORT ( Clk, Reset, Halt, R16 : IN STD_LOGIC; DataIn : IN STD_LOGIC_VECTOR(15 DOWNTO 0); DataOut : OUT STD_LOGIC_VECTOR(15 DOWNTO 0); Fetch, BusFree, OE, WR, W16 : OUT STD_LOGIC; MemBank, Hilo : OUT STD_LOGIC; Colour, WColour : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); Address : OUT STD_LOGIC_VECTOR(15 DOWNTO 0) ); END indi16; ARCHITECTURE a OF indi16 IS -- the sequence clock (256 pixels) SIGNAL Seq : STD_LOGIC_VECTOR(10 DOWNTO 0); -- other hidden registers SIGNAL IR, Acc, ALUin, Data : STD_LOGIC_VECTOR(15 DOWNTO 0); -- the carry flag SIGNAL C : STD_LOGIC; VARIABLE ID, OD, C : STD_LOGIC; VARIABLE LMB, RegW, PrePost : STD_LOGIC; VARIABLE SrcDest : STD_LOGIC; VARIABLE Ins : STD_LOGIC_VECTOR(7 DOWNTO 0); VARIABLE Op, Rin, Rout : STD_LOGIC_VECTOR(1 DOWNTO 0); CONSTANT Zero16 : STD_LOGIC_VECTOR(15 DOWNTO 0) := "0000000000000000"; BEGIN myalu : alu PORT MAP (Acc => Acc, ALUin => ALUin, ALUout => ALUout, Cin => Cin, C => C, Op => Op); PROCESS (Clk, Reset, Halt) BEGIN IF Reset = '1' THEN -- reset happening Acc <= Zero16; Address <= Zero16; Fetch <= '1'; Cout <= '0'; Hilo <= '0'; ELSIF Clk'EVENT AND Clk = '1' AND Halt = '0' THEN -- instruction loop IF LMB = '1' THEN Ins := IR(7 DOWNTO 0); ELSE Ins := IR(15 DOWNTO 8); END IF; Op := Ins(7 DOWNTO 6); ID := Ins(5); Rin := Ins(4 DOWNTO 3); OD := Ins(2); Rout := Ins(1 DOWNTO 0); -- memory access IF Seq(0) = '1' THEN IF R16 = '0' THEN D16 := DataIn(7 DOWNTO 0) & Data(7 DOWNTO 0); ELSE D16 := DataIn; END IF; -- main 8 phase cycle, don't forget C; CASE Seq(3 DOWNTO 1) IS WHEN "000" => -- 0 Instruction Fetch Prepost := '1'; Fetch <= '0'; SrcDest := '1'; ID := '0'; IR <= D16; -- adress pregen? Address <= Zero16; WHEN "001" => -- 1 VFETCH PrePost := '0'; -- clear once/many latch vs. assign Fetch <= '0'; -- DEFAULT /* videogen on %n -- on latch by use of area robustness trade -- visualizations of gate levels vs. enable toggling etc. -- addr gen Address <= Addr; LMB := '0'; WHEN "010" => -- 2 HI op SRC fetch PrePost := '1'; IF ID = '1' THEN ALUin <= RVal; ELSE ALUin <= D16; END IF; Fetch <= '0'; -- again --addr gen Address <= Zero16; WHEN "011" => -- 3 CFETCH PrePost := '0'; DataOut <= ALUout; Acc <= ALUout; Fetch <= '0'; -- addr gen SrcDest := '0'; Address <= Addr; WHEN "100" => -- 4 HI op DEST store PrePost := '1'; Fetch <= '0'; --addr gen SrcDest := '1'; LMB := '1'; Address <= Addr; WHEN "101" => -- 5 LO op SRC fetch Fetch <= '0'; IF ID = '1' THEN ALUin <= RVal; ELSE ALUin <= D16; END IF; --addr gen Address <= Zero16; WHEN "110" => -- 6 PFETCH PrePost := '0'; Fetch <= '0'; DataOut <= ALUout; COut <= C; --addr gen SrcDest := '0'; Address <= Addr; WHEN "111" => -- 7 LO op DEST store PrePost := '1'; Fetch <= '1'; -- addr gen SrcDest := '1'; Address <= P; END CASE; ELSE Data <= DataIn; END IF; Hilo <= NOT Seq(0); -- clock next cycle Seq <= Seq + 1; END IF; END PROCESS; END a;