summaryrefslogtreecommitdiffstats
path: root/zpu/hdl/zpu4/src
diff options
context:
space:
mode:
authoroharboe <oharboe>2008-04-22 05:52:16 +0000
committeroharboe <oharboe>2008-04-22 05:52:16 +0000
commitd09fa3de9df02a66c5084623076ac3e167b58274 (patch)
treeb734b58ae8ca60717464d503e9a9bcd4a98727a7 /zpu/hdl/zpu4/src
parent167263dcae188a8812627ab52cfd96b8fdc5df8a (diff)
downloadzpu-d09fa3de9df02a66c5084623076ac3e167b58274.zip
zpu-d09fa3de9df02a66c5084623076ac3e167b58274.tar.gz
* 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
Diffstat (limited to 'zpu/hdl/zpu4/src')
-rw-r--r--zpu/hdl/zpu4/src/bram_dmips.vhd12
-rw-r--r--zpu/hdl/zpu4/src/dmipssmalltrace_ghdl.sh26
-rw-r--r--zpu/hdl/zpu4/src/dmipstrace_ghdl.sh25
-rw-r--r--zpu/hdl/zpu4/src/dram_dmips.vhd8
-rw-r--r--zpu/hdl/zpu4/src/dram_hello.vhd8
-rw-r--r--zpu/hdl/zpu4/src/io.vhd6
-rw-r--r--zpu/hdl/zpu4/src/log.txt414
-rw-r--r--zpu/hdl/zpu4/src/sim_fpga_top.vhd377
-rw-r--r--zpu/hdl/zpu4/src/sim_small_fpga_top.vhd356
-rw-r--r--zpu/hdl/zpu4/src/simzpu_medium_ghdl.sh25
-rw-r--r--zpu/hdl/zpu4/src/timer.vhd6
-rw-r--r--zpu/hdl/zpu4/src/trace.vhd7
-rw-r--r--zpu/hdl/zpu4/src/zpu_config_trace.vhd1
-rw-r--r--zpu/hdl/zpu4/src/zpu_core.vhd1795
-rw-r--r--zpu/hdl/zpu4/src/zpu_core_small.vhd880
-rw-r--r--zpu/hdl/zpu4/src/zpupkg.vhd44
16 files changed, 2149 insertions, 1841 deletions
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<stackB) then
- binaryOpResult(0) <= '1';
- end if;
- state <= State_BinaryOpResult;
- end if;
- when State_Ulessthanorequal =>
- 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)<signed(stackB)) then
- binaryOpResult(0) <= '1';
- end if;
- state <= State_BinaryOpResult;
- end if;
- when State_Lessthanorequal =>
- 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<stackB) then
+ binaryOpResult(0) <= '1';
+ end if;
+ state <= State_BinaryOpResult;
+ end if;
+ when State_Ulessthanorequal =>
+ 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)<signed(stackB)) then
+ binaryOpResult(0) <= '1';
+ end if;
+ state <= State_BinaryOpResult;
+ end if;
+ when State_Lessthanorequal =>
+ 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));
OpenPOWER on IntegriCloud