diff options
author | oharboe <oharboe> | 2008-04-22 05:52:16 +0000 |
---|---|---|
committer | oharboe <oharboe> | 2008-04-22 05:52:16 +0000 |
commit | d09fa3de9df02a66c5084623076ac3e167b58274 (patch) | |
tree | b734b58ae8ca60717464d503e9a9bcd4a98727a7 | |
parent | 167263dcae188a8812627ab52cfd96b8fdc5df8a (diff) | |
download | zpu-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
-rw-r--r-- | zpu/ChangeLog | 13 | ||||
-rw-r--r-- | zpu/hdl/example/helloworld.vhd | 12 | ||||
-rw-r--r-- | zpu/hdl/example_ghdl/README | 74 | ||||
-rw-r--r-- | zpu/hdl/example_ghdl/ghdl_import.sh | 13 | ||||
-rw-r--r-- | zpu/hdl/example_ghdl/ghdl_make.sh | 4 | ||||
-rw-r--r-- | zpu/hdl/example_ghdl/ghdl_options.sh | 3 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/bram_dmips.vhd | 12 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/dmipssmalltrace_ghdl.sh | 26 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/dmipstrace_ghdl.sh | 25 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/dram_dmips.vhd | 8 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/dram_hello.vhd | 8 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/io.vhd | 6 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/log.txt | 414 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/sim_fpga_top.vhd | 377 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/sim_small_fpga_top.vhd | 356 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/simzpu_medium_ghdl.sh | 25 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/timer.vhd | 6 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/trace.vhd | 7 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/zpu_config_trace.vhd | 1 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/zpu_core.vhd | 1795 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/zpu_core_small.vhd | 880 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/zpupkg.vhd | 44 |
22 files changed, 2262 insertions, 1847 deletions
diff --git a/zpu/ChangeLog b/zpu/ChangeLog index 331ea74..249ff02 100644 --- a/zpu/ChangeLog +++ b/zpu/ChangeLog @@ -1,3 +1,16 @@ +2008-04-17 Arnim Läuger
+ * 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
2008-04-17 Øyvind Harboe
* deleted duplicate files from example folder.
* retired Xilinx synthesizing example. It messes up the zpu4 directory.
diff --git a/zpu/hdl/example/helloworld.vhd b/zpu/hdl/example/helloworld.vhd index 2e5ce4e..f9383fd 100644 --- a/zpu/hdl/example/helloworld.vhd +++ b/zpu/hdl/example/helloworld.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 :=
(
@@ -3094,10 +3094,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;
@@ -3106,10 +3106,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/example_ghdl/README b/zpu/hdl/example_ghdl/README new file mode 100644 index 0000000..c537284 --- /dev/null +++ b/zpu/hdl/example_ghdl/README @@ -0,0 +1,74 @@ +This directory contains a quick setup of the helloworld example for
+the GHDL simulator.
+
+ http://ghdl.free.fr/
+
+Compiled by Arnim Laeuger, 17-Apr-2008.
+
+
+Prerequisites
+-------------
+
+The RTL source code references the ROC component from Xilinx' unisim
+library. If not already done, you'll have to prepare this library containing
+at least the roc entity and architecture objects.
+
+Decide where to store this library. This could be locally in this directory or
+at some central place where it can be referenced from other projects. I'd
+prefer the latter option.
+
+ $ cd <where unisim lib should be stored>
+
+Prepare the sources for GHDL:
+ $ mkdir src
+ $ cd src
+ $ ghdl --chop <WebPack installation dir>/vhdl/src/unisims/*
+ $ cd ..
+
+Import the sources into the library:
+ $ mkdir unisim_v93
+ $ ghdl -i --work=unisim --workdir=unisim_v93 --std=93 -fexplicit --no-vital-checks --ieee=synopsys src/*
+
+Compile the required component:
+ $ ghdl -m --syn-binding --work=unisim --workdir=unisim_v93 --std=93 -fexplicit --no-vital-checks --ieee=synopsys roc
+ $ rm roc
+ -> not required for library
+
+If you require more components from the unisim library for other projects, you
+can repeat the compile step later on without running through the preparation
+and import steps.
+
+
+Compiling the example
+---------------------
+
+Edit ghdl_options.sh and point the variable UNISIM_DIR to the location of your
+newly created unisim library.
+
+You need to import the project sources once by running
+ $ ./ghdl_import.sh
+
+Compilation (using GHDL's make feature) is invoked by
+ $ ./ghdl_make.sh
+
+Whenever the VHDL sources change, it's enough to execute ghdl_make.sh. GHDL
+will trace the dependencies and will rebuild only the modified sources.
+
+
+Simulation
+----------
+
+Simulation finally happens by running the fpga_top executable generated by the
+compilation step. Don't forget to set a stop time or the testbench might run
+forever:
+
+ $ ./fpga_top --stop-time=2100us
+
+The log.txt and trace.txt files are generated as simulation progresses. They
+should be compared to the files given in the example directory.
+
+Waveforms can be obtained by specifying the ghw file name:
+
+ $ ./fpga_top --stop-time=1ms --wave=zpu.ghw
+
+They can be inspected with gtkwave from http://home.nc.rr.com/gtkwave/.
diff --git a/zpu/hdl/example_ghdl/ghdl_import.sh b/zpu/hdl/example_ghdl/ghdl_import.sh new file mode 100644 index 0000000..299134b --- /dev/null +++ b/zpu/hdl/example_ghdl/ghdl_import.sh @@ -0,0 +1,13 @@ +#!/bin/sh
+. ghdl_options.sh
+
+mkdir -p work
+ghdl -i ${IMPORT_OPTIONS} ../../hdl/example/zpu_config.vhd
+ghdl -i ${IMPORT_OPTIONS} ../../hdl/zpu4/src/zpupkg.vhd
+ghdl -i ${IMPORT_OPTIONS} ../../hdl/example/helloworld.vhd
+ghdl -i ${IMPORT_OPTIONS} ../../hdl/zpu4/src/txt_util.vhd
+ghdl -i ${IMPORT_OPTIONS} ../../hdl/zpu4/src/trace.vhd
+ghdl -i ${IMPORT_OPTIONS} ../../hdl/zpu4/src/zpu_core_small.vhd
+ghdl -i ${IMPORT_OPTIONS} ../../hdl/zpu4/src/io.vhd
+ghdl -i ${IMPORT_OPTIONS} ../../hdl/zpu4/src/timer.vhd
+ghdl -i ${IMPORT_OPTIONS} ../../hdl/zpu4/src/sim_small_fpga_top.vhd
diff --git a/zpu/hdl/example_ghdl/ghdl_make.sh b/zpu/hdl/example_ghdl/ghdl_make.sh new file mode 100644 index 0000000..948b100 --- /dev/null +++ b/zpu/hdl/example_ghdl/ghdl_make.sh @@ -0,0 +1,4 @@ +#!/bin/sh
+. ghdl_options.sh
+
+ghdl -m ${MAKE_OPTIONS} fpga_top
diff --git a/zpu/hdl/example_ghdl/ghdl_options.sh b/zpu/hdl/example_ghdl/ghdl_options.sh new file mode 100644 index 0000000..3883ee7 --- /dev/null +++ b/zpu/hdl/example_ghdl/ghdl_options.sh @@ -0,0 +1,3 @@ +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"
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));
|