From fbe743288c676e94b52849f083a9f3d5015a13ed Mon Sep 17 00:00:00 2001 From: oharboe Date: Fri, 22 Feb 2008 07:57:20 +0000 Subject: wip porting zpu_core_bram.vhd from ZPU3. --- zpu/hdl/zpu4/src/bram_dmips.vhd | 6 +- zpu/hdl/zpu4/src/simzpu_bram.do | 28 ++ zpu/hdl/zpu4/src/zpu_config_trace.vhd | 1 + zpu/hdl/zpu4/src/zpu_core_bram.vhd | 780 ++++++++++++++++++++++++++++++++++ zpu/hdl/zpu4/src/zpu_core_small.vhd | 13 - zpu/hdl/zpu4/src/zpupkg.vhd | 13 + 6 files changed, 825 insertions(+), 16 deletions(-) create mode 100644 zpu/hdl/zpu4/src/simzpu_bram.do create mode 100644 zpu/hdl/zpu4/src/zpu_core_bram.vhd (limited to 'zpu/hdl/zpu4/src') diff --git a/zpu/hdl/zpu4/src/bram_dmips.vhd b/zpu/hdl/zpu4/src/bram_dmips.vhd index 1c85e0d..83bfc28 100644 --- a/zpu/hdl/zpu4/src/bram_dmips.vhd +++ b/zpu/hdl/zpu4/src/bram_dmips.vhd @@ -10,11 +10,11 @@ use work.zpupkg.all; entity dualport_ram is port (clk : in std_logic; memAWriteEnable : in std_logic; - memAAddr : in std_logic_vector(maxAddrBit downto minAddrBit); + memAAddr : in std_logic_vector(maxAddrBitBRAM downto minAddrBit); memAWrite : in std_logic_vector(wordSize-1 downto 0); memARead : out std_logic_vector(wordSize-1 downto 0); memBWriteEnable : in std_logic; - memBAddr : in std_logic_vector(maxAddrBit downto minAddrBit); + memBAddr : in std_logic_vector(maxAddrBitBRAM downto minAddrBit); memBWrite : in std_logic_vector(wordSize-1 downto 0); memBRead : out std_logic_vector(wordSize-1 downto 0)); end dualport_ram; @@ -22,7 +22,7 @@ end dualport_ram; architecture dualport_ram_arch of dualport_ram is -type ram_type is array(0 to ((2**(maxAddrBit+1))/4)-1) of std_logic_vector(wordSize-1 downto 0); +type ram_type is array(0 to ((2**(maxAddrBitBRAM+1))/4)-1) of std_logic_vector(wordSize-1 downto 0); shared variable ram : ram_type := ( diff --git a/zpu/hdl/zpu4/src/simzpu_bram.do b/zpu/hdl/zpu4/src/simzpu_bram.do new file mode 100644 index 0000000..1c8673d --- /dev/null +++ b/zpu/hdl/zpu4/src/simzpu_bram.do @@ -0,0 +1,28 @@ +# Xilinx WebPack modelsim script +# +# cd C:/workspace/zpu/zpu/hdl/zpu4/src +# do simzpu_bram.do + +set BreakOnAssertion 1 +vlib work + +vcom -93 -explicit zpu_config_trace.vhd +vcom -93 -explicit zpupkg.vhd +vcom -93 -explicit txt_util.vhd +vcom -93 -explicit sim_fpga_top.vhd +vcom -93 -explicit zpu_core_bram.vhd +vcom -93 -explicit bram_dmips.vhd +vcom -93 -explicit timer.vhd +vcom -93 -explicit io.vhd +vcom -93 -explicit trace.vhd + +# run ZPU +vsim fpga_top +view wave +add wave -recursive fpga_top/zpu/* +#add wave -recursive fpga_top/* +view structure +#view signals + +# Enough to run tiny programs +run 1us diff --git a/zpu/hdl/zpu4/src/zpu_config_trace.vhd b/zpu/hdl/zpu4/src/zpu_config_trace.vhd index a2d7d9d..4d0f15f 100644 --- a/zpu/hdl/zpu4/src/zpu_config_trace.vhd +++ b/zpu/hdl/zpu4/src/zpu_config_trace.vhd @@ -12,6 +12,7 @@ package zpu_config is constant ZPU_Frequency : std_logic_vector(7 downto 0) := x"64"; constant maxAddrBitIncIO : integer := 27; constant maxAddrBitDRAM : integer := 16; + constant maxAddrBitBRAM : integer := 16; constant spStart : std_logic_vector(maxAddrBitIncIO downto 0) := x"001fff8"; end zpu_config; diff --git a/zpu/hdl/zpu4/src/zpu_core_bram.vhd b/zpu/hdl/zpu4/src/zpu_core_bram.vhd new file mode 100644 index 0000000..0bedba3 --- /dev/null +++ b/zpu/hdl/zpu4/src/zpu_core_bram.vhd @@ -0,0 +1,780 @@ +-- Company: ZPU3 +-- Engineer: Øyvind Harboe + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +use IEEE.STD_LOGIC_arith.ALL; + +library work; +use work.zpu_config.all; +use work.zpupkg.all; + + +-- io_busy : in std_logic; +-- io_read : in std_logic_vector(7 downto 0); +-- io_write : out std_logic_vector(7 downto 0); +-- io_addr : out std_logic_vector(maxAddrBit downto minAddrBit); +-- io_writeEnable : out std_logic; +-- io_readEnable : out std_logic; + + +entity zpu_core is + Port ( clk : in std_logic; + areset : in std_logic; + enable : in std_logic; + in_mem_busy : in std_logic; + mem_read : in std_logic_vector(wordSize-1 downto 0); + mem_write : out std_logic_vector(wordSize-1 downto 0); + out_mem_addr : out std_logic_vector(maxAddrBitIncIO downto 0); + out_mem_writeEnable : out std_logic; + out_mem_readEnable : out std_logic; + mem_writeMask: out std_logic_vector(wordBytes-1 downto 0); + interrupt : in std_logic; + break : out std_logic); +end zpu_core; + + +architecture behave of zpu_core is + +signal readIO : std_logic; + + + +signal memAWriteEnable : std_logic; +signal memAAddr : std_logic_vector(maxAddrBit downto minAddrBit); +signal memAWrite : std_logic_vector(wordSize-1 downto 0); +signal memARead : std_logic_vector(wordSize-1 downto 0); +signal memBWriteEnable : std_logic; +signal memBAddr : std_logic_vector(maxAddrBit downto minAddrBit); +signal memBWrite : std_logic_vector(wordSize-1 downto 0); +signal memBRead : std_logic_vector(wordSize-1 downto 0); + + + +signal pc : std_logic_vector(maxAddrBit downto 0); +signal sp : std_logic_vector(maxAddrBit downto minAddrBit); + +signal idim_flag : std_logic; + +--signal storeToStack : std_logic; +--signal fetchNextInstruction : std_logic; +--signal extraCycle : std_logic; +signal busy : std_logic; +--signal fetching : std_logic; + +signal begin_inst : std_logic; + + + +signal trace_opcode : std_logic_vector(7 downto 0); +signal trace_pc : std_logic_vector(maxAddrBitIncIO downto 0); +signal trace_sp : std_logic_vector(maxAddrBitIncIO downto minAddrBit); +signal trace_topOfStack : std_logic_vector(wordSize-1 downto 0); +signal trace_topOfStackB : std_logic_vector(wordSize-1 downto 0); + +-- state machine. + +type State_Type is +( +State_ResyncDecode, +State_WriteIODone, +State_Execute, +State_StoreToStack, +State_Add, +State_Or, +State_And, +State_Store, +State_ReadIO, +State_WriteIO, +State_Load, +State_ResyncStack, +State_AddSP, +State_ReadIODone, +State_Decode, +State_LoadByte1, +State_LoadByte2, +State_StoreByte1, +State_StoreByte2, +State_Mult1, +State_Mult2, +State_Mult3 +); + +type DecodedOpcodeType is +( +Decoded_Nop, +Decoded_Im, +Decoded_ImShift, +Decoded_LoadSP, +Decoded_StoreSP, +Decoded_AddSP, +Decoded_Emulate, +Decoded_Break, +Decoded_PushPC, +Decoded_PushSP, +Decoded_PopPC, +Decoded_Add, +Decoded_Or, +Decoded_And, +Decoded_Load, +Decoded_Not, +Decoded_Flip, +Decoded_Store, +Decoded_PopSP, +Decoded_Ashiftleft, +Decoded_Ashiftright, +Decoded_Lshiftright, +Decoded_Eqbranch, +Decoded_Neqbranch, +Decoded_Eq, +Decoded_Neq, +Decoded_Loadb, +Decoded_Lessthan, +Decoded_Lessthanorequal, +Decoded_Ulessthan, +Decoded_Ulessthanorequal, +Decoded_Storeb, +Decoded_Lshift2, +Decoded_DoubleIm, +Decoded_AddIm, +Decoded_Mult16x16, +Decoded_Swap, +Decoded_Callpcrel, +Decoded_Pushspadd +); + + +signal mult1 : std_logic_vector(wordSize/2-1 downto 0); +signal mult2 : std_logic_vector(wordSize/2-1 downto 0); +signal multResult : std_logic_vector(wordSize-1 downto 0); + +signal storeByte : std_logic_vector(7 downto 0); +signal byteSelect : std_logic_vector(minAddrBit-1 downto 0); + +signal opcode : std_logic_vector(OpCode_Size-1 downto 0); +signal opcode2 : std_logic_vector(OpCode_Size-1 downto 0); + +signal decodedOpcode : DecodedOpcodeType; + +signal state : State_Type; + +begin + traceFileGenerate: + if Generate_Trace generate + trace_file: trace port map ( + clk => clk, + begin_inst => begin_inst, + pc => trace_pc, + opcode => trace_opcode, + sp => trace_sp, + memA => trace_topOfStack, + memB => trace_topOfStackB, + busy => busy, + intsp => (others => 'U') + ); + end generate; + + + memory: dualport_ram port map ( + clk => clk, + memAWriteEnable => memAWriteEnable, + memAAddr => memAAddr(maxAddrBitBRAM downto minAddrBit), + memAWrite => memAWrite, + memARead => memARead, + memBWriteEnable => memBWriteEnable, + memBAddr => memBAddr(maxAddrBitBRAM downto minAddrBit), + memBWrite => memBWrite, + memBRead => memBRead + ); + + + + process(clk, areset) + begin + if (clk'event and clk = '1') then + multResult <= mult1 * mult2; + end if; + end process; + + + + opcodeControl: + process(clk, areset) + variable tOpcode : std_logic_vector(OpCode_Size-1 downto 0); + variable tOpcode2 : std_logic_vector(OpCode_Size-1 downto 0); + variable spOffset : std_logic_vector(4 downto 0); + variable spOffset2 : std_logic_vector(4 downto 0); + variable nextPC : std_logic_vector(maxAddrBit downto 0); + variable pushspaddTemp : std_logic_vector(maxAddrBit downto minAddrBit); + variable tempVal : std_logic_vector(wordSize-1 downto 0); + variable compareA : signed(wordSize-1 downto 0); + variable compareB : signed(wordSize-1 downto 0); + begin + if areset = '1' then + mult1 <= (others => '0'); + mult2 <= (others => '0'); + state <= State_ResyncDecode; + break <= '0'; + sp <= spStart(maxAddrBit downto minAddrBit); + pc <= (others => '0'); + idim_flag <= '0'; + begin_inst <= '0'; + memAAddr <= (others => '0'); + memBAddr <= (others => '0'); + memAWriteEnable <= '0'; + memBWriteEnable <= '0'; + out_mem_writeEnable <= '0'; + out_mem_readEnable <= '0'; + decodedOpcode <= Decoded_Break; + memAWrite <= (others => '0'); + memBWrite <= (others => '0'); + opcode <= (others => '0'); + out_mem_addr <= (others => '0'); + mem_write <= (others => '0'); + elsif (clk'event and clk = '1') then + memAWriteEnable <= '0'; + memBWriteEnable <= '0'; + + out_mem_writeEnable <= '0'; + out_mem_readEnable <= '0'; + out_mem_addr <= memARead(maxAddrBitIncIO downto 0); + begin_inst <= '0'; + + case state is + when State_Decode => + nextPC:=pc+1; + case pc(1 downto 0) is + when "00" => tOpcode := memARead(31 downto 24); + when "01" => tOpcode := memARead(23 downto 16); + when "10" => tOpcode := memARead(15 downto 8); + when others => tOpcode := memARead(7 downto 0); + end case; + case nextPC(1 downto 0) is + when "00" => tOpcode2 := memBRead(31 downto 24); + when "01" => tOpcode2 := memBRead(23 downto 16); + when "10" => tOpcode2 := memBRead(15 downto 8); + when others => tOpcode2 := memBRead(7 downto 0); + end case; + idim_flag <= tOpcode(7); + opcode <= tOpcode; + opcode2 <= tOpcode2; + if (tOpcode(7 downto 7)=OpCode_Im and tOpcode2(7 downto 4)=0 and tOpcode2(3 downto 0)=Opcode_Add and idim_flag='0') then + idim_flag <= '0'; + decodedOpcode <= Decoded_AddIm; + nextPC := pc + 2; + elsif (tOpcode(7 downto 7)=OpCode_Im and tOpcode2(7 downto 7)=OpCode_Im and idim_flag='0') then + decodedOpcode <= Decoded_DoubleIm; + nextPC := pc + 2; + elsif (tOpcode(7 downto 4)=OpCode_AddSP and tOpcode(3 downto 0)=0 and + tOpcode2(7 downto 4)=OpCode_AddSP and tOpcode2(3 downto 0)=0) then + decodedOpcode <= Decoded_Lshift2; + nextPC := pc + 2; + elsif (tOpcode(7 downto 7)=OpCode_Im) then + if (idim_flag='1') then + decodedOpcode<=Decoded_ImShift; + else + decodedOpcode<=Decoded_Im; + end if; + elsif (tOpcode(7 downto 5)=OpCode_StoreSP) then + decodedOpcode<=Decoded_StoreSP; + elsif (tOpcode(7 downto 5)=OpCode_LoadSP) then + decodedOpcode<=Decoded_LoadSP; + elsif (tOpcode(7 downto 5)=OpCode_Emulate) then + if tOpcode(5 downto 0)=OpCode_Eqbranch then + decodedOpcode <= Decoded_Eqbranch; + elsif tOpcode(5 downto 0)=OpCode_Neqbranch then + decodedOpcode <= Decoded_Neqbranch; + elsif tOpcode(5 downto 0)=OpCode_Eq then + decodedOpcode <= Decoded_Eq; + elsif tOpcode(5 downto 0)=OpCode_Neq then + decodedOpcode <= Decoded_Neq; + elsif tOpcode(5 downto 0)=OpCode_Lessthan then + decodedOpcode <= Decoded_Lessthan; + elsif tOpcode(5 downto 0)=OpCode_Lessthanorequal then + decodedOpcode <= Decoded_Lessthanorequal; + elsif tOpcode(5 downto 0)=OpCode_Ulessthan then + decodedOpcode <= Decoded_Ulessthan; + elsif tOpcode(5 downto 0)=OpCode_Ulessthanorequal then + decodedOpcode <= Decoded_Ulessthanorequal; + elsif tOpcode(5 downto 0)=OpCode_Loadb then + decodedOpcode <= Decoded_Loadb; + elsif tOpcode(5 downto 0)=OpCode_Storeb then + decodedOpcode <= Decoded_Storeb; + elsif tOpcode(5 downto 0)=OpCode_Mult16x16 then + decodedOpcode <= Decoded_Mult16x16; + elsif tOpcode(5 downto 0)=OpCode_Swap then + decodedOpcode <= Decoded_Swap; + elsif tOpcode(5 downto 0)=OpCode_Callpcrel then + decodedOpcode <= Decoded_Callpcrel; + elsif tOpcode(5 downto 0)=OpCode_Pushspadd then + decodedOpcode <= Decoded_Pushspadd; +-- elsif tOpcode(5 downto 0)=OpCode_Lshiftright then +-- decodedOpcode <= Decoded_Lshiftright; +-- elsif tOpcode(5 downto 0)=OpCode_Ashiftleft then +-- decodedOpcode <= Decoded_Ashiftleft; +-- elsif tOpcode(5 downto 0)=OpCode_Ashiftright then +-- decodedOpcode <= Decoded_Ashiftright; + else + decodedOpcode<=Decoded_Emulate; + end if; + elsif (tOpcode(7 downto 4)=OpCode_AddSP) then + decodedOpcode<=Decoded_AddSP; + else + case tOpcode(3 downto 0) is + when OpCode_PushSP => + decodedOpcode<=Decoded_PushSP; + when OpCode_PopPC => + decodedOpcode<=Decoded_PopPC; + when OpCode_Add => + decodedOpcode<=Decoded_Add; + when OpCode_Or => + decodedOpcode<=Decoded_Or; + when OpCode_And => + decodedOpcode<=Decoded_And; + when OpCode_Load => + decodedOpcode<=Decoded_Load; + when OpCode_Not => + decodedOpcode<=Decoded_Not; + when OpCode_Flip => + decodedOpcode<=Decoded_Flip; + when OpCode_Store => + decodedOpcode<=Decoded_Store; + when OpCode_PopSP => + decodedOpcode<=Decoded_PopSP; + when OpCode_Break => + decodedOpcode<=Decoded_Break; + when others => + decodedOpcode<=Decoded_Nop; + end case; + end if; + -- Fetch the two next opcodes... :-) + memAAddr <= nextPC(maxAddrBit downto minAddrBit); + nextPC:=nextPC+1; + memBAddr <= nextPC(maxAddrBit downto minAddrBit); + state <= State_Execute; + when State_Execute => + state <= State_Decode; + -- at this point: + -- memBRead contains opcode word + -- memARead contains top of stack + pc <= pc + 1; + + -- trace + begin_inst <= '1'; + trace_pc <= (others => '0'); + trace_pc(maxAddrBit downto 0) <= pc; + trace_sp <= (others => '0'); + trace_sp(maxAddrBit downto minAddrBit) <= sp; + trace_opcode <= opcode; + trace_topOfStack <= memARead; + trace_topOfStackB <= memBRead; + + + -- during the next cycle we'll be reading the next opcode + spOffset(4):=not opcode(4); + spOffset(3 downto 0):=opcode(3 downto 0); + spOffset2(4):=not opcode2(4); + spOffset2(3 downto 0):=opcode2(3 downto 0); + + case decodedOpcode is + + when Decoded_DoubleIm => + memAWriteEnable <= '1'; + sp <= sp - 1; + memAAddr <= sp-1; + for i in wordSize-1 downto 14 loop + memAWrite(i) <= opcode(6); + end loop; + memAWrite(13 downto 7) <= opcode(6 downto 0); + memAWrite(6 downto 0) <= opcode2(6 downto 0); + memBAddr <= sp; + memBWrite <= memARead; + memBWriteEnable <= '1'; + pc <= pc + 2; + when Decoded_Im => + memAWriteEnable <= '1'; + sp <= sp - 1; + memAAddr <= sp-1; + for i in wordSize-1 downto 7 loop + memAWrite(i) <= opcode(6); + end loop; + memAWrite(6 downto 0) <= opcode(6 downto 0); + memBAddr <= sp; + memBWrite <= memARead; + memBWriteEnable <= '1'; + when Decoded_ImShift => + memAAddr <= sp; + memAWriteEnable <= '1'; + memAWrite(wordSize-1 downto 7) <= memARead(wordSize-8 downto 0); + memAWrite(6 downto 0) <= opcode(6 downto 0); + memBAddr <= sp + 1; + when Decoded_StoreSP => + memAWriteEnable <= '1'; + memAAddr <= sp+spOffset; + memAWrite <= memARead; + -- avoid address crashes. + memBAddr <= sp - 1; + sp <= sp + 1; + state <= State_ResyncDecode; + when Decoded_LoadSP => + sp <= sp - 1; + if (spOffset = 0) then + -- This is a duplicate instruction. + memAAddr <= sp-1; + memAWriteEnable <= '1'; + memAWrite <= memARead; + else + memAAddr <= sp+spOffset; + end if; + memBAddr <= sp; + memBWrite <= memARead; + memBWriteEnable <= '1'; + when Decoded_Callpcrel => + memAWriteEnable <= '1'; + memAAddr <= sp; + memAWrite <= (others => DontCareValue); + memAWrite(maxAddrBit downto 0) <= pc + 1; + memBAddr <= sp+1; + pc <= pc + memARead(maxAddrBit downto 0); + state <= State_ResyncDecode; + when Decoded_Emulate => + sp <= sp - 1; + memAWriteEnable <= '1'; + memAAddr <= sp - 1; + memAWrite <= (others => DontCareValue); + memAWrite(maxAddrBit downto 0) <= pc + 1; + memBAddr <= sp; + memBWrite <= memARead; + memBWriteEnable <= '1'; + -- The emulate address is: + -- 98 7654 3210 + -- 0000 00aa aaa0 0000 + pc <= (others => '0'); + pc(9 downto 5) <= opcode(4 downto 0); + state <= State_ResyncDecode; + when Decoded_AddSP => + if spOffset=0 then + -- avoid address line crashes... + -- FIX!!! is this an issue? + -- oh-well. While we are at it, we've got a faster + -- shift operation without updating the toolchain. + memAWriteEnable <= '1'; + memAAddr <= sp; + memAWrite <= memARead + memARead; + memBAddr <= sp+1; + else + memAWriteEnable <= '1'; + memAAddr <= sp; + memAWrite <= memARead; + memBAddr <= sp+spOffset; + state <= State_AddSP; + end if; + when Decoded_Break => + report "Break instruction encountered" severity failure; + break <= '1'; + when Decoded_PushSP => + memAWriteEnable <= '1'; + memAAddr <= sp - 1; + sp <= sp - 1; + memAWrite <= (others => DontCareValue); + memAWrite(maxAddrBit downto minAddrBit) <= sp; + memBAddr <= sp; + memBWrite <= memARead; + memBWriteEnable <= '1'; + when Decoded_Pushspadd => + memAWriteEnable <= '1'; + memAAddr <= sp; + memAWrite <= (others => DontCareValue); + pushspaddTemp := memARead(maxAddrBit-minAddrBit downto 0); + memAWrite(maxAddrBit downto minAddrBit) <= sp+pushspaddTemp; + memBAddr <= sp+1; + when Decoded_PopPC => + memAAddr <= sp; + pc <= memARead(maxAddrBit downto 0); + sp <= sp + 1; + state <= State_ResyncDecode; + when Decoded_AddIm => + memAWriteEnable <= '1'; + memAAddr <= sp; + tempVal(wordSize-1 downto 7) := (others => tOpcode(6)); + tempVal(6 downto 0) := tOpcode(6 downto 0); + memAWrite <= memARead + tempVal; + memBAddr <= sp + 1; + pc <= pc + 2; + when Decoded_Add => + memAWriteEnable <= '1'; + memAWrite <= memARead + memBRead; + memAAddr <= sp + 1; + memBAddr <= sp + 2; + sp <= sp + 1; + when Decoded_Or => + sp <= sp + 1; + memAWriteEnable <= '1'; + memAWrite <= memARead or memBRead; + memAWriteEnable <= '1'; + memAAddr <= sp + 1; + memBAddr <= sp + 2; + when Decoded_And => + sp <= sp + 1; + memAWriteEnable <= '1'; + memAWrite <= memARead and memBRead; + memAWriteEnable <= '1'; + memAAddr <= sp + 1; + memBAddr <= sp + 2; + when Decoded_Load => + if (memARead(ioBit)='1') then + out_mem_addr <= memARead(maxAddrBitIncIO downto 0); + out_mem_readEnable <= '1'; + state <= State_ReadIO; + else + memAAddr <= memARead(maxAddrBit downto minAddrBit); + memBAddr <= sp + 1; + end if; + when Decoded_Swap => + memAAddr <= sp; + memAWriteEnable <= '1'; + memAWrite(wordSize/2-1 downto 0) <= memARead(wordSize-1 downto wordSize/2); + memAWrite(wordSize-1 downto wordSize/2) <= memARead(wordSize/2-1 downto 0); + memBAddr <= sp + 1; + when Decoded_Not => + memAAddr <= sp; + memAWriteEnable <= '1'; + memAWrite <= not memARead; + memBAddr <= sp + 1; + when Decoded_Flip => + memAAddr <= sp; + memAWriteEnable <= '1'; + for i in 0 to wordSize-1 loop + memAWrite(i) <= memARead(wordSize-1-i); + end loop; + memBAddr <= sp + 1; + when Decoded_Lshift2 => + memAAddr <= sp; + memAWriteEnable <= '1'; + memAWrite(1 downto 0) <= (others => '0'); + memAWrite(wordSize-1 downto 2) <= memARead(wordSize-1-2 downto 0); + memBAddr <= sp + 1; + pc <= pc + 2; + when Decoded_Store => + sp <= sp + 2; + if (memARead(ioBit)='1') then + out_mem_writeEnable <= '1'; + out_mem_addr <= memARead(maxAddrBitIncIO downto 0); + mem_write <= memBRead; + state <= State_WriteIO; + else + memAWriteEnable <= '1'; + memAAddr <= memARead(maxAddrBit downto minAddrBit); + memAWrite <= memBRead; + state <= State_ResyncDecode; + end if; + when Decoded_PopSP => + sp <= memARead(maxAddrBit downto minAddrBit); + state <= State_ResyncDecode; + when Decoded_Ashiftleft => + memAWrite(wordSize-1 downto conv_integer(memARead(wordPower-1 downto 0))) <= + memBRead(wordSize-conv_integer(memARead(wordPower-1 downto 0))-1 downto 0); + if memARead(wordPower-1 downto 0)/=0 then + memAWrite(conv_integer(memARead(wordPower-1 downto 0))-1 downto 0) <= (others => '0'); + end if; + memAWriteEnable <= '1'; + memAAddr <= sp + 1; + memBAddr <= sp + 2; + sp <= sp + 1; + when Decoded_Ashiftright | Decoded_Lshiftright => + memAWrite(wordSize-1-conv_integer(memARead(wordPower-1 downto 0)) downto 0) <= + memBRead(wordSize-1 downto conv_integer(memARead(wordPower-1 downto 0))); + if memARead(wordPower-1 downto 0)/=0 then + if decodedOpcode=Decoded_Ashiftright and memBRead(wordSize-1)='1' then + memAWrite(wordSize-1 downto wordSize-conv_integer(memARead(wordPower-1 downto 0))-1) <= (others => '1'); + else + memAWrite(wordSize-1 downto wordSize-conv_integer(memARead(wordPower-1 downto 0))-1) <= (others => '0'); + end if; + end if; + memAWriteEnable <= '1'; + memAAddr <= sp + 1; + memBAddr <= sp + 2; + sp <= sp + 1; + when Decoded_Eqbranch => + sp <= sp + 2; + if (memBRead=0) then + pc <= memARead(maxAddrBit downto 0) + pc; + end if; + state <= State_ResyncDecode; + when Decoded_Neqbranch => + sp <= sp + 2; + if (memBRead/=0) then + pc <= memARead(maxAddrBit downto 0) + pc; + end if; + state <= State_ResyncDecode; + when Decoded_Eq => + sp <= sp + 1; + memAWrite <= (others => '0'); + if (memARead=memBRead) then + memAWrite(0) <= '1'; + end if; + memAAddr <= sp + 1; + memAWriteEnable <= '1'; + memBAddr <= sp + 2; + when Decoded_Neq => + sp <= sp + 1; + memAWrite <= (others => '0'); + if (memARead/=memBRead) then + memAWrite(0) <= '1'; + end if; + memAAddr <= sp + 1; + memAWriteEnable <= '1'; + memBAddr <= sp + 2; + when Decoded_Ulessthan => + sp <= sp + 1; + memAWrite <= (others => '0'); + if (memARead + sp <= sp + 1; + memAWrite <= (others => '0'); + if (memARead<=memBRead) then + memAWrite(0) <= '1'; + end if; + memAAddr <= sp + 1; + memAWriteEnable <= '1'; + memBAddr <= sp + 2; + when Decoded_Lessthan => + sp <= sp + 1; + memAWrite <= (others => '0'); + compareA := signed(memARead); + compareB := signed(memBRead); + if (compareA + sp <= sp + 1; + memAWrite <= (others => '0'); + compareA := signed(memARead); + compareB := signed(memBRead); + if (compareA<=compareB) then + memAWrite(0) <= '1'; + end if; + memAAddr <= sp + 1; + memAWriteEnable <= '1'; + memBAddr <= sp + 2; + when Decoded_Loadb => + byteSelect <= memARead(minAddrBit-1 downto 0); + memAAddr <= memARead(maxAddrBit downto minAddrBit); + state <= State_LoadByte1; + when Decoded_Storeb => + sp <= sp + 2; + byteSelect <= memARead(minAddrBit-1 downto 0); + storeByte <= memBRead(7 downto 0); + memAAddr <= memARead(maxAddrBit downto minAddrBit); + memBAddr <= sp; + state <= State_StoreByte1; + when Decoded_Mult16x16 => + mult1 <= memARead(wordSize/2-1 downto 0); + mult2 <= memBRead(wordSize/2-1 downto 0); + sp <= sp + 1; + state <= State_Mult1; + when others => + -- nop. Here we persist whatever was loaded into + -- memARead + memAAddr <= sp; + memAWriteEnable <= '1'; + memAWrite <= memARead; + memBAddr <= sp + 1; + + end case; + when State_ReadIO => + state <= State_ReadIODone; + when State_ReadIODone => + if (in_mem_busy = '0') then + state <= State_ResyncDecode; + memAWriteEnable <= '1'; + memAWrite <= (others => '0'); + memAWrite <= mem_read; + memAAddr <= sp; + end if; + when State_WriteIO => + state <= State_WriteIODone; + when State_WriteIODone => + if (in_mem_busy = '0') then + state <= State_ResyncDecode; + end if; + when State_ResyncDecode => + memAAddr <= pc(maxAddrBit downto minAddrBit); + nextPC:=pc+1; + memBAddr <= nextPC(maxAddrBit downto minAddrBit); + state <= State_ResyncStack; + when State_ResyncStack => + memAAddr <= sp; + memBAddr <= sp+1; + state <= State_Decode; + when State_AddSP => + memAAddr <= pc(maxAddrBit downto minAddrBit); + nextPC:=pc+1; + memBAddr <= nextPC(maxAddrBit downto minAddrBit); + state <= State_Add; + when State_Add => + memAWriteEnable <= '1'; + memAWrite <= memARead + memBRead; + memAAddr <= sp; + memBAddr <= sp + 1; + state <= State_Decode; + when State_LoadByte1 => + memAAddr <= pc(maxAddrBit downto minAddrBit); + nextPC:=pc+1; + memBAddr <= nextPC(maxAddrBit downto minAddrBit); + state <= State_LoadByte2; + when State_LoadByte2 => + memAWriteEnable <= '1'; + memAAddr <= sp; + memAWrite <= (others => '0'); + case byteSelect is + when "00" => memAWrite(7 downto 0) <= memARead(31 downto 24); + when "01" => memAWrite(7 downto 0) <= memARead(23 downto 16); + when "10" => memAWrite(7 downto 0) <= memARead(15 downto 8); + when others => memAWrite(7 downto 0) <= memARead(7 downto 0); + end case; + memBAddr <= sp + 1; + state <= State_Decode; + when State_StoreByte1 => + state <= State_StoreByte2; + when State_StoreByte2 => + memAWriteEnable <= '1'; + memAAddr <= memBRead(maxAddrBit downto minAddrBit); + memAWrite <= memARead; + case byteSelect is + when "00" => memAWrite(31 downto 24) <= storeByte; + when "01" => memAWrite(23 downto 16) <= storeByte; + when "10" => memAWrite(15 downto 8) <= storeByte; + when others => memAWrite(7 downto 0) <= storeByte; + end case; + state <= State_ResyncDecode; + when State_Mult1 => + memAAddr <= pc(maxAddrBit downto minAddrBit); + nextPC:=pc+1; + memBAddr <= nextPC(maxAddrBit downto minAddrBit); + state <= State_Mult2; + when State_Mult2 => + memAWriteEnable <= '1'; + memAWrite <= multResult; + memAAddr <= sp; + memBAddr <= sp + 1; + state <= State_Decode; + + when others => + null; + end case; + end if; + end process; + + + +end behave; diff --git a/zpu/hdl/zpu4/src/zpu_core_small.vhd b/zpu/hdl/zpu4/src/zpu_core_small.vhd index 8ebd40d..4d73f88 100644 --- a/zpu/hdl/zpu4/src/zpu_core_small.vhd +++ b/zpu/hdl/zpu4/src/zpu_core_small.vhd @@ -27,19 +27,6 @@ end zpu_core; architecture behave of zpu_core is -component dualport_ram is -port (clk : in std_logic; - memAWriteEnable : in std_logic; - memAAddr : in std_logic_vector(maxAddrBitBRAM downto minAddrBit); - memAWrite : in std_logic_vector(wordSize-1 downto 0); - memARead : out std_logic_vector(wordSize-1 downto 0); - memBWriteEnable : in std_logic; - memBAddr : in std_logic_vector(maxAddrBitBRAM downto minAddrBit); - memBWrite : in std_logic_vector(wordSize-1 downto 0); - memBRead : out std_logic_vector(wordSize-1 downto 0)); -end component; - - signal readIO : std_logic; diff --git a/zpu/hdl/zpu4/src/zpupkg.vhd b/zpu/hdl/zpu4/src/zpupkg.vhd index fd00b9e..32e162b 100644 --- a/zpu/hdl/zpu4/src/zpupkg.vhd +++ b/zpu/hdl/zpu4/src/zpupkg.vhd @@ -24,6 +24,19 @@ package zpupkg is constant stack_size : integer := 2**stack_bits; + component dualport_ram is + port (clk : in std_logic; + memAWriteEnable : in std_logic; + memAAddr : in std_logic_vector(maxAddrBitBRAM downto minAddrBit); + memAWrite : in std_logic_vector(wordSize-1 downto 0); + memARead : out std_logic_vector(wordSize-1 downto 0); + memBWriteEnable : in std_logic; + memBAddr : in std_logic_vector(maxAddrBitBRAM downto minAddrBit); + memBWrite : in std_logic_vector(wordSize-1 downto 0); + memBRead : out std_logic_vector(wordSize-1 downto 0)); + end component; + + component dram is port (clk : in std_logic; areset : in std_logic; -- cgit v1.1