From d09fa3de9df02a66c5084623076ac3e167b58274 Mon Sep 17 00:00:00 2001 From: oharboe Date: Tue, 22 Apr 2008 05:52:16 +0000 Subject: * zpu/hdl/example_ghdl/ghdl_import.sh, zpu/hdl/example_ghdl/ghdl_make.sh, zpu/hdl/example_ghdl/ghdl_options.sh, zpu/hdl/example_ghdl/README: GHDL example * zpu/hdl/zpu4/src/dmipssmalltrace_ghdl.sh: testcase for GHDL * zpu/hdl/zpu4/src/dmipstrace_ghdl.sh: testcase for GHDL * zpu/hdl/zpu4/src/simzpu_medium_ghdl.sh: testcase for GHDL * zpu/hdl/example/helloworld.vhd, zpu/hdl/zpu4/src/bram_dmips.vhd, zpu/hdl/zpu4/src/dmipssmalltrace_ghdl.sh, zpu/hdl/zpu4/src/dram_dmips.vhd, zpu/hdl/zpu4/src/dram_hello.vhd, zpu/hdl/zpu4/src/io.vhd, zpu/hdl/zpu4/src/sim_fpga_top.vhd, zpu/hdl/zpu4/src/sim_small_fpga_top.vhd, zpu/hdl/zpu4/src/timer.vhd, zpu/hdl/zpu4/src/trace.vhd, zpu/hdl/zpu4/src/zpu_config_trace.vhd, zpu/hdl/zpu4/src/zpu_core_small.vhd, zpu/hdl/zpu4/src/zpu_core.vhd, zpu/hdl/zpu4/src/zpupkg.vhd: conversion to numeric_std --- zpu/hdl/zpu4/src/bram_dmips.vhd | 12 +- zpu/hdl/zpu4/src/dmipssmalltrace_ghdl.sh | 26 + zpu/hdl/zpu4/src/dmipstrace_ghdl.sh | 25 + zpu/hdl/zpu4/src/dram_dmips.vhd | 8 +- zpu/hdl/zpu4/src/dram_hello.vhd | 8 +- zpu/hdl/zpu4/src/io.vhd | 6 +- zpu/hdl/zpu4/src/log.txt | 414 +++++-- zpu/hdl/zpu4/src/sim_fpga_top.vhd | 377 ++++--- zpu/hdl/zpu4/src/sim_small_fpga_top.vhd | 356 +++--- zpu/hdl/zpu4/src/simzpu_medium_ghdl.sh | 25 + zpu/hdl/zpu4/src/timer.vhd | 6 +- zpu/hdl/zpu4/src/trace.vhd | 7 +- zpu/hdl/zpu4/src/zpu_config_trace.vhd | 1 - zpu/hdl/zpu4/src/zpu_core.vhd | 1795 +++++++++++++++--------------- zpu/hdl/zpu4/src/zpu_core_small.vhd | 880 ++++++++------- zpu/hdl/zpu4/src/zpupkg.vhd | 44 +- 16 files changed, 2149 insertions(+), 1841 deletions(-) create mode 100644 zpu/hdl/zpu4/src/dmipssmalltrace_ghdl.sh create mode 100644 zpu/hdl/zpu4/src/dmipstrace_ghdl.sh create mode 100644 zpu/hdl/zpu4/src/simzpu_medium_ghdl.sh (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 83bfc28..1d62d21 100644 --- a/zpu/hdl/zpu4/src/bram_dmips.vhd +++ b/zpu/hdl/zpu4/src/bram_dmips.vhd @@ -1,6 +1,6 @@ library ieee; use ieee.std_logic_1164.all; -use ieee.std_logic_unsigned.all; +use ieee.numeric_std.all; library work; @@ -22,7 +22,7 @@ end dualport_ram; architecture dualport_ram_arch of dualport_ram is -type ram_type is array(0 to ((2**(maxAddrBitBRAM+1))/4)-1) of std_logic_vector(wordSize-1 downto 0); +type ram_type is array(natural range 0 to ((2**(maxAddrBitBRAM+1))/4)-1) of std_logic_vector(wordSize-1 downto 0); shared variable ram : ram_type := ( @@ -3691,10 +3691,10 @@ begin end if; if (memAWriteEnable = '1') then - ram(conv_integer(memAAddr)) := memAWrite; + ram(to_integer(unsigned(memAAddr))) := memAWrite; memARead <= memAWrite; else - memARead <= ram(conv_integer(memAAddr)); + memARead <= ram(to_integer(unsigned(memAAddr))); end if; end if; end process; @@ -3703,10 +3703,10 @@ process (clk) begin if (clk'event and clk = '1') then if (memBWriteEnable = '1') then - ram(conv_integer(memBAddr)) := memBWrite; + ram(to_integer(unsigned(memBAddr))) := memBWrite; memBRead <= memBWrite; else - memBRead <= ram(conv_integer(memBAddr)); + memBRead <= ram(to_integer(unsigned(memBAddr))); end if; end if; end process; diff --git a/zpu/hdl/zpu4/src/dmipssmalltrace_ghdl.sh b/zpu/hdl/zpu4/src/dmipssmalltrace_ghdl.sh new file mode 100644 index 0000000..5e43b64 --- /dev/null +++ b/zpu/hdl/zpu4/src/dmipssmalltrace_ghdl.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +UNISIM_DIR="'location of GHDL objects for unisim library'/unisim_v93" +IMPORT_OPTIONS="--std=93 --ieee=synopsys --workdir=work -P${UNISIM_DIR}" +MAKE_OPTIONS="${IMPORT_OPTIONS} -Wl,-s -fexplicit --syn-binding" + +if test ! -e work; then + echo "Building work library..." + mkdir work + ghdl -i ${IMPORT_OPTIONS} zpu_config_trace.vhd + ghdl -i ${IMPORT_OPTIONS} zpupkg.vhd + ghdl -i ${IMPORT_OPTIONS} txt_util.vhd + ghdl -i ${IMPORT_OPTIONS} sim_fpga_top.vhd + ghdl -i ${IMPORT_OPTIONS} zpu_core_small.vhd + ghdl -i ${IMPORT_OPTIONS} bram_dmips.vhd + ghdl -i ${IMPORT_OPTIONS} dram_dmips.vhd + ghdl -i ${IMPORT_OPTIONS} timer.vhd + ghdl -i ${IMPORT_OPTIONS} io.vhd + ghdl -i ${IMPORT_OPTIONS} trace.vhd +fi + +echo "Compiling design..." +if ghdl -m ${MAKE_OPTIONS} fpga_top; then + echo "Compilation finished, start simulation with" + echo " ./fpga_top --stop-time=1ms" +fi diff --git a/zpu/hdl/zpu4/src/dmipstrace_ghdl.sh b/zpu/hdl/zpu4/src/dmipstrace_ghdl.sh new file mode 100644 index 0000000..3be392f --- /dev/null +++ b/zpu/hdl/zpu4/src/dmipstrace_ghdl.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +UNISIM_DIR="'location of GHDL objects for unisim library'/unisim_v93" +IMPORT_OPTIONS="--std=93 --ieee=synopsys --workdir=work -P${UNISIM_DIR}" +MAKE_OPTIONS="${IMPORT_OPTIONS} -Wl,-s -fexplicit --syn-binding" + +if test ! -e work; then + echo "Building work library..." + mkdir work + ghdl -i ${IMPORT_OPTIONS} zpu_config_trace.vhd + ghdl -i ${IMPORT_OPTIONS} zpupkg.vhd + ghdl -i ${IMPORT_OPTIONS} txt_util.vhd + ghdl -i ${IMPORT_OPTIONS} sim_fpga_top.vhd + ghdl -i ${IMPORT_OPTIONS} zpu_core.vhd + ghdl -i ${IMPORT_OPTIONS} dram_dmips.vhd + ghdl -i ${IMPORT_OPTIONS} timer.vhd + ghdl -i ${IMPORT_OPTIONS} io.vhd + ghdl -i ${IMPORT_OPTIONS} trace.vhd +fi + +echo "Compiling design..." +if ghdl -m ${MAKE_OPTIONS} fpga_top; then + echo "Compilation finished, start simulation with" + echo " ./fpga_top --stop-time=2500us" +fi diff --git a/zpu/hdl/zpu4/src/dram_dmips.vhd b/zpu/hdl/zpu4/src/dram_dmips.vhd index a289fd7..a9fd59e 100644 --- a/zpu/hdl/zpu4/src/dram_dmips.vhd +++ b/zpu/hdl/zpu4/src/dram_dmips.vhd @@ -1,6 +1,6 @@ library ieee; use ieee.std_logic_1164.all; -use ieee.std_logic_unsigned.all; +use ieee.numeric_std.all; library work; @@ -22,7 +22,7 @@ end dram; architecture dram_arch of dram is -type ram_type is array(0 to ((2**(maxAddrBitDRAM+1))/4)-1) of std_logic_vector(wordSize-1 downto 0); +type ram_type is array(natural range 0 to ((2**(maxAddrBitDRAM+1))/4)-1) of std_logic_vector(wordSize-1 downto 0); shared variable ram : ram_type := ( @@ -3294,10 +3294,10 @@ begin if areset = '1' then elsif (clk'event and clk = '1') then if (mem_writeEnable = '1') then - ram(conv_integer(mem_addr(maxAddrBit downto minAddrBit))) := mem_write; + ram(to_integer(unsigned(mem_addr(maxAddrBit downto minAddrBit)))) := mem_write; end if; if (mem_readEnable = '1') then - mem_read <= ram(conv_integer(mem_addr(maxAddrBit downto minAddrBit))); + mem_read <= ram(to_integer(unsigned(mem_addr(maxAddrBit downto minAddrBit)))); end if; end if; end process; diff --git a/zpu/hdl/zpu4/src/dram_hello.vhd b/zpu/hdl/zpu4/src/dram_hello.vhd index 3f7788a..4f02cca 100644 --- a/zpu/hdl/zpu4/src/dram_hello.vhd +++ b/zpu/hdl/zpu4/src/dram_hello.vhd @@ -1,6 +1,6 @@ library ieee; use ieee.std_logic_1164.all; -use ieee.std_logic_unsigned.all; +use ieee.numeric_std.all; library work; @@ -22,7 +22,7 @@ end dram; architecture dram_arch of dram is -type ram_type is array(0 to ((2**(maxAddrBitDRAM+1))/4)-1) of std_logic_vector(wordSize-1 downto 0); +type ram_type is array(natural range 0 to ((2**(maxAddrBitDRAM+1))/4)-1) of std_logic_vector(wordSize-1 downto 0); shared variable ram : ram_type := ( @@ -3093,10 +3093,10 @@ begin if areset = '1' then elsif (clk'event and clk = '1') then if (mem_writeEnable = '1') then - ram(conv_integer(mem_addr(maxAddrBit downto minAddrBit))) := mem_write; + ram(to_integer(unsigned(mem_addr(maxAddrBit downto minAddrBit)))) := mem_write; end if; if (mem_readEnable = '1') then - mem_read <= ram(conv_integer(mem_addr(maxAddrBit downto minAddrBit))); + mem_read <= ram(to_integer(unsigned(mem_addr(maxAddrBit downto minAddrBit)))); end if; end if; end process; diff --git a/zpu/hdl/zpu4/src/io.vhd b/zpu/hdl/zpu4/src/io.vhd index 7dbe36f..7a2601f 100644 --- a/zpu/hdl/zpu4/src/io.vhd +++ b/zpu/hdl/zpu4/src/io.vhd @@ -1,6 +1,6 @@ library ieee; use ieee.std_logic_1164.all; -use IEEE.STD_LOGIC_UNSIGNED.ALL; +use ieee.numeric_std.all; use std.textio.all; @@ -63,12 +63,12 @@ begin if addr=x"2028003" then -- Write to UART -- report "" & character'image(conv_integer(memBint)) severity note; - print(l_file, character'val(conv_integer(write))); + print(l_file, character'val(to_integer(unsigned(write)))); elsif addr(12)='1' then -- report "xxx" severity failure; -- timer_we <= '1'; else - print(l_file, character'val(conv_integer(write))); + print(l_file, character'val(to_integer(unsigned(write)))); report "Illegal IO write" severity warning; end if; diff --git a/zpu/hdl/zpu4/src/log.txt b/zpu/hdl/zpu4/src/log.txt index 47b8a65..7a82879 100644 --- a/zpu/hdl/zpu4/src/log.txt +++ b/zpu/hdl/zpu4/src/log.txt @@ -1,156 +1,380 @@ +H +e +l +l +o + +w +o +r +l +d + +1 -D -h -r -y -s -t -o -n + + + +H e +l +l +o -B -e -n -c -h -m -a +w +o r -k -, +l +d -V +2 + + + + + + +H e -r -s -i +l +l o -n -2 -. -1 +w +o +r +l +d -( -L -a -n -g -u -a -g +1 + + + + + + +H e -: +l +l +o + +w +o +r +l +d -C -) +2 -P +H +e +l +l +o + +w +o r +l +d + +1 + + + + + + +H +e +l +l +o + +w o -g r -a -m +l +d + +2 + + + + + + +H +e +l +l +o -c +w o -m -p -i +r l +d + +1 + + + + + + +H e +l +l +o + +w +o +r +l d +2 + + + + + + +H +e +l +l +o + w -i -t -h o -u -t +r +l +d + +1 + + + + + + +H +e +l +l +o -' +w +o r +l +d + +2 + + + + + + +H e -g -i -s -t +l +l +o + +w +o +r +l +d + +1 + + + + + + +H e +l +l +o + +w +o r -' +l +d + +2 + + + + + + +H +e +l +l +o -a -t -t +w +o r -i -b -u -t +l +d + +1 + + + + + + +H e +l +l +o + +w +o +r +l +d + +2 -E -x +H e -c -u -t -i +l +l o -n -s -t -a +w +o r -t -s -, +l +d -5 -0 -0 -0 -0 +1 + + + + + + +H +e +l +l +o +w +o r -u -n -s +l +d -t -h +2 + + + + + + +H +e +l +l +o + +w +o r +l +d + +1 + + + + + + +H +e +l +l o -u -g -h -D -h +w +o r -y -s -t +l +d + +2 + + + + + + +H +e +l +l o -n + +w +o +r +l +d + +1 + + + + + + +H e +l +l +o + +w +o +r +l +d + +2 + + + - diff --git a/zpu/hdl/zpu4/src/sim_fpga_top.vhd b/zpu/hdl/zpu4/src/sim_fpga_top.vhd index 4defc82..29151af 100644 --- a/zpu/hdl/zpu4/src/sim_fpga_top.vhd +++ b/zpu/hdl/zpu4/src/sim_fpga_top.vhd @@ -1,189 +1,188 @@ --------------------------------------------------------------------------------- --- Company: --- Engineer: --- --- Create Date: 20:15:31 04/14/05 --- Design Name: --- Module Name: fpga_top - behave --- Project Name: --- Target Device: --- Tool versions: --- Description: --- --- Dependencies: --- --- Revision: --- Revision 0.01 - File Created --- Additional Comments: --- --------------------------------------------------------------------------------- -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.STD_LOGIC_ARITH.ALL; -use IEEE.STD_LOGIC_UNSIGNED.ALL; - ----- Uncomment the following library declaration if instantiating ----- any Xilinx primitives in this code. -library UNISIM; -use UNISIM.VComponents.all; - -library work; -use work.zpu_config.all; -use work.zpupkg.all; - -entity fpga_top is -end fpga_top; - -architecture behave of fpga_top is - - -signal clk : std_logic; - -signal areset : std_logic; - - -component zpu_io is - generic ( - log_file: string := "log.txt" - ); - port( - clk : in std_logic; - areset : in std_logic; - busy : out std_logic; - writeEnable : in std_logic; - readEnable : in std_logic; - write : in std_logic_vector(wordSize-1 downto 0); - read : out std_logic_vector(wordSize-1 downto 0); - addr : in std_logic_vector(maxAddrBit downto minAddrBit) - ); -end component; - - - - - -signal mem_busy : std_logic; -signal mem_read : std_logic_vector(wordSize-1 downto 0); -signal mem_write : std_logic_vector(wordSize-1 downto 0); -signal mem_addr : std_logic_vector(maxAddrBitIncIO downto 0); -signal mem_writeEnable : std_logic; -signal mem_readEnable : std_logic; -signal mem_writeMask: std_logic_vector(wordBytes-1 downto 0); - -signal enable : std_logic; - -signal dram_mem_busy : std_logic; -signal dram_mem_read : std_logic_vector(wordSize-1 downto 0); -signal dram_mem_write : std_logic_vector(wordSize-1 downto 0); -signal dram_mem_writeEnable : std_logic; -signal dram_mem_readEnable : std_logic; -signal dram_mem_writeMask: std_logic_vector(wordBytes-1 downto 0); - - -signal io_busy : std_logic; - -signal io_mem_read : std_logic_vector(wordSize-1 downto 0); -signal io_mem_writeEnable : std_logic; -signal io_mem_readEnable : std_logic; - - -signal dram_ready : std_logic; -signal io_ready : std_logic; -signal io_reading : std_logic; - - -signal break : std_logic; - -begin - poweronreset: roc port map (O => areset); - - - - zpu: zpu_core port map ( - clk => clk , - areset => areset, - enable => enable, - in_mem_busy => mem_busy, - mem_read => mem_read, - mem_write => mem_write, - out_mem_addr => mem_addr, - out_mem_writeEnable => mem_writeEnable, - out_mem_readEnable => mem_readEnable, - mem_writeMask => mem_writeMask, - interrupt => '0', - break => break); - - dram_imp: dram port map ( - clk => clk , - areset => areset, - mem_busy => dram_mem_busy, - mem_read => dram_mem_read, - mem_write => mem_write, - mem_addr => mem_addr(maxAddrBit downto 0), - mem_writeEnable => dram_mem_writeEnable, - mem_readEnable => dram_mem_readEnable, - mem_writeMask => mem_writeMask); - - - ioMap: zpu_io port map ( - clk => clk, - areset => areset, - busy => io_busy, - writeEnable => io_mem_writeEnable, - readEnable => io_mem_readEnable, - write => mem_write(wordSize-1 downto 0), - read => io_mem_read, - addr => mem_addr(maxAddrBit downto minAddrBit) - ); - - dram_mem_writeEnable <= mem_writeEnable and not mem_addr(ioBit); - dram_mem_readEnable <= mem_readEnable and not mem_addr(ioBit); - io_mem_writeEnable <= mem_writeEnable and mem_addr(ioBit); - io_mem_readEnable <= mem_readEnable and mem_addr(ioBit); - mem_busy <= io_busy or dram_mem_busy or io_busy; - - - - -- Memory reads either come from IO or DRAM. We need to pick the right one. - memorycontrol: - process(dram_mem_read, dram_ready, io_ready, io_mem_read) - begin - mem_read <= (others => 'U'); - if dram_ready='1' then - mem_read <= dram_mem_read; - end if; - - if io_ready='1' then - mem_read <= io_mem_read; - end if; - end process; - - - io_ready <= (io_reading or io_mem_readEnable) and not io_busy; - - memoryControlSync: - process(clk, areset) - begin - if areset = '1' then - enable <= '0'; - io_reading <= '0'; - dram_ready <= '0'; - elsif (clk'event and clk = '1') then - enable <= '1'; - io_reading <= io_busy or io_mem_readEnable; - dram_ready<=dram_mem_readEnable; - - end if; - end process; - - -- wiggle the clock @ 100MHz - clock : PROCESS - begin - clk <= '0'; - wait for 5 ns; - clk <= '1'; - wait for 5 ns; - end PROCESS clock; - - -end behave; +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 20:15:31 04/14/05 +-- Design Name: +-- Module Name: fpga_top - behave +-- Project Name: +-- Target Device: +-- Tool versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +-------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +---- Uncomment the following library declaration if instantiating +---- any Xilinx primitives in this code. +library UNISIM; +use UNISIM.VComponents.all; + +library work; +use work.zpu_config.all; + +entity fpga_top is +end fpga_top; + +use work.zpupkg.all; + +architecture behave of fpga_top is + + +signal clk : std_logic; + +signal areset : std_logic; + + +component zpu_io is + generic ( + log_file: string := "log.txt" + ); + port( + clk : in std_logic; + areset : in std_logic; + busy : out std_logic; + writeEnable : in std_logic; + readEnable : in std_logic; + write : in std_logic_vector(wordSize-1 downto 0); + read : out std_logic_vector(wordSize-1 downto 0); + addr : in std_logic_vector(maxAddrBit downto minAddrBit) + ); +end component; + + + + + +signal mem_busy : std_logic; +signal mem_read : std_logic_vector(wordSize-1 downto 0); +signal mem_write : std_logic_vector(wordSize-1 downto 0); +signal mem_addr : std_logic_vector(maxAddrBitIncIO downto 0); +signal mem_writeEnable : std_logic; +signal mem_readEnable : std_logic; +signal mem_writeMask: std_logic_vector(wordBytes-1 downto 0); + +signal enable : std_logic; + +signal dram_mem_busy : std_logic; +signal dram_mem_read : std_logic_vector(wordSize-1 downto 0); +signal dram_mem_write : std_logic_vector(wordSize-1 downto 0); +signal dram_mem_writeEnable : std_logic; +signal dram_mem_readEnable : std_logic; +signal dram_mem_writeMask: std_logic_vector(wordBytes-1 downto 0); + + +signal io_busy : std_logic; + +signal io_mem_read : std_logic_vector(wordSize-1 downto 0); +signal io_mem_writeEnable : std_logic; +signal io_mem_readEnable : std_logic; + + +signal dram_ready : std_logic; +signal io_ready : std_logic; +signal io_reading : std_logic; + + +signal break : std_logic; + +begin + poweronreset: roc port map (O => areset); + + + + zpu: zpu_core port map ( + clk => clk , + areset => areset, + enable => enable, + in_mem_busy => mem_busy, + mem_read => mem_read, + mem_write => mem_write, + out_mem_addr => mem_addr, + out_mem_writeEnable => mem_writeEnable, + out_mem_readEnable => mem_readEnable, + mem_writeMask => mem_writeMask, + interrupt => '0', + break => break); + + dram_imp: dram port map ( + clk => clk , + areset => areset, + mem_busy => dram_mem_busy, + mem_read => dram_mem_read, + mem_write => mem_write, + mem_addr => mem_addr(maxAddrBit downto 0), + mem_writeEnable => dram_mem_writeEnable, + mem_readEnable => dram_mem_readEnable, + mem_writeMask => mem_writeMask); + + + ioMap: zpu_io port map ( + clk => clk, + areset => areset, + busy => io_busy, + writeEnable => io_mem_writeEnable, + readEnable => io_mem_readEnable, + write => mem_write(wordSize-1 downto 0), + read => io_mem_read, + addr => mem_addr(maxAddrBit downto minAddrBit) + ); + + dram_mem_writeEnable <= mem_writeEnable and not mem_addr(ioBit); + dram_mem_readEnable <= mem_readEnable and not mem_addr(ioBit); + io_mem_writeEnable <= mem_writeEnable and mem_addr(ioBit); + io_mem_readEnable <= mem_readEnable and mem_addr(ioBit); + mem_busy <= io_busy or dram_mem_busy or io_busy; + + + + -- Memory reads either come from IO or DRAM. We need to pick the right one. + memorycontrol: + process(dram_mem_read, dram_ready, io_ready, io_mem_read) + begin + mem_read <= (others => 'U'); + if dram_ready='1' then + mem_read <= dram_mem_read; + end if; + + if io_ready='1' then + mem_read <= io_mem_read; + end if; + end process; + + + io_ready <= (io_reading or io_mem_readEnable) and not io_busy; + + memoryControlSync: + process(clk, areset) + begin + if areset = '1' then + enable <= '0'; + io_reading <= '0'; + dram_ready <= '0'; + elsif (clk'event and clk = '1') then + enable <= '1'; + io_reading <= io_busy or io_mem_readEnable; + dram_ready<=dram_mem_readEnable; + + end if; + end process; + + -- wiggle the clock @ 100MHz + clock : PROCESS + begin + clk <= '0'; + wait for 5 ns; + clk <= '1'; + wait for 5 ns; + end PROCESS clock; + + +end behave; diff --git a/zpu/hdl/zpu4/src/sim_small_fpga_top.vhd b/zpu/hdl/zpu4/src/sim_small_fpga_top.vhd index b51fea0..5c05881 100644 --- a/zpu/hdl/zpu4/src/sim_small_fpga_top.vhd +++ b/zpu/hdl/zpu4/src/sim_small_fpga_top.vhd @@ -1,179 +1,177 @@ --------------------------------------------------------------------------------- --- Company: --- Engineer: --- --- Create Date: 20:15:31 04/14/05 --- Design Name: --- Module Name: fpga_top - behave --- Project Name: --- Target Device: --- Tool versions: --- Description: --- --- Dependencies: --- --- Revision: --- Revision 0.01 - File Created --- Additional Comments: --- --------------------------------------------------------------------------------- -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.STD_LOGIC_ARITH.ALL; -use IEEE.STD_LOGIC_UNSIGNED.ALL; - ----- Uncomment the following library declaration if instantiating ----- any Xilinx primitives in this code. -library UNISIM; -use UNISIM.VComponents.all; - -library work; -use work.zpu_config.all; -use work.zpupkg.all; - -entity fpga_top is -end fpga_top; - -architecture behave of fpga_top is - - -signal clk : std_logic; - -signal areset : std_logic; - - -component zpu_io is - generic ( - log_file: string := "log.txt" - ); - port( - clk : in std_logic; - areset : in std_logic; - busy : out std_logic; - writeEnable : in std_logic; - readEnable : in std_logic; - write : in std_logic_vector(wordSize-1 downto 0); - read : out std_logic_vector(wordSize-1 downto 0); - addr : in std_logic_vector(maxAddrBit downto minAddrBit) - ); -end component; - - - - - -signal mem_busy : std_logic; -signal mem_read : std_logic_vector(wordSize-1 downto 0); -signal mem_write : std_logic_vector(wordSize-1 downto 0); -signal mem_addr : std_logic_vector(maxAddrBitIncIO downto 0); -signal mem_writeEnable : std_logic; -signal mem_readEnable : std_logic; -signal mem_writeMask: std_logic_vector(wordBytes-1 downto 0); - -signal enable : std_logic; - -signal dram_mem_busy : std_logic; -signal dram_mem_read : std_logic_vector(wordSize-1 downto 0); -signal dram_mem_write : std_logic_vector(wordSize-1 downto 0); -signal dram_mem_writeEnable : std_logic; -signal dram_mem_readEnable : std_logic; -signal dram_mem_writeMask: std_logic_vector(wordBytes-1 downto 0); - - -signal io_busy : std_logic; - -signal io_mem_read : std_logic_vector(wordSize-1 downto 0); -signal io_mem_writeEnable : std_logic; -signal io_mem_readEnable : std_logic; - - -signal dram_ready : std_logic; -signal io_ready : std_logic; -signal io_reading : std_logic; - - -signal break : std_logic; - -begin - poweronreset: roc port map (O => areset); - - - - zpu: zpu_core port map ( - clk => clk , - areset => areset, - enable => enable, - in_mem_busy => mem_busy, - mem_read => mem_read, - mem_write => mem_write, - out_mem_addr => mem_addr, - out_mem_writeEnable => mem_writeEnable, - out_mem_readEnable => mem_readEnable, - mem_writeMask => mem_writeMask, - interrupt => '0', - break => break); - - - ioMap: zpu_io port map ( - clk => clk, - areset => areset, - busy => io_busy, - writeEnable => io_mem_writeEnable, - readEnable => io_mem_readEnable, - write => mem_write, - read => io_mem_read, - addr => mem_addr(maxAddrBit downto minAddrBit) - ); - - dram_mem_writeEnable <= mem_writeEnable and not mem_addr(ioBit); - dram_mem_readEnable <= mem_readEnable and not mem_addr(ioBit); - io_mem_writeEnable <= mem_writeEnable and mem_addr(ioBit); - io_mem_readEnable <= mem_readEnable and mem_addr(ioBit); - mem_busy <= io_busy; - - - - -- Memory reads either come from IO or DRAM. We need to pick the right one. - memorycontrol: - process(dram_mem_read, dram_ready, io_ready, io_mem_read) - begin - mem_read <= (others => 'U'); - if dram_ready='1' then - mem_read <= dram_mem_read; - end if; - - if io_ready='1' then - mem_read <= (others => '0'); - mem_read <= io_mem_read; - end if; - end process; - - - io_ready <= (io_reading or io_mem_readEnable) and not io_busy; - - memoryControlSync: - process(clk, areset) - begin - if areset = '1' then - enable <= '0'; - io_reading <= '0'; - dram_ready <= '0'; - elsif (clk'event and clk = '1') then - enable <= '1'; - io_reading <= io_busy or io_mem_readEnable; - dram_ready<=dram_mem_readEnable; - - end if; - end process; - - -- wiggle the clock @ 100MHz - clock : PROCESS - begin - clk <= '0'; - wait for 5 ns; - clk <= '1'; - wait for 5 ns; - end PROCESS clock; - - -end behave; +-------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 20:15:31 04/14/05 +-- Design Name: +-- Module Name: fpga_top - behave +-- Project Name: +-- Target Device: +-- Tool versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +-------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +---- Uncomment the following library declaration if instantiating +---- any Xilinx primitives in this code. +library UNISIM; +use UNISIM.VComponents.all; + +library work; +use work.zpu_config.all; +use work.zpupkg.all; + +entity fpga_top is +end fpga_top; + +architecture behave of fpga_top is + + +signal clk : std_logic; + +signal areset : std_logic; + + +component zpu_io is + generic ( + log_file: string := "log.txt" + ); + port( + clk : in std_logic; + areset : in std_logic; + busy : out std_logic; + writeEnable : in std_logic; + readEnable : in std_logic; + write : in std_logic_vector(wordSize-1 downto 0); + read : out std_logic_vector(wordSize-1 downto 0); + addr : in std_logic_vector(maxAddrBit downto minAddrBit) + ); +end component; + + + + + +signal mem_busy : std_logic; +signal mem_read : std_logic_vector(wordSize-1 downto 0); +signal mem_write : std_logic_vector(wordSize-1 downto 0); +signal mem_addr : std_logic_vector(maxAddrBitIncIO downto 0); +signal mem_writeEnable : std_logic; +signal mem_readEnable : std_logic; +signal mem_writeMask: std_logic_vector(wordBytes-1 downto 0); + +signal enable : std_logic; + +signal dram_mem_busy : std_logic; +signal dram_mem_read : std_logic_vector(wordSize-1 downto 0); +signal dram_mem_write : std_logic_vector(wordSize-1 downto 0); +signal dram_mem_writeEnable : std_logic; +signal dram_mem_readEnable : std_logic; +signal dram_mem_writeMask: std_logic_vector(wordBytes-1 downto 0); + + +signal io_busy : std_logic; + +signal io_mem_read : std_logic_vector(wordSize-1 downto 0); +signal io_mem_writeEnable : std_logic; +signal io_mem_readEnable : std_logic; + + +signal dram_ready : std_logic; +signal io_ready : std_logic; +signal io_reading : std_logic; + + +signal break : std_logic; + +begin + poweronreset: roc port map (O => areset); + + + + zpu: zpu_core port map ( + clk => clk , + areset => areset, + enable => enable, + in_mem_busy => mem_busy, + mem_read => mem_read, + mem_write => mem_write, + out_mem_addr => mem_addr, + out_mem_writeEnable => mem_writeEnable, + out_mem_readEnable => mem_readEnable, + mem_writeMask => mem_writeMask, + interrupt => '0', + break => break); + + + ioMap: zpu_io port map ( + clk => clk, + areset => areset, + busy => io_busy, + writeEnable => io_mem_writeEnable, + readEnable => io_mem_readEnable, + write => mem_write, + read => io_mem_read, + addr => mem_addr(maxAddrBit downto minAddrBit) + ); + + dram_mem_writeEnable <= mem_writeEnable and not mem_addr(ioBit); + dram_mem_readEnable <= mem_readEnable and not mem_addr(ioBit); + io_mem_writeEnable <= mem_writeEnable and mem_addr(ioBit); + io_mem_readEnable <= mem_readEnable and mem_addr(ioBit); + mem_busy <= io_busy; + + + + -- Memory reads either come from IO or DRAM. We need to pick the right one. + memorycontrol: + process(dram_mem_read, dram_ready, io_ready, io_mem_read) + begin + mem_read <= (others => 'U'); + if dram_ready='1' then + mem_read <= dram_mem_read; + end if; + + if io_ready='1' then + mem_read <= (others => '0'); + mem_read <= io_mem_read; + end if; + end process; + + + io_ready <= (io_reading or io_mem_readEnable) and not io_busy; + + memoryControlSync: + process(clk, areset) + begin + if areset = '1' then + enable <= '0'; + io_reading <= '0'; + dram_ready <= '0'; + elsif (clk'event and clk = '1') then + enable <= '1'; + io_reading <= io_busy or io_mem_readEnable; + dram_ready<=dram_mem_readEnable; + + end if; + end process; + + -- wiggle the clock @ 100MHz + clock : PROCESS + begin + clk <= '0'; + wait for 5 ns; + clk <= '1'; + wait for 5 ns; + end PROCESS clock; + + +end behave; diff --git a/zpu/hdl/zpu4/src/simzpu_medium_ghdl.sh b/zpu/hdl/zpu4/src/simzpu_medium_ghdl.sh new file mode 100644 index 0000000..7a7f3df --- /dev/null +++ b/zpu/hdl/zpu4/src/simzpu_medium_ghdl.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +UNISIM_DIR="'location of GHDL objects for unisim library'/unisim_v93" +IMPORT_OPTIONS="--std=93 --ieee=synopsys --workdir=work -P${UNISIM_DIR}" +MAKE_OPTIONS="${IMPORT_OPTIONS} -Wl,-s -fexplicit --syn-binding" + +if test ! -e work; then + echo "Building work library..." + mkdir work + ghdl -i ${IMPORT_OPTIONS} zpu_config_trace.vhd + ghdl -i ${IMPORT_OPTIONS} zpupkg.vhd + ghdl -i ${IMPORT_OPTIONS} txt_util.vhd + ghdl -i ${IMPORT_OPTIONS} sim_fpga_top.vhd + ghdl -i ${IMPORT_OPTIONS} zpu_core.vhd + ghdl -i ${IMPORT_OPTIONS} dram_hello.vhd + ghdl -i ${IMPORT_OPTIONS} timer.vhd + ghdl -i ${IMPORT_OPTIONS} io.vhd + ghdl -i ${IMPORT_OPTIONS} trace.vhd +fi + +echo "Compiling design..." +if ghdl -m ${MAKE_OPTIONS} fpga_top; then + echo "Compilation finished, start simulation with" + echo " ./fpga_top --stop-time=1ms" +fi diff --git a/zpu/hdl/zpu4/src/timer.vhd b/zpu/hdl/zpu4/src/timer.vhd index 60c8fe2..be1dbb8 100644 --- a/zpu/hdl/zpu4/src/timer.vhd +++ b/zpu/hdl/zpu4/src/timer.vhd @@ -1,6 +1,6 @@ library ieee; use ieee.std_logic_1164.all; -use IEEE.STD_LOGIC_UNSIGNED.ALL; +use ieee.numeric_std.all; entity timer is port( @@ -19,7 +19,7 @@ signal sample : std_logic; signal reset : std_logic; -signal cnt : std_logic_vector(63 downto 0); +signal cnt : unsigned(63 downto 0); signal cnt_smp : std_logic_vector(63 downto 0); begin @@ -36,7 +36,7 @@ begin cnt <= cnt + 1; if sample = '1' then -- report "sampling" severity failure; - cnt_smp <= cnt; + cnt_smp <= std_logic_vector(cnt); end if; end if; end process; diff --git a/zpu/hdl/zpu4/src/trace.vhd b/zpu/hdl/zpu4/src/trace.vhd index bc5279f..e687aaf 100644 --- a/zpu/hdl/zpu4/src/trace.vhd +++ b/zpu/hdl/zpu4/src/trace.vhd @@ -1,7 +1,6 @@ library ieee; use ieee.std_logic_1164.all; ---use IEEE.STD_LOGIC_ARITH.ALL; -use IEEE.STD_LOGIC_UNSIGNED.ALL; +use ieee.numeric_std.all; use std.textio.all; @@ -45,7 +44,7 @@ receive_data: process variable l: line; variable t : std_logic_vector(wordSize-1 downto 0); variable t2 : std_logic_vector(maxAddrBitIncIO downto 0); -variable counter : std_logic_vector(63 downto 0); +variable counter : unsigned(63 downto 0); @@ -69,7 +68,7 @@ counter := (others => '0'); if begin_inst = '1' then t(maxAddrBitIncIO downto 2):=sp; t2:=pc; - print(l_file, "0x" & hstr(t2) & " 0x" & hstr(opcode) & " 0x" & hstr(t) & " 0x" & hstr(memA) & " 0x" & hstr(memB) & " 0x" & hstr(intSp) & " 0x" & hstr(counter)); + print(l_file, "0x" & hstr(t2) & " 0x" & hstr(opcode) & " 0x" & hstr(t) & " 0x" & hstr(memA) & " 0x" & hstr(memB) & " 0x" & hstr(intSp) & " 0x" & hstr(std_logic_vector(counter))); end if; wait until clk = '0'; diff --git a/zpu/hdl/zpu4/src/zpu_config_trace.vhd b/zpu/hdl/zpu4/src/zpu_config_trace.vhd index 4d0f15f..d765d9a 100644 --- a/zpu/hdl/zpu4/src/zpu_config_trace.vhd +++ b/zpu/hdl/zpu4/src/zpu_config_trace.vhd @@ -1,6 +1,5 @@ library ieee; use ieee.std_logic_1164.all; -use ieee.std_logic_unsigned.all; package zpu_config is diff --git a/zpu/hdl/zpu4/src/zpu_core.vhd b/zpu/hdl/zpu4/src/zpu_core.vhd index a603fe9..37fa2d1 100644 --- a/zpu/hdl/zpu4/src/zpu_core.vhd +++ b/zpu/hdl/zpu4/src/zpu_core.vhd @@ -1,898 +1,897 @@ - --- Company: ZPU4 generic memory interface CPU --- 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; - - --- mem_writeEnable - set to '1' for a single cycle to send off a write request. --- mem_write is valid only while mem_writeEnable='1'. --- mem_readEnable - set to '1' for a single cycle to send off a read request. --- --- mem_busy - It is illegal to send off a read/write request when mem_busy='1'. --- Set to '0' when mem_read is valid after a read request. --- If it goes to '1'(busy), it is on the cycle after mem_read/writeEnable --- is '1'. --- mem_addr - address for read/write request --- mem_read - read data. Valid only on the cycle after mem_busy='0' after --- mem_readEnable='1' for a single cycle. --- mem_write - data to write --- mem_writeMask - set to '1' for those bits that are to be written to memory upon --- write request --- break - set to '1' when CPU hits break instruction --- interrupt - set to '1' until interrupts are cleared by CPU. - - - - -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 - -type InsnType is -( -State_AddTop, -State_Dup, -State_DupStackB, -State_Pop, -State_Popdown, -State_Add, -State_Or, -State_And, -State_Store, -State_AddSP, -State_Shift, -State_Nop, -State_Im, -State_LoadSP, -State_StoreSP, -State_Emulate, -State_Load, -State_PushPC, -State_PushSP, -State_PopPC, -State_PopPCRel, -State_Not, -State_Flip, -State_PopSP, -State_Neqbranch, -State_Eq, -State_Loadb, -State_Mult, -State_Lessthan, -State_Lessthanorequal, -State_Ulessthanorequal, -State_Ulessthan, -State_Pushspadd, -State_Call, -State_Callpcrel, -State_Sub, -State_Break, -State_Storeb, -State_InsnFetch -); - -type StateType is -( -State_Load2, -State_Popped, -State_LoadSP2, -State_LoadSP3, -State_AddSP2, -State_Fetch, -State_Execute, -State_Decode, -State_Decode2, -State_Resync, - -State_StoreSP2, -State_Resync2, -State_Resync3, -State_Loadb2, -State_Storeb2, -State_Mult2, -State_Mult3, -State_Mult5, -State_Mult4, -State_BinaryOpResult2, -State_BinaryOpResult, -State_Idle -); - - -signal pc : std_logic_vector(maxAddrBitIncIO downto 0); -signal sp : std_logic_vector(maxAddrBitIncIO downto minAddrBit); -signal incSp : std_logic_vector(maxAddrBitIncIO downto minAddrBit); -signal incIncSp : std_logic_vector(maxAddrBitIncIO downto minAddrBit); -signal decSp : std_logic_vector(maxAddrBitIncIO downto minAddrBit); -signal stackA : std_logic_vector(wordSize-1 downto 0); -signal binaryOpResult : std_logic_vector(wordSize-1 downto 0); -signal binaryOpResult2 : std_logic_vector(wordSize-1 downto 0); -signal multResult2 : std_logic_vector(wordSize-1 downto 0); -signal multResult3 : std_logic_vector(wordSize-1 downto 0); -signal multResult : std_logic_vector(wordSize-1 downto 0); -signal multA : std_logic_vector(wordSize-1 downto 0); -signal multB : std_logic_vector(wordSize-1 downto 0); -signal stackB : std_logic_vector(wordSize-1 downto 0); -signal idim_flag : std_logic; -signal busy : std_logic; -signal mem_writeEnable : std_logic; -signal mem_readEnable : std_logic; -signal mem_addr : std_logic_vector(maxAddrBitIncIO downto minAddrBit); -signal mem_delayAddr : std_logic_vector(maxAddrBitIncIO downto minAddrBit); -signal mem_delayReadEnable : std_logic; - -signal decodeWord : std_logic_vector(wordSize-1 downto 0); - - -signal state : StateType; -signal insn : InsnType; -type InsnArray is array(0 to wordBytes-1) of InsnType; -signal decodedOpcode : InsnArray; - -type OpcodeArray is array(0 to wordBytes-1) of std_logic_vector(7 downto 0); - -signal opcode : OpcodeArray; - - - - -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. - -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; - - - -- the memory subsystem will tell us one cycle later whether or - -- not it is busy - out_mem_writeEnable <= mem_writeEnable; - out_mem_readEnable <= mem_readEnable; - out_mem_addr(maxAddrBitIncIO downto minAddrBit) <= mem_addr; - out_mem_addr(minAddrBit-1 downto 0) <= (others => '0'); - - incSp <= sp + 1; - incIncSp <= sp + 2; - decSp <= sp - 1; - - - opcodeControl: - process(clk, areset) - variable tOpcode : std_logic_vector(OpCode_Size-1 downto 0); - variable spOffset : std_logic_vector(4 downto 0); - variable tSpOffset : std_logic_vector(4 downto 0); - variable nextPC : std_logic_vector(maxAddrBitIncIO downto 0); - variable tNextState : InsnType; - variable tDecodedOpcode : InsnArray; - variable tMultResult : std_logic_vector(wordSize*2-1 downto 0); - begin - if areset = '1' then - state <= State_Idle; - break <= '0'; - sp <= spStart(maxAddrBitIncIO downto minAddrBit); - - pc <= (others => '0'); - idim_flag <= '0'; - begin_inst <= '0'; - mem_writeEnable <= '0'; - mem_readEnable <= '0'; - multA <= (others => '0'); - multB <= (others => '0'); - mem_writeMask <= (others => '1'); - elsif (clk'event and clk = '1') then - -- we must multiply unconditionally to get pipelined multiplication - tMultResult := multA * multB; - multResult3 <= multResult2; - multResult2 <= multResult; - multResult <= tMultResult(wordSize-1 downto 0); - - - binaryOpResult2 <= binaryOpResult; -- pipeline a bit. - - - multA <= (others => DontCareValue); - multB <= (others => DontCareValue); - - - mem_addr <= (others => DontCareValue); - mem_readEnable <='0'; - mem_writeEnable <='0'; - mem_write <= (others => DontCareValue); - - if (mem_writeEnable = '1') and (mem_readEnable = '1') then - report "read/write collision" severity failure; - end if; - - - - - spOffset(4):=not opcode(conv_integer(pc(byteBits-1 downto 0)))(4); - spOffset(3 downto 0):=opcode(conv_integer(pc(byteBits-1 downto 0)))(3 downto 0); - nextPC := pc + 1; - - -- prepare trace snapshot - trace_opcode <= opcode(conv_integer(pc(byteBits-1 downto 0))); - trace_pc <= pc; - trace_sp <= sp; - trace_topOfStack <= stackA; - trace_topOfStackB <= stackB; - begin_inst <= '0'; - - - case state is - when State_Idle => - if enable='1' then - state <= State_Resync; - end if; - -- Initial state of ZPU, fetch top of stack + first instruction - when State_Resync => - if in_mem_busy='0' then - mem_addr <= sp; - mem_readEnable <= '1'; - state <= State_Resync2; - end if; - when State_Resync2 => - if in_mem_busy='0' then - stackA <= mem_read; - mem_addr <= incSp; - mem_readEnable <= '1'; - state <= State_Resync3; - end if; - when State_Resync3 => - if in_mem_busy='0' then - stackB <= mem_read; - mem_addr <= pc(maxAddrBitIncIO downto minAddrBit); - mem_readEnable <= '1'; - state <= State_Decode; - end if; - when State_Decode => - if in_mem_busy='0' then - decodeWord <= mem_read; - state <= State_Decode2; - end if; - when State_Decode2 => - -- decode 4 instructions in parallel - for i in 0 to wordBytes-1 loop - tOpcode := decodeWord((wordBytes-1-i+1)*8-1 downto (wordBytes-1-i)*8); - - tSpOffset(4):=not tOpcode(4); - tSpOffset(3 downto 0):=tOpcode(3 downto 0); - - opcode(i) <= tOpcode; - if (tOpcode(7 downto 7)=OpCode_Im) then - tNextState:=State_Im; - elsif (tOpcode(7 downto 5)=OpCode_StoreSP) then - if tSpOffset = 0 then - tNextState := State_Pop; - elsif tSpOffset=1 then - tNextState := State_PopDown; - else - tNextState :=State_StoreSP; - end if; - elsif (tOpcode(7 downto 5)=OpCode_LoadSP) then - if tSpOffset = 0 then - tNextState :=State_Dup; - elsif tSpOffset = 1 then - tNextState :=State_DupStackB; - else - tNextState :=State_LoadSP; - end if; - elsif (tOpcode(7 downto 5)=OpCode_Emulate) then - tNextState :=State_Emulate; - if tOpcode(5 downto 0)=OpCode_Neqbranch then - tNextState :=State_Neqbranch; - elsif tOpcode(5 downto 0)=OpCode_Eq then - tNextState :=State_Eq; - elsif tOpcode(5 downto 0)=OpCode_Lessthan then - tNextState :=State_Lessthan; - elsif tOpcode(5 downto 0)=OpCode_Lessthanorequal then - --tNextState :=State_Lessthanorequal; - elsif tOpcode(5 downto 0)=OpCode_Ulessthan then - tNextState :=State_Ulessthan; - elsif tOpcode(5 downto 0)=OpCode_Ulessthanorequal then - --tNextState :=State_Ulessthanorequal; - elsif tOpcode(5 downto 0)=OpCode_Loadb then - tNextState :=State_Loadb; - elsif tOpcode(5 downto 0)=OpCode_Mult then - tNextState :=State_Mult; - elsif tOpcode(5 downto 0)=OpCode_Storeb then - tNextState :=State_Storeb; - elsif tOpcode(5 downto 0)=OpCode_Pushspadd then - tNextState :=State_Pushspadd; - elsif tOpcode(5 downto 0)=OpCode_Callpcrel then - tNextState :=State_Callpcrel; - elsif tOpcode(5 downto 0)=OpCode_Call then - --tNextState :=State_Call; - elsif tOpcode(5 downto 0)=OpCode_Sub then - tNextState :=State_Sub; - elsif tOpcode(5 downto 0)=OpCode_PopPCRel then - --tNextState :=State_PopPCRel; - end if; - elsif (tOpcode(7 downto 4)=OpCode_AddSP) then - if tSpOffset = 0 then - tNextState := State_Shift; - elsif tSpOffset = 1 then - tNextState := State_AddTop; - else - tNextState :=State_AddSP; - end if; - else - case tOpcode(3 downto 0) is - when OpCode_Nop => - tNextState :=State_Nop; - when OpCode_PushSP => - tNextState :=State_PushSP; - when OpCode_PopPC => - tNextState :=State_PopPC; - when OpCode_Add => - tNextState :=State_Add; - when OpCode_Or => - tNextState :=State_Or; - when OpCode_And => - tNextState :=State_And; - when OpCode_Load => - tNextState :=State_Load; - when OpCode_Not => - tNextState :=State_Not; - when OpCode_Flip => - tNextState :=State_Flip; - when OpCode_Store => - tNextState :=State_Store; - when OpCode_PopSP => - tNextState :=State_PopSP; - when others => - tNextState := State_Break; - - end case; - end if; - tDecodedOpcode(i) := tNextState; - - end loop; - - insn <= tDecodedOpcode(conv_integer(pc(byteBits-1 downto 0))); - - -- once we wrap, we need to fetch - tDecodedOpcode(0) := State_InsnFetch; - - decodedOpcode <= tDecodedOpcode; - state <= State_Execute; - - - - -- Each instruction must: - -- - -- 1. set idim_flag - -- 2. increase pc if applicable - -- 3. set next state if appliable - -- 4. do it's operation - - when State_Execute => - insn <= decodedOpcode(conv_integer(nextPC(byteBits-1 downto 0))); - - case insn is - when State_InsnFetch => - state <= State_Fetch; - when State_Im => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '1'; - pc <= pc + 1; - - if idim_flag='1' then - stackA(wordSize-1 downto 7) <= stackA(wordSize-8 downto 0); - stackA(6 downto 0) <= opcode(conv_integer(pc(byteBits-1 downto 0)))(6 downto 0); - else - mem_writeEnable <= '1'; - mem_addr <= incSp; - mem_write <= stackB; - stackB <= stackA; - sp <= decSp; - for i in wordSize-1 downto 7 loop - stackA(i) <= opcode(conv_integer(pc(byteBits-1 downto 0)))(6); - end loop; - stackA(6 downto 0) <= opcode(conv_integer(pc(byteBits-1 downto 0)))(6 downto 0); - end if; - end if; - when State_StoreSP => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - state <= State_StoreSP2; - - mem_writeEnable <= '1'; - mem_addr <= sp+spOffset; - mem_write <= stackA; - stackA <= stackB; - sp <= incSp; - end if; - - - when State_LoadSP => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - state <= State_LoadSP2; - - sp <= decSp; - mem_writeEnable <= '1'; - mem_addr <= incSp; - mem_write <= stackB; - end if; - when State_Emulate => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - sp <= decSp; - mem_writeEnable <= '1'; - mem_addr <= incSp; - mem_write <= stackB; - stackA <= (others => DontCareValue); - stackA(maxAddrBitIncIO downto 0) <= pc + 1; - stackB <= stackA; - - -- The emulate address is: - -- 98 7654 3210 - -- 0000 00aa aaa0 0000 - pc <= (others => '0'); - pc(9 downto 5) <= opcode(conv_integer(pc(byteBits-1 downto 0)))(4 downto 0); - state <= State_Fetch; - end if; - when State_Callpcrel => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - stackA <= (others => DontCareValue); - stackA(maxAddrBitIncIO downto 0) <= pc + 1; - - pc <= pc + stackA(maxAddrBitIncIO downto 0); - state <= State_Fetch; - end if; - when State_Call => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - stackA <= (others => DontCareValue); - stackA(maxAddrBitIncIO downto 0) <= pc + 1; - pc <= stackA(maxAddrBitIncIO downto 0); - state <= State_Fetch; - end if; - when State_AddSP => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - state <= State_AddSP2; - - mem_readEnable <= '1'; - mem_addr <= sp+spOffset; - end if; - when State_PushSP => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - pc <= pc + 1; - - sp <= decSp; - stackA <= (others => '0'); - stackA(maxAddrBitIncIO downto minAddrBit) <= sp; - stackB <= stackA; - mem_writeEnable <= '1'; - mem_addr <= incSp; - mem_write <= stackB; - end if; - when State_PopPC => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - pc <= stackA(maxAddrBitIncIO downto 0); - sp <= incSp; - - mem_writeEnable <= '1'; - mem_addr <= incSp; - mem_write <= stackB; - state <= State_Resync; - end if; - when State_PopPCRel => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - pc <= stackA(maxAddrBitIncIO downto 0) + pc; - sp <= incSp; - - mem_writeEnable <= '1'; - mem_addr <= incSp; - mem_write <= stackB; - state <= State_Resync; - end if; - when State_Add => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - stackA <= stackA + stackB; - - mem_readEnable <= '1'; - mem_addr <= incIncSp; - sp <= incSp; - state <= State_Popped; - end if; - when State_Sub => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - binaryOpResult <= stackB - stackA; - state <= State_BinaryOpResult; - end if; - when State_Pop => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - mem_addr <= incIncSp; - mem_readEnable <= '1'; - sp <= incSp; - stackA <= stackB; - state <= State_Popped; - end if; - when State_PopDown => - if in_mem_busy='0' then - -- PopDown leaves top of stack unchanged - begin_inst <= '1'; - idim_flag <= '0'; - mem_addr <= incIncSp; - mem_readEnable <= '1'; - sp <= incSp; - state <= State_Popped; - end if; - when State_Or => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - stackA <= stackA or stackB; - mem_readEnable <= '1'; - mem_addr <= incIncSp; - sp <= incSp; - state <= State_Popped; - end if; - when State_And => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - - stackA <= stackA and stackB; - mem_readEnable <= '1'; - mem_addr <= incIncSp; - sp <= incSp; - state <= State_Popped; - end if; - when State_Eq => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - - binaryOpResult <= (others => '0'); - if (stackA=stackB) then - binaryOpResult(0) <= '1'; - end if; - state <= State_BinaryOpResult; - end if; - when State_Ulessthan => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - - binaryOpResult <= (others => '0'); - if (stackA - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - - binaryOpResult <= (others => '0'); - if (stackA<=stackB) then - binaryOpResult(0) <= '1'; - end if; - state <= State_BinaryOpResult; - end if; - when State_Lessthan => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - - binaryOpResult <= (others => '0'); - if (signed(stackA) - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - - binaryOpResult <= (others => '0'); - if (signed(stackA)<=signed(stackB)) then - binaryOpResult(0) <= '1'; - end if; - state <= State_BinaryOpResult; - end if; - when State_Load => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - state <= State_Load2; - - mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit); - mem_readEnable <= '1'; - end if; - - when State_Dup => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - pc <= pc + 1; - - sp <= decSp; - stackB <= stackA; - mem_write <= stackB; - mem_addr <= incSp; - mem_writeEnable <= '1'; - end if; - when State_DupStackB => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - pc <= pc + 1; - - sp <= decSp; - stackA <= stackB; - stackB <= stackA; - mem_write <= stackB; - mem_addr <= incSp; - mem_writeEnable <= '1'; - end if; - when State_Store => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - pc <= pc + 1; - mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit); - mem_write <= stackB; - mem_writeEnable <= '1'; - sp <= incIncSp; - state <= State_Resync; - end if; - when State_PopSP => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - pc <= pc + 1; - - mem_write <= stackB; - mem_addr <= incSp; - mem_writeEnable <= '1'; - sp <= stackA(maxAddrBitIncIO downto minAddrBit); - state <= State_Resync; - end if; - when State_Nop => - begin_inst <= '1'; - idim_flag <= '0'; - pc <= pc + 1; - when State_Not => - begin_inst <= '1'; - idim_flag <= '0'; - pc <= pc + 1; - - stackA <= not stackA; - when State_Flip => - begin_inst <= '1'; - idim_flag <= '0'; - pc <= pc + 1; - - for i in 0 to wordSize-1 loop - stackA(i) <= stackA(wordSize-1-i); - end loop; - when State_AddTop => - begin_inst <= '1'; - idim_flag <= '0'; - pc <= pc + 1; - - stackA <= stackA + stackB; - when State_Shift => - begin_inst <= '1'; - idim_flag <= '0'; - pc <= pc + 1; - - stackA(wordSize-1 downto 1) <= stackA(wordSize-2 downto 0); - stackA(0) <= '0'; - when State_Pushspadd => - begin_inst <= '1'; - idim_flag <= '0'; - pc <= pc + 1; - - stackA <= (others => '0'); - stackA(maxAddrBitIncIO downto minAddrBit) <= stackA(maxAddrBitIncIO-minAddrBit downto 0)+sp; - when State_Neqbranch => - -- branches are almost always taken as they form loops - begin_inst <= '1'; - idim_flag <= '0'; - sp <= incIncSp; - if (stackB/=0) then - pc <= stackA(maxAddrBitIncIO downto 0) + pc; - else - pc <= pc + 1; - end if; - -- need to fetch stack again. - state <= State_Resync; - when State_Mult => - begin_inst <= '1'; - idim_flag <= '0'; - - multA <= stackA; - multB <= stackB; - state <= State_Mult2; - when State_Break => - report "Break instruction encountered" severity failure; - break <= '1'; - - when State_Loadb => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - state <= State_Loadb2; - - mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit); - mem_readEnable <= '1'; - end if; - when State_Storeb => - if in_mem_busy='0' then - begin_inst <= '1'; - idim_flag <= '0'; - state <= State_Storeb2; - - mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit); - mem_readEnable <= '1'; - end if; - - when others => - sp <= (others => DontCareValue); - report "Illegal instruction" severity failure; - break <= '1'; - end case; - - - when State_StoreSP2 => - if in_mem_busy='0' then - mem_addr <= incSp; - mem_readEnable <= '1'; - state <= State_Popped; - end if; - when State_LoadSP2 => - if in_mem_busy='0' then - state <= State_LoadSP3; - mem_readEnable <= '1'; - mem_addr <= sp+spOffset+1; - end if; - when State_LoadSP3 => - if in_mem_busy='0' then - pc <= pc + 1; - state <= State_Execute; - stackB <= stackA; - stackA <= mem_read; - end if; - when State_AddSP2 => - if in_mem_busy='0' then - pc <= pc + 1; - state <= State_Execute; - stackA <= stackA + mem_read; - end if; - when State_Load2 => - if in_mem_busy='0' then - stackA <= mem_read; - pc <= pc + 1; - state <= State_Execute; - end if; - when State_Loadb2 => - if in_mem_busy='0' then - stackA <= (others => '0'); - stackA(7 downto 0) <= mem_read(((wordBytes-1-conv_integer(stackA(byteBits-1 downto 0)))*8+7) downto (wordBytes-1-conv_integer(stackA(byteBits-1 downto 0)))*8); - pc <= pc + 1; - state <= State_Execute; - end if; - when State_Storeb2 => - if in_mem_busy='0' then - mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit); - mem_write <= mem_read; - mem_write(((wordBytes-1-conv_integer(stackA(byteBits-1 downto 0)))*8+7) downto (wordBytes-1-conv_integer(stackA(byteBits-1 downto 0)))*8) <= stackB(7 downto 0) ; - mem_writeEnable <= '1'; - pc <= pc + 1; - sp <= incIncSp; - state <= State_Resync; - end if; - when State_Fetch => - if in_mem_busy='0' then - mem_addr <= pc(maxAddrBitIncIO downto minAddrBit); - mem_readEnable <= '1'; - state <= State_Decode; - end if; - when State_Mult2 => - state <= State_Mult3; - when State_Mult3 => - state <= State_Mult4; - when State_Mult4 => - state <= State_Mult5; - when State_Mult5 => - if in_mem_busy='0' then - stackA <= multResult3; - mem_readEnable <= '1'; - mem_addr <= incIncSp; - sp <= incSp; - state <= State_Popped; - end if; - when State_BinaryOpResult => - state <= State_BinaryOpResult2; - when State_BinaryOpResult2 => - mem_readEnable <= '1'; - mem_addr <= incIncSp; - sp <= incSp; - stackA <= binaryOpResult2; - state <= State_Popped; - when State_Popped => - if in_mem_busy='0' then - pc <= pc + 1; - stackB <= mem_read; - state <= State_Execute; - end if; - when others => - sp <= (others => DontCareValue); - report "Illegal state" severity failure; - break <= '1'; - end case; - end if; - end process; - - - -end behave; + +-- Company: ZPU4 generic memory interface CPU +-- Engineer: Øyvind Harboe + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use ieee.numeric_std.all; + +library work; +use work.zpu_config.all; +use work.zpupkg.all; + + +-- mem_writeEnable - set to '1' for a single cycle to send off a write request. +-- mem_write is valid only while mem_writeEnable='1'. +-- mem_readEnable - set to '1' for a single cycle to send off a read request. +-- +-- mem_busy - It is illegal to send off a read/write request when mem_busy='1'. +-- Set to '0' when mem_read is valid after a read request. +-- If it goes to '1'(busy), it is on the cycle after mem_read/writeEnable +-- is '1'. +-- mem_addr - address for read/write request +-- mem_read - read data. Valid only on the cycle after mem_busy='0' after +-- mem_readEnable='1' for a single cycle. +-- mem_write - data to write +-- mem_writeMask - set to '1' for those bits that are to be written to memory upon +-- write request +-- break - set to '1' when CPU hits break instruction +-- interrupt - set to '1' until interrupts are cleared by CPU. + + + + +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 + +type InsnType is +( +State_AddTop, +State_Dup, +State_DupStackB, +State_Pop, +State_Popdown, +State_Add, +State_Or, +State_And, +State_Store, +State_AddSP, +State_Shift, +State_Nop, +State_Im, +State_LoadSP, +State_StoreSP, +State_Emulate, +State_Load, +State_PushPC, +State_PushSP, +State_PopPC, +State_PopPCRel, +State_Not, +State_Flip, +State_PopSP, +State_Neqbranch, +State_Eq, +State_Loadb, +State_Mult, +State_Lessthan, +State_Lessthanorequal, +State_Ulessthanorequal, +State_Ulessthan, +State_Pushspadd, +State_Call, +State_Callpcrel, +State_Sub, +State_Break, +State_Storeb, +State_InsnFetch +); + +type StateType is +( +State_Load2, +State_Popped, +State_LoadSP2, +State_LoadSP3, +State_AddSP2, +State_Fetch, +State_Execute, +State_Decode, +State_Decode2, +State_Resync, + +State_StoreSP2, +State_Resync2, +State_Resync3, +State_Loadb2, +State_Storeb2, +State_Mult2, +State_Mult3, +State_Mult5, +State_Mult4, +State_BinaryOpResult2, +State_BinaryOpResult, +State_Idle +); + + +signal pc : unsigned(maxAddrBitIncIO downto 0); +signal sp : unsigned(maxAddrBitIncIO downto minAddrBit); +signal incSp : unsigned(maxAddrBitIncIO downto minAddrBit); +signal incIncSp : unsigned(maxAddrBitIncIO downto minAddrBit); +signal decSp : unsigned(maxAddrBitIncIO downto minAddrBit); +signal stackA : unsigned(wordSize-1 downto 0); +signal binaryOpResult : unsigned(wordSize-1 downto 0); +signal binaryOpResult2 : unsigned(wordSize-1 downto 0); +signal multResult2 : unsigned(wordSize-1 downto 0); +signal multResult3 : unsigned(wordSize-1 downto 0); +signal multResult : unsigned(wordSize-1 downto 0); +signal multA : unsigned(wordSize-1 downto 0); +signal multB : unsigned(wordSize-1 downto 0); +signal stackB : unsigned(wordSize-1 downto 0); +signal idim_flag : std_logic; +signal busy : std_logic; +signal mem_writeEnable : std_logic; +signal mem_readEnable : std_logic; +signal mem_addr : std_logic_vector(maxAddrBitIncIO downto minAddrBit); +signal mem_delayAddr : std_logic_vector(maxAddrBitIncIO downto minAddrBit); +signal mem_delayReadEnable : std_logic; + +signal decodeWord : std_logic_vector(wordSize-1 downto 0); + + +signal state : StateType; +signal insn : InsnType; +type InsnArray is array(0 to wordBytes-1) of InsnType; +signal decodedOpcode : InsnArray; + +type OpcodeArray is array(0 to wordBytes-1) of std_logic_vector(7 downto 0); + +signal opcode : OpcodeArray; + + + + +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. + +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; + + + -- the memory subsystem will tell us one cycle later whether or + -- not it is busy + out_mem_writeEnable <= mem_writeEnable; + out_mem_readEnable <= mem_readEnable; + out_mem_addr(maxAddrBitIncIO downto minAddrBit) <= mem_addr; + out_mem_addr(minAddrBit-1 downto 0) <= (others => '0'); + + incSp <= sp + 1; + incIncSp <= sp + 2; + decSp <= sp - 1; + + + opcodeControl: + process(clk, areset) + variable tOpcode : std_logic_vector(OpCode_Size-1 downto 0); + variable spOffset : unsigned(4 downto 0); + variable tSpOffset : unsigned(4 downto 0); + variable nextPC : unsigned(maxAddrBitIncIO downto 0); + variable tNextState : InsnType; + variable tDecodedOpcode : InsnArray; + variable tMultResult : unsigned(wordSize*2-1 downto 0); + begin + if areset = '1' then + state <= State_Idle; + break <= '0'; + sp <= unsigned(spStart(maxAddrBitIncIO downto minAddrBit)); + + pc <= (others => '0'); + idim_flag <= '0'; + begin_inst <= '0'; + mem_writeEnable <= '0'; + mem_readEnable <= '0'; + multA <= (others => '0'); + multB <= (others => '0'); + mem_writeMask <= (others => '1'); + elsif (clk'event and clk = '1') then + -- we must multiply unconditionally to get pipelined multiplication + tMultResult := multA * multB; + multResult3 <= multResult2; + multResult2 <= multResult; + multResult <= tMultResult(wordSize-1 downto 0); + + + binaryOpResult2 <= binaryOpResult; -- pipeline a bit. + + + multA <= (others => DontCareValue); + multB <= (others => DontCareValue); + + + mem_addr <= (others => DontCareValue); + mem_readEnable <='0'; + mem_writeEnable <='0'; + mem_write <= (others => DontCareValue); + + if (mem_writeEnable = '1') and (mem_readEnable = '1') then + report "read/write collision" severity failure; + end if; + + + + + spOffset(4):=not opcode(to_integer(pc(byteBits-1 downto 0)))(4); + spOffset(3 downto 0):=unsigned(opcode(to_integer(pc(byteBits-1 downto 0)))(3 downto 0)); + nextPC := pc + 1; + + -- prepare trace snapshot + trace_opcode <= opcode(to_integer(pc(byteBits-1 downto 0))); + trace_pc <= std_logic_vector(pc); + trace_sp <= std_logic_vector(sp); + trace_topOfStack <= std_logic_vector(stackA); + trace_topOfStackB <= std_logic_vector(stackB); + begin_inst <= '0'; + + + case state is + when State_Idle => + if enable='1' then + state <= State_Resync; + end if; + -- Initial state of ZPU, fetch top of stack + first instruction + when State_Resync => + if in_mem_busy='0' then + mem_addr <= std_logic_vector(sp); + mem_readEnable <= '1'; + state <= State_Resync2; + end if; + when State_Resync2 => + if in_mem_busy='0' then + stackA <= unsigned(mem_read); + mem_addr <= std_logic_vector(incSp); + mem_readEnable <= '1'; + state <= State_Resync3; + end if; + when State_Resync3 => + if in_mem_busy='0' then + stackB <= unsigned(mem_read); + mem_addr <= std_logic_vector(pc(maxAddrBitIncIO downto minAddrBit)); + mem_readEnable <= '1'; + state <= State_Decode; + end if; + when State_Decode => + if in_mem_busy='0' then + decodeWord <= mem_read; + state <= State_Decode2; + end if; + when State_Decode2 => + -- decode 4 instructions in parallel + for i in 0 to wordBytes-1 loop + tOpcode := decodeWord((wordBytes-1-i+1)*8-1 downto (wordBytes-1-i)*8); + + tSpOffset(4):=not tOpcode(4); + tSpOffset(3 downto 0):=unsigned(tOpcode(3 downto 0)); + + opcode(i) <= tOpcode; + if (tOpcode(7 downto 7)=OpCode_Im) then + tNextState:=State_Im; + elsif (tOpcode(7 downto 5)=OpCode_StoreSP) then + if tSpOffset = 0 then + tNextState := State_Pop; + elsif tSpOffset=1 then + tNextState := State_PopDown; + else + tNextState :=State_StoreSP; + end if; + elsif (tOpcode(7 downto 5)=OpCode_LoadSP) then + if tSpOffset = 0 then + tNextState :=State_Dup; + elsif tSpOffset = 1 then + tNextState :=State_DupStackB; + else + tNextState :=State_LoadSP; + end if; + elsif (tOpcode(7 downto 5)=OpCode_Emulate) then + tNextState :=State_Emulate; + if tOpcode(5 downto 0)=OpCode_Neqbranch then + tNextState :=State_Neqbranch; + elsif tOpcode(5 downto 0)=OpCode_Eq then + tNextState :=State_Eq; + elsif tOpcode(5 downto 0)=OpCode_Lessthan then + tNextState :=State_Lessthan; + elsif tOpcode(5 downto 0)=OpCode_Lessthanorequal then + --tNextState :=State_Lessthanorequal; + elsif tOpcode(5 downto 0)=OpCode_Ulessthan then + tNextState :=State_Ulessthan; + elsif tOpcode(5 downto 0)=OpCode_Ulessthanorequal then + --tNextState :=State_Ulessthanorequal; + elsif tOpcode(5 downto 0)=OpCode_Loadb then + tNextState :=State_Loadb; + elsif tOpcode(5 downto 0)=OpCode_Mult then + tNextState :=State_Mult; + elsif tOpcode(5 downto 0)=OpCode_Storeb then + tNextState :=State_Storeb; + elsif tOpcode(5 downto 0)=OpCode_Pushspadd then + tNextState :=State_Pushspadd; + elsif tOpcode(5 downto 0)=OpCode_Callpcrel then + tNextState :=State_Callpcrel; + elsif tOpcode(5 downto 0)=OpCode_Call then + --tNextState :=State_Call; + elsif tOpcode(5 downto 0)=OpCode_Sub then + tNextState :=State_Sub; + elsif tOpcode(5 downto 0)=OpCode_PopPCRel then + --tNextState :=State_PopPCRel; + end if; + elsif (tOpcode(7 downto 4)=OpCode_AddSP) then + if tSpOffset = 0 then + tNextState := State_Shift; + elsif tSpOffset = 1 then + tNextState := State_AddTop; + else + tNextState :=State_AddSP; + end if; + else + case tOpcode(3 downto 0) is + when OpCode_Nop => + tNextState :=State_Nop; + when OpCode_PushSP => + tNextState :=State_PushSP; + when OpCode_PopPC => + tNextState :=State_PopPC; + when OpCode_Add => + tNextState :=State_Add; + when OpCode_Or => + tNextState :=State_Or; + when OpCode_And => + tNextState :=State_And; + when OpCode_Load => + tNextState :=State_Load; + when OpCode_Not => + tNextState :=State_Not; + when OpCode_Flip => + tNextState :=State_Flip; + when OpCode_Store => + tNextState :=State_Store; + when OpCode_PopSP => + tNextState :=State_PopSP; + when others => + tNextState := State_Break; + + end case; + end if; + tDecodedOpcode(i) := tNextState; + + end loop; + + insn <= tDecodedOpcode(to_integer(pc(byteBits-1 downto 0))); + + -- once we wrap, we need to fetch + tDecodedOpcode(0) := State_InsnFetch; + + decodedOpcode <= tDecodedOpcode; + state <= State_Execute; + + + + -- Each instruction must: + -- + -- 1. set idim_flag + -- 2. increase pc if applicable + -- 3. set next state if appliable + -- 4. do it's operation + + when State_Execute => + insn <= decodedOpcode(to_integer(nextPC(byteBits-1 downto 0))); + + case insn is + when State_InsnFetch => + state <= State_Fetch; + when State_Im => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '1'; + pc <= pc + 1; + + if idim_flag='1' then + stackA(wordSize-1 downto 7) <= stackA(wordSize-8 downto 0); + stackA(6 downto 0) <= unsigned(opcode(to_integer(pc(byteBits-1 downto 0)))(6 downto 0)); + else + mem_writeEnable <= '1'; + mem_addr <= std_logic_vector(incSp); + mem_write <= std_logic_vector(stackB); + stackB <= stackA; + sp <= decSp; + for i in wordSize-1 downto 7 loop + stackA(i) <= opcode(to_integer(pc(byteBits-1 downto 0)))(6); + end loop; + stackA(6 downto 0) <= unsigned(opcode(to_integer(pc(byteBits-1 downto 0)))(6 downto 0)); + end if; + end if; + when State_StoreSP => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + state <= State_StoreSP2; + + mem_writeEnable <= '1'; + mem_addr <= std_logic_vector(sp+spOffset); + mem_write <= std_logic_vector(stackA); + stackA <= stackB; + sp <= incSp; + end if; + + + when State_LoadSP => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + state <= State_LoadSP2; + + sp <= decSp; + mem_writeEnable <= '1'; + mem_addr <= std_logic_vector(incSp); + mem_write <= std_logic_vector(stackB); + end if; + when State_Emulate => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + sp <= decSp; + mem_writeEnable <= '1'; + mem_addr <= std_logic_vector(incSp); + mem_write <= std_logic_vector(stackB); + stackA <= (others => DontCareValue); + stackA(maxAddrBitIncIO downto 0) <= pc + 1; + stackB <= stackA; + + -- The emulate address is: + -- 98 7654 3210 + -- 0000 00aa aaa0 0000 + pc <= (others => '0'); + pc(9 downto 5) <= unsigned(opcode(to_integer(pc(byteBits-1 downto 0)))(4 downto 0)); + state <= State_Fetch; + end if; + when State_Callpcrel => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + stackA <= (others => DontCareValue); + stackA(maxAddrBitIncIO downto 0) <= pc + 1; + + pc <= pc + stackA(maxAddrBitIncIO downto 0); + state <= State_Fetch; + end if; + when State_Call => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + stackA <= (others => DontCareValue); + stackA(maxAddrBitIncIO downto 0) <= pc + 1; + pc <= stackA(maxAddrBitIncIO downto 0); + state <= State_Fetch; + end if; + when State_AddSP => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + state <= State_AddSP2; + + mem_readEnable <= '1'; + mem_addr <= std_logic_vector(sp+spOffset); + end if; + when State_PushSP => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + pc <= pc + 1; + + sp <= decSp; + stackA <= (others => '0'); + stackA(maxAddrBitIncIO downto minAddrBit) <= sp; + stackB <= stackA; + mem_writeEnable <= '1'; + mem_addr <= std_logic_vector(incSp); + mem_write <= std_logic_vector(stackB); + end if; + when State_PopPC => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + pc <= stackA(maxAddrBitIncIO downto 0); + sp <= incSp; + + mem_writeEnable <= '1'; + mem_addr <= std_logic_vector(incSp); + mem_write <= std_logic_vector(stackB); + state <= State_Resync; + end if; + when State_PopPCRel => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + pc <= stackA(maxAddrBitIncIO downto 0) + pc; + sp <= incSp; + + mem_writeEnable <= '1'; + mem_addr <= std_logic_vector(incSp); + mem_write <= std_logic_vector(stackB); + state <= State_Resync; + end if; + when State_Add => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + stackA <= stackA + stackB; + + mem_readEnable <= '1'; + mem_addr <= std_logic_vector(incIncSp); + sp <= incSp; + state <= State_Popped; + end if; + when State_Sub => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + binaryOpResult <= stackB - stackA; + state <= State_BinaryOpResult; + end if; + when State_Pop => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + mem_addr <= std_logic_vector(incIncSp); + mem_readEnable <= '1'; + sp <= incSp; + stackA <= stackB; + state <= State_Popped; + end if; + when State_PopDown => + if in_mem_busy='0' then + -- PopDown leaves top of stack unchanged + begin_inst <= '1'; + idim_flag <= '0'; + mem_addr <= std_logic_vector(incIncSp); + mem_readEnable <= '1'; + sp <= incSp; + state <= State_Popped; + end if; + when State_Or => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + stackA <= stackA or stackB; + mem_readEnable <= '1'; + mem_addr <= std_logic_vector(incIncSp); + sp <= incSp; + state <= State_Popped; + end if; + when State_And => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + + stackA <= stackA and stackB; + mem_readEnable <= '1'; + mem_addr <= std_logic_vector(incIncSp); + sp <= incSp; + state <= State_Popped; + end if; + when State_Eq => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + + binaryOpResult <= (others => '0'); + if (stackA=stackB) then + binaryOpResult(0) <= '1'; + end if; + state <= State_BinaryOpResult; + end if; + when State_Ulessthan => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + + binaryOpResult <= (others => '0'); + if (stackA + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + + binaryOpResult <= (others => '0'); + if (stackA<=stackB) then + binaryOpResult(0) <= '1'; + end if; + state <= State_BinaryOpResult; + end if; + when State_Lessthan => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + + binaryOpResult <= (others => '0'); + if (signed(stackA) + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + + binaryOpResult <= (others => '0'); + if (signed(stackA)<=signed(stackB)) then + binaryOpResult(0) <= '1'; + end if; + state <= State_BinaryOpResult; + end if; + when State_Load => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + state <= State_Load2; + + mem_addr <= std_logic_vector(stackA(maxAddrBitIncIO downto minAddrBit)); + mem_readEnable <= '1'; + end if; + + when State_Dup => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + pc <= pc + 1; + + sp <= decSp; + stackB <= stackA; + mem_write <= std_logic_vector(stackB); + mem_addr <= std_logic_vector(incSp); + mem_writeEnable <= '1'; + end if; + when State_DupStackB => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + pc <= pc + 1; + + sp <= decSp; + stackA <= stackB; + stackB <= stackA; + mem_write <= std_logic_vector(stackB); + mem_addr <= std_logic_vector(incSp); + mem_writeEnable <= '1'; + end if; + when State_Store => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + pc <= pc + 1; + mem_addr <= std_logic_vector(stackA(maxAddrBitIncIO downto minAddrBit)); + mem_write <= std_logic_vector(stackB); + mem_writeEnable <= '1'; + sp <= incIncSp; + state <= State_Resync; + end if; + when State_PopSP => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + pc <= pc + 1; + + mem_write <= std_logic_vector(stackB); + mem_addr <= std_logic_vector(incSp); + mem_writeEnable <= '1'; + sp <= stackA(maxAddrBitIncIO downto minAddrBit); + state <= State_Resync; + end if; + when State_Nop => + begin_inst <= '1'; + idim_flag <= '0'; + pc <= pc + 1; + when State_Not => + begin_inst <= '1'; + idim_flag <= '0'; + pc <= pc + 1; + + stackA <= not stackA; + when State_Flip => + begin_inst <= '1'; + idim_flag <= '0'; + pc <= pc + 1; + + for i in 0 to wordSize-1 loop + stackA(i) <= stackA(wordSize-1-i); + end loop; + when State_AddTop => + begin_inst <= '1'; + idim_flag <= '0'; + pc <= pc + 1; + + stackA <= stackA + stackB; + when State_Shift => + begin_inst <= '1'; + idim_flag <= '0'; + pc <= pc + 1; + + stackA(wordSize-1 downto 1) <= stackA(wordSize-2 downto 0); + stackA(0) <= '0'; + when State_Pushspadd => + begin_inst <= '1'; + idim_flag <= '0'; + pc <= pc + 1; + + stackA <= (others => '0'); + stackA(maxAddrBitIncIO downto minAddrBit) <= stackA(maxAddrBitIncIO-minAddrBit downto 0)+sp; + when State_Neqbranch => + -- branches are almost always taken as they form loops + begin_inst <= '1'; + idim_flag <= '0'; + sp <= incIncSp; + if (stackB/=0) then + pc <= stackA(maxAddrBitIncIO downto 0) + pc; + else + pc <= pc + 1; + end if; + -- need to fetch stack again. + state <= State_Resync; + when State_Mult => + begin_inst <= '1'; + idim_flag <= '0'; + + multA <= stackA; + multB <= stackB; + state <= State_Mult2; + when State_Break => + report "Break instruction encountered" severity failure; + break <= '1'; + + when State_Loadb => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + state <= State_Loadb2; + + mem_addr <= std_logic_vector(stackA(maxAddrBitIncIO downto minAddrBit)); + mem_readEnable <= '1'; + end if; + when State_Storeb => + if in_mem_busy='0' then + begin_inst <= '1'; + idim_flag <= '0'; + state <= State_Storeb2; + + mem_addr <= std_logic_vector(stackA(maxAddrBitIncIO downto minAddrBit)); + mem_readEnable <= '1'; + end if; + + when others => + sp <= (others => DontCareValue); + report "Illegal instruction" severity failure; + break <= '1'; + end case; + + + when State_StoreSP2 => + if in_mem_busy='0' then + mem_addr <= std_logic_vector(incSp); + mem_readEnable <= '1'; + state <= State_Popped; + end if; + when State_LoadSP2 => + if in_mem_busy='0' then + state <= State_LoadSP3; + mem_readEnable <= '1'; + mem_addr <= std_logic_vector(sp+spOffset+1); + end if; + when State_LoadSP3 => + if in_mem_busy='0' then + pc <= pc + 1; + state <= State_Execute; + stackB <= stackA; + stackA <= unsigned(mem_read); + end if; + when State_AddSP2 => + if in_mem_busy='0' then + pc <= pc + 1; + state <= State_Execute; + stackA <= stackA + unsigned(mem_read); + end if; + when State_Load2 => + if in_mem_busy='0' then + stackA <= unsigned(mem_read); + pc <= pc + 1; + state <= State_Execute; + end if; + when State_Loadb2 => + if in_mem_busy='0' then + stackA <= (others => '0'); + stackA(7 downto 0) <= unsigned(mem_read(((wordBytes-1-to_integer(stackA(byteBits-1 downto 0)))*8+7) downto (wordBytes-1-to_integer(stackA(byteBits-1 downto 0)))*8)); + pc <= pc + 1; + state <= State_Execute; + end if; + when State_Storeb2 => + if in_mem_busy='0' then + mem_addr <= std_logic_vector(stackA(maxAddrBitIncIO downto minAddrBit)); + mem_write <= mem_read; + mem_write(((wordBytes-1-to_integer(stackA(byteBits-1 downto 0)))*8+7) downto (wordBytes-1-to_integer(stackA(byteBits-1 downto 0)))*8) <= std_logic_vector(stackB(7 downto 0)); + mem_writeEnable <= '1'; + pc <= pc + 1; + sp <= incIncSp; + state <= State_Resync; + end if; + when State_Fetch => + if in_mem_busy='0' then + mem_addr <= std_logic_vector(pc(maxAddrBitIncIO downto minAddrBit)); + mem_readEnable <= '1'; + state <= State_Decode; + end if; + when State_Mult2 => + state <= State_Mult3; + when State_Mult3 => + state <= State_Mult4; + when State_Mult4 => + state <= State_Mult5; + when State_Mult5 => + if in_mem_busy='0' then + stackA <= multResult3; + mem_readEnable <= '1'; + mem_addr <= std_logic_vector(incIncSp); + sp <= incSp; + state <= State_Popped; + end if; + when State_BinaryOpResult => + state <= State_BinaryOpResult2; + when State_BinaryOpResult2 => + mem_readEnable <= '1'; + mem_addr <= std_logic_vector(incIncSp); + sp <= incSp; + stackA <= binaryOpResult2; + state <= State_Popped; + when State_Popped => + if in_mem_busy='0' then + pc <= pc + 1; + stackB <= unsigned(mem_read); + state <= State_Execute; + end if; + when others => + sp <= (others => DontCareValue); + report "Illegal state" severity failure; + break <= '1'; + 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 4d73f88..0d734d2 100644 --- a/zpu/hdl/zpu4/src/zpu_core_small.vhd +++ b/zpu/hdl/zpu4/src/zpu_core_small.vhd @@ -1,433 +1,447 @@ --- Company: ZPU3 --- Engineer: Øyvind Harboe - -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.STD_LOGIC_UNSIGNED.ALL; - -library work; -use work.zpu_config.all; -use work.zpupkg.all; - - -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_Fetch, -State_WriteIODone, -State_Execute, -State_StoreToStack, -State_Add, -State_Or, -State_And, -State_Store, -State_ReadIO, -State_WriteIO, -State_Load, -State_FetchNext, -State_AddSP, -State_ReadIODone, -State_Decode, -State_Resync -); - -type DecodedOpcodeType is -( -Decoded_Nop, -Decoded_Im, -Decoded_ImShift, -Decoded_LoadSP, -Decoded_StoreSP , -Decoded_AddSP, -Decoded_Emulate, -Decoded_Break, -Decoded_PushSP, -Decoded_PopPC, -Decoded_Add, -Decoded_Or, -Decoded_And, -Decoded_Load, -Decoded_Not, -Decoded_Flip, -Decoded_Store, -Decoded_PopSP -); - - - -signal sampledOpcode : std_logic_vector(OpCode_Size-1 downto 0); -signal opcode : std_logic_vector(OpCode_Size-1 downto 0); - -signal decodedOpcode : DecodedOpcodeType; -signal sampledDecodedOpcode : 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 - ); - - - - decodeControl: - process(memBRead, pc) - variable tOpcode : std_logic_vector(OpCode_Size-1 downto 0); - begin - tOpcode := memBRead((wordBytes-1-conv_integer(pc(minAddrBit-1 downto 0))+1)*8-1 downto (wordBytes-1-conv_integer(pc(minAddrBit-1 downto 0)))*8); - - sampledOpcode <= tOpcode; - - if (tOpcode(7 downto 7)=OpCode_Im) then - sampledDecodedOpcode<=Decoded_Im; - elsif (tOpcode(7 downto 5)=OpCode_StoreSP) then - sampledDecodedOpcode<=Decoded_StoreSP; - elsif (tOpcode(7 downto 5)=OpCode_LoadSP) then - sampledDecodedOpcode<=Decoded_LoadSP; - elsif (tOpcode(7 downto 5)=OpCode_Emulate) then - sampledDecodedOpcode<=Decoded_Emulate; - elsif (tOpcode(7 downto 4)=OpCode_AddSP) then - sampledDecodedOpcode<=Decoded_AddSP; - else - case tOpcode(3 downto 0) is - when OpCode_Break => - sampledDecodedOpcode<=Decoded_Break; - when OpCode_PushSP => - sampledDecodedOpcode<=Decoded_PushSP; - when OpCode_PopPC => - sampledDecodedOpcode<=Decoded_PopPC; - when OpCode_Add => - sampledDecodedOpcode<=Decoded_Add; - when OpCode_Or => - sampledDecodedOpcode<=Decoded_Or; - when OpCode_And => - sampledDecodedOpcode<=Decoded_And; - when OpCode_Load => - sampledDecodedOpcode<=Decoded_Load; - when OpCode_Not => - sampledDecodedOpcode<=Decoded_Not; - when OpCode_Flip => - sampledDecodedOpcode<=Decoded_Flip; - when OpCode_Store => - sampledDecodedOpcode<=Decoded_Store; - when OpCode_PopSP => - sampledDecodedOpcode<=Decoded_PopSP; - when others => - sampledDecodedOpcode<=Decoded_Nop; - end case; - end if; - end process; - - - opcodeControl: - process(clk, areset) - variable spOffset : std_logic_vector(4 downto 0); - begin - if areset = '1' then - state <= State_Resync; - 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'; - memAWrite <= (others => '0'); - memBWrite <= (others => '0'); - mem_writeMask <= (others => '1'); - elsif (clk'event and clk = '1') then - memAWriteEnable <= '0'; - memBWriteEnable <= '0'; - -- This saves ca. 100 LUT's, by explicitly declaring that the - -- memAWrite can be left at whatever value if memAWriteEnable is - -- not set. - memAWrite <= (others => DontCareValue); - memBWrite <= (others => DontCareValue); --- out_mem_addr <= (others => DontCareValue); --- mem_write <= (others => DontCareValue); - spOffset := (others => DontCareValue); - memAAddr <= (others => DontCareValue); - memBAddr <= (others => DontCareValue); - - out_mem_writeEnable <= '0'; - out_mem_readEnable <= '0'; - begin_inst <= '0'; - out_mem_addr <= memARead(maxAddrBitIncIO downto 0); - mem_write <= memBRead; - - decodedOpcode <= sampledDecodedOpcode; - opcode <= sampledOpcode; - - case state is - when State_Execute => - state <= State_Fetch; - -- 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_opcode <= opcode; - trace_sp <= (others => '0'); - trace_sp(maxAddrBit downto minAddrBit) <= sp; - 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); - - idim_flag <= '0'; - case decodedOpcode is - when Decoded_Im => - idim_flag <= '1'; - memAWriteEnable <= '1'; - if (idim_flag='0') then - 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); - else - memAAddr <= sp; - memAWrite(wordSize-1 downto 7) <= memARead(wordSize-8 downto 0); - memAWrite(6 downto 0) <= opcode(6 downto 0); - end if; - when Decoded_StoreSP => - memBWriteEnable <= '1'; - memBAddr <= sp+spOffset; - memBWrite <= memARead; - sp <= sp + 1; - state <= State_Resync; - when Decoded_LoadSP => - sp <= sp - 1; - memAAddr <= sp+spOffset; - when Decoded_Emulate => - sp <= sp - 1; - memAWriteEnable <= '1'; - memAAddr <= sp - 1; - memAWrite <= (others => DontCareValue); - memAWrite(maxAddrBit downto 0) <= pc + 1; - -- The emulate address is: - -- 98 7654 3210 - -- 0000 00aa aaa0 0000 - pc <= (others => '0'); - pc(9 downto 5) <= opcode(4 downto 0); - when Decoded_AddSP => - memAAddr <= sp; - memBAddr <= sp+spOffset; - state <= State_AddSP; - 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; - when Decoded_PopPC => - pc <= memARead(maxAddrBit downto 0); - sp <= sp + 1; - state <= State_Resync; - when Decoded_Add => - sp <= sp + 1; - state <= State_Add; - when Decoded_Or => - sp <= sp + 1; - state <= State_Or; - when Decoded_And => - sp <= sp + 1; - state <= State_And; - 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); - end if; - when Decoded_Not => - memAAddr <= sp(maxAddrBit downto minAddrBit); - memAWriteEnable <= '1'; - memAWrite <= not memARead; - when Decoded_Flip => - memAAddr <= sp(maxAddrBit downto minAddrBit); - memAWriteEnable <= '1'; - for i in 0 to wordSize-1 loop - memAWrite(i) <= memARead(wordSize-1-i); - end loop; - when Decoded_Store => - memBAddr <= sp + 1; - sp <= sp + 1; - if (memARead(ioBit)='1') then - state <= State_WriteIO; - else - state <= State_Store; - end if; - when Decoded_PopSP => - sp <= memARead(maxAddrBit downto minAddrBit); - state <= State_Resync; - when Decoded_Nop => - memAAddr <= sp; - when others => - null; - end case; - when State_ReadIO => - if (in_mem_busy = '0') then - state <= State_Fetch; - memAWriteEnable <= '1'; - memAWrite <= mem_read; - end if; - when State_WriteIO => - sp <= sp + 1; - out_mem_writeEnable <= '1'; - out_mem_addr <= memARead(maxAddrBitIncIO downto 0); - mem_write <= memBRead; - state <= State_WriteIODone; - when State_WriteIODone => - if (in_mem_busy = '0') then - state <= State_Resync; - end if; - when State_Fetch => - -- We need to resync. During the *next* cycle - -- we'll fetch the opcode @ pc and thus it will - -- be available for State_Execute the cycle after - -- next - memBAddr <= pc(maxAddrBit downto minAddrBit); - state <= State_FetchNext; - when State_FetchNext => - -- at this point memARead contains the value that is either - -- from the top of stack or should be copied to the top of the stack - memAWriteEnable <= '1'; - memAWrite <= memARead; - memAAddr <= sp; - memBAddr <= sp + 1; - state <= State_Decode; - when State_Decode => - -- during the State_Execute cycle we'll be fetching SP+1 - memAAddr <= sp; - memBAddr <= sp + 1; - state <= State_Execute; - when State_Store => - sp <= sp + 1; - memAWriteEnable <= '1'; - memAAddr <= memARead(maxAddrBit downto minAddrBit); - memAWrite <= memBRead; - state <= State_Resync; - when State_AddSP => - state <= State_Add; - when State_Add => - memAAddr <= sp; - memAWriteEnable <= '1'; - memAWrite <= memARead + memBRead; - state <= State_Fetch; - when State_Or => - memAAddr <= sp; - memAWriteEnable <= '1'; - memAWrite <= memARead or memBRead; - state <= State_Fetch; - when State_Resync => - memAAddr <= sp; - state <= State_Fetch; - when State_And => - memAAddr <= sp; - memAWriteEnable <= '1'; - memAWrite <= memARead and memBRead; - state <= State_Fetch; - when others => - null; - end case; - - end if; - end process; - - - -end behave; +-- Company: ZPU3 +-- Engineer: Øyvind Harboe + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use ieee.numeric_std.all; + +library work; +use work.zpu_config.all; +use work.zpupkg.all; + + +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 : unsigned(maxAddrBit downto minAddrBit); +signal memAWrite : unsigned(wordSize-1 downto 0); +signal memARead : unsigned(wordSize-1 downto 0); +signal memBWriteEnable : std_logic; +signal memBAddr : unsigned(maxAddrBit downto minAddrBit); +signal memBWrite : unsigned(wordSize-1 downto 0); +signal memBRead : unsigned(wordSize-1 downto 0); + + + +signal pc : unsigned(maxAddrBit downto 0); +signal sp : unsigned(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_Fetch, +State_WriteIODone, +State_Execute, +State_StoreToStack, +State_Add, +State_Or, +State_And, +State_Store, +State_ReadIO, +State_WriteIO, +State_Load, +State_FetchNext, +State_AddSP, +State_ReadIODone, +State_Decode, +State_Resync +); + +type DecodedOpcodeType is +( +Decoded_Nop, +Decoded_Im, +Decoded_ImShift, +Decoded_LoadSP, +Decoded_StoreSP , +Decoded_AddSP, +Decoded_Emulate, +Decoded_Break, +Decoded_PushSP, +Decoded_PopPC, +Decoded_Add, +Decoded_Or, +Decoded_And, +Decoded_Load, +Decoded_Not, +Decoded_Flip, +Decoded_Store, +Decoded_PopSP +); + + + +signal sampledOpcode : std_logic_vector(OpCode_Size-1 downto 0); +signal opcode : std_logic_vector(OpCode_Size-1 downto 0); + +signal decodedOpcode : DecodedOpcodeType; +signal sampledDecodedOpcode : DecodedOpcodeType; + + +signal state : State_Type; + +subtype AddrBitBRAM_range is natural range maxAddrBitBRAM downto minAddrBit; +signal memAAddr_stdlogic : std_logic_vector(AddrBitBRAM_range); +signal memAWrite_stdlogic : std_logic_vector(memAWrite'range); +signal memARead_stdlogic : std_logic_vector(memARead'range); +signal memBAddr_stdlogic : std_logic_vector(AddrBitBRAM_range); +signal memBWrite_stdlogic : std_logic_vector(memBWrite'range); +signal memBRead_stdlogic : std_logic_vector(memBRead'range); + +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; + + + memAAddr_stdlogic <= std_logic_vector(memAAddr(AddrBitBRAM_range)); + memAWrite_stdlogic <= std_logic_vector(memAWrite); + memBAddr_stdlogic <= std_logic_vector(memBAddr(AddrBitBRAM_range)); + memBWrite_stdlogic <= std_logic_vector(memBWrite); + memory: dualport_ram port map ( + clk => clk, + memAWriteEnable => memAWriteEnable, + memAAddr => memAAddr_stdlogic, + memAWrite => memAWrite_stdlogic, + memARead => memARead_stdlogic, + memBWriteEnable => memBWriteEnable, + memBAddr => memBAddr_stdlogic, + memBWrite => memBWrite_stdlogic, + memBRead => memBRead_stdlogic + ); + memARead <= unsigned(memARead_stdlogic); + memBRead <= unsigned(memBRead_stdlogic); + + + + decodeControl: + process(memBRead, pc) + variable tOpcode : std_logic_vector(OpCode_Size-1 downto 0); + begin + tOpcode := std_logic_vector(memBRead((wordBytes-1-to_integer(pc(minAddrBit-1 downto 0))+1)*8-1 downto (wordBytes-1-to_integer(pc(minAddrBit-1 downto 0)))*8)); + + sampledOpcode <= tOpcode; + + if (tOpcode(7 downto 7)=OpCode_Im) then + sampledDecodedOpcode<=Decoded_Im; + elsif (tOpcode(7 downto 5)=OpCode_StoreSP) then + sampledDecodedOpcode<=Decoded_StoreSP; + elsif (tOpcode(7 downto 5)=OpCode_LoadSP) then + sampledDecodedOpcode<=Decoded_LoadSP; + elsif (tOpcode(7 downto 5)=OpCode_Emulate) then + sampledDecodedOpcode<=Decoded_Emulate; + elsif (tOpcode(7 downto 4)=OpCode_AddSP) then + sampledDecodedOpcode<=Decoded_AddSP; + else + case tOpcode(3 downto 0) is + when OpCode_Break => + sampledDecodedOpcode<=Decoded_Break; + when OpCode_PushSP => + sampledDecodedOpcode<=Decoded_PushSP; + when OpCode_PopPC => + sampledDecodedOpcode<=Decoded_PopPC; + when OpCode_Add => + sampledDecodedOpcode<=Decoded_Add; + when OpCode_Or => + sampledDecodedOpcode<=Decoded_Or; + when OpCode_And => + sampledDecodedOpcode<=Decoded_And; + when OpCode_Load => + sampledDecodedOpcode<=Decoded_Load; + when OpCode_Not => + sampledDecodedOpcode<=Decoded_Not; + when OpCode_Flip => + sampledDecodedOpcode<=Decoded_Flip; + when OpCode_Store => + sampledDecodedOpcode<=Decoded_Store; + when OpCode_PopSP => + sampledDecodedOpcode<=Decoded_PopSP; + when others => + sampledDecodedOpcode<=Decoded_Nop; + end case; + end if; + end process; + + + opcodeControl: + process(clk, areset) + variable spOffset : unsigned(4 downto 0); + begin + if areset = '1' then + state <= State_Resync; + break <= '0'; + sp <= unsigned(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'; + memAWrite <= (others => '0'); + memBWrite <= (others => '0'); + mem_writeMask <= (others => '1'); + elsif (clk'event and clk = '1') then + memAWriteEnable <= '0'; + memBWriteEnable <= '0'; + -- This saves ca. 100 LUT's, by explicitly declaring that the + -- memAWrite can be left at whatever value if memAWriteEnable is + -- not set. + memAWrite <= (others => DontCareValue); + memBWrite <= (others => DontCareValue); +-- out_mem_addr <= (others => DontCareValue); +-- mem_write <= (others => DontCareValue); + spOffset := (others => DontCareValue); + memAAddr <= (others => DontCareValue); + memBAddr <= (others => DontCareValue); + + out_mem_writeEnable <= '0'; + out_mem_readEnable <= '0'; + begin_inst <= '0'; + out_mem_addr <= std_logic_vector(memARead(maxAddrBitIncIO downto 0)); + mem_write <= std_logic_vector(memBRead); + + decodedOpcode <= sampledDecodedOpcode; + opcode <= sampledOpcode; + + case state is + when State_Execute => + state <= State_Fetch; + -- 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) <= std_logic_vector(pc); + trace_opcode <= opcode; + trace_sp <= (others => '0'); + trace_sp(maxAddrBit downto minAddrBit) <= std_logic_vector(sp); + trace_topOfStack <= std_logic_vector(memARead); + trace_topOfStackB <= std_logic_vector(memBRead); + + -- during the next cycle we'll be reading the next opcode + spOffset(4):=not opcode(4); + spOffset(3 downto 0) := unsigned(opcode(3 downto 0)); + + idim_flag <= '0'; + case decodedOpcode is + when Decoded_Im => + idim_flag <= '1'; + memAWriteEnable <= '1'; + if (idim_flag='0') then + sp <= sp - 1; + memAAddr <= sp-1; + for i in wordSize-1 downto 7 loop + memAWrite(i) <= opcode(6); + end loop; + memAWrite(6 downto 0) <= unsigned(opcode(6 downto 0)); + else + memAAddr <= sp; + memAWrite(wordSize-1 downto 7) <= memARead(wordSize-8 downto 0); + memAWrite(6 downto 0) <= unsigned(opcode(6 downto 0)); + end if; + when Decoded_StoreSP => + memBWriteEnable <= '1'; + memBAddr <= sp+spOffset; + memBWrite <= memARead; + sp <= sp + 1; + state <= State_Resync; + when Decoded_LoadSP => + sp <= sp - 1; + memAAddr <= sp+spOffset; + when Decoded_Emulate => + sp <= sp - 1; + memAWriteEnable <= '1'; + memAAddr <= sp - 1; + memAWrite <= (others => DontCareValue); + memAWrite(maxAddrBit downto 0) <= pc + 1; + -- The emulate address is: + -- 98 7654 3210 + -- 0000 00aa aaa0 0000 + pc <= (others => '0'); + pc(9 downto 5) <= unsigned(opcode(4 downto 0)); + when Decoded_AddSP => + memAAddr <= sp; + memBAddr <= sp+spOffset; + state <= State_AddSP; + 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; + when Decoded_PopPC => + pc <= memARead(maxAddrBit downto 0); + sp <= sp + 1; + state <= State_Resync; + when Decoded_Add => + sp <= sp + 1; + state <= State_Add; + when Decoded_Or => + sp <= sp + 1; + state <= State_Or; + when Decoded_And => + sp <= sp + 1; + state <= State_And; + when Decoded_Load => + if (memARead(ioBit)='1') then + out_mem_addr <= std_logic_vector(memARead(maxAddrBitIncIO downto 0)); + out_mem_readEnable <= '1'; + state <= State_ReadIO; + else + memAAddr <= memARead(maxAddrBit downto minAddrBit); + end if; + when Decoded_Not => + memAAddr <= sp(maxAddrBit downto minAddrBit); + memAWriteEnable <= '1'; + memAWrite <= not memARead; + when Decoded_Flip => + memAAddr <= sp(maxAddrBit downto minAddrBit); + memAWriteEnable <= '1'; + for i in 0 to wordSize-1 loop + memAWrite(i) <= memARead(wordSize-1-i); + end loop; + when Decoded_Store => + memBAddr <= sp + 1; + sp <= sp + 1; + if (memARead(ioBit)='1') then + state <= State_WriteIO; + else + state <= State_Store; + end if; + when Decoded_PopSP => + sp <= memARead(maxAddrBit downto minAddrBit); + state <= State_Resync; + when Decoded_Nop => + memAAddr <= sp; + when others => + null; + end case; + when State_ReadIO => + if (in_mem_busy = '0') then + state <= State_Fetch; + memAWriteEnable <= '1'; + memAWrite <= unsigned(mem_read); + end if; + when State_WriteIO => + sp <= sp + 1; + out_mem_writeEnable <= '1'; + out_mem_addr <= std_logic_vector(memARead(maxAddrBitIncIO downto 0)); + mem_write <= std_logic_vector(memBRead); + state <= State_WriteIODone; + when State_WriteIODone => + if (in_mem_busy = '0') then + state <= State_Resync; + end if; + when State_Fetch => + -- We need to resync. During the *next* cycle + -- we'll fetch the opcode @ pc and thus it will + -- be available for State_Execute the cycle after + -- next + memBAddr <= pc(maxAddrBit downto minAddrBit); + state <= State_FetchNext; + when State_FetchNext => + -- at this point memARead contains the value that is either + -- from the top of stack or should be copied to the top of the stack + memAWriteEnable <= '1'; + memAWrite <= memARead; + memAAddr <= sp; + memBAddr <= sp + 1; + state <= State_Decode; + when State_Decode => + -- during the State_Execute cycle we'll be fetching SP+1 + memAAddr <= sp; + memBAddr <= sp + 1; + state <= State_Execute; + when State_Store => + sp <= sp + 1; + memAWriteEnable <= '1'; + memAAddr <= memARead(maxAddrBit downto minAddrBit); + memAWrite <= memBRead; + state <= State_Resync; + when State_AddSP => + state <= State_Add; + when State_Add => + memAAddr <= sp; + memAWriteEnable <= '1'; + memAWrite <= memARead + memBRead; + state <= State_Fetch; + when State_Or => + memAAddr <= sp; + memAWriteEnable <= '1'; + memAWrite <= memARead or memBRead; + state <= State_Fetch; + when State_Resync => + memAAddr <= sp; + state <= State_Fetch; + when State_And => + memAAddr <= sp; + memAWriteEnable <= '1'; + memAWrite <= memARead and memBRead; + state <= State_Fetch; + when others => + null; + end case; + + end if; + end process; + + + +end behave; diff --git a/zpu/hdl/zpu4/src/zpupkg.vhd b/zpu/hdl/zpu4/src/zpupkg.vhd index 32e162b..f3800b0 100644 --- a/zpu/hdl/zpu4/src/zpupkg.vhd +++ b/zpu/hdl/zpu4/src/zpupkg.vhd @@ -1,6 +1,6 @@ library IEEE; use IEEE.STD_LOGIC_1164.all; -use IEEE.STD_LOGIC_ARITH.all; +use ieee.numeric_std.all; library work; use work.zpu_config.all; @@ -133,33 +133,33 @@ package zpupkg is constant OpCode_Compare : std_logic_vector(3 downto 0) := "1110"; constant OpCode_PopInt : std_logic_vector(3 downto 0) := "1111"; - constant OpCode_Lessthan : std_logic_vector(5 downto 0) := conv_std_logic_vector(36, 6); - constant OpCode_Lessthanorequal : std_logic_vector(5 downto 0) := conv_std_logic_vector(37, 6); - constant OpCode_Ulessthan : std_logic_vector(5 downto 0) := conv_std_logic_vector(38, 6); - constant OpCode_Ulessthanorequal : std_logic_vector(5 downto 0) := conv_std_logic_vector(39, 6); + constant OpCode_Lessthan : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(36, 6)); + constant OpCode_Lessthanorequal : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(37, 6)); + constant OpCode_Ulessthan : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(38, 6)); + constant OpCode_Ulessthanorequal : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(39, 6)); - constant OpCode_Swap : std_logic_vector(5 downto 0) := conv_std_logic_vector(40, 6); - constant OpCode_Mult : std_logic_vector(5 downto 0) := conv_std_logic_vector(41, 6); + constant OpCode_Swap : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(40, 6)); + constant OpCode_Mult : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(41, 6)); - constant OpCode_Lshiftright : std_logic_vector(5 downto 0) := conv_std_logic_vector(42, 6); - constant OpCode_Ashiftleft : std_logic_vector(5 downto 0) := conv_std_logic_vector(43, 6); - constant OpCode_Ashiftright : std_logic_vector(5 downto 0) := conv_std_logic_vector(44, 6); - constant OpCode_Call : std_logic_vector(5 downto 0) := conv_std_logic_vector(45, 6); + constant OpCode_Lshiftright : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(42, 6)); + constant OpCode_Ashiftleft : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(43, 6)); + constant OpCode_Ashiftright : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(44, 6)); + constant OpCode_Call : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(45, 6)); - constant OpCode_Eq : std_logic_vector(5 downto 0) := conv_std_logic_vector(46, 6); - constant OpCode_Neq : std_logic_vector(5 downto 0) := conv_std_logic_vector(47, 6); + constant OpCode_Eq : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(46, 6)); + constant OpCode_Neq : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(47, 6)); - constant OpCode_Sub : std_logic_vector(5 downto 0) := conv_std_logic_vector(49, 6); - constant OpCode_Loadb : std_logic_vector(5 downto 0) := conv_std_logic_vector(51, 6); - constant OpCode_Storeb : std_logic_vector(5 downto 0) := conv_std_logic_vector(52, 6); + constant OpCode_Sub : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(49, 6)); + constant OpCode_Loadb : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(51, 6)); + constant OpCode_Storeb : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(52, 6)); - constant OpCode_Eqbranch : std_logic_vector(5 downto 0) := conv_std_logic_vector(55, 6); - constant OpCode_Neqbranch : std_logic_vector(5 downto 0) := conv_std_logic_vector(56, 6); - constant OpCode_Poppcrel : std_logic_vector(5 downto 0) := conv_std_logic_vector(57, 6); + constant OpCode_Eqbranch : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(55, 6)); + constant OpCode_Neqbranch : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(56, 6)); + constant OpCode_Poppcrel : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(57, 6)); - constant OpCode_Pushspadd : std_logic_vector(5 downto 0) := conv_std_logic_vector(61, 6); - constant OpCode_Mult16x16 : std_logic_vector(5 downto 0) := conv_std_logic_vector(62, 6); - constant OpCode_Callpcrel : std_logic_vector(5 downto 0) := conv_std_logic_vector(63, 6); + constant OpCode_Pushspadd : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(61, 6)); + constant OpCode_Mult16x16 : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(62, 6)); + constant OpCode_Callpcrel : std_logic_vector(5 downto 0) := std_logic_vector(to_unsigned(63, 6)); -- cgit v1.1