1
0
mirror of git://projects.qi-hardware.com/nn-usb-fpga.git synced 2025-04-21 12:27:27 +03:00

Adding plasma example

This commit is contained in:
Carlos Camargo
2010-04-21 20:01:38 -05:00
parent f80360a678
commit 22c469585b
59 changed files with 18082 additions and 0 deletions

78
plasma/logic/Makefile Normal file
View File

@@ -0,0 +1,78 @@
DESIGN = plasma_3e
PINS = $(DESIGN).ucf
DEVICE = xc3s500e-fg320-4
BGFLAGS = -g TdoPin:PULLNONE -g DonePin:PULLUP \
-g CRC:enable -g StartUpClk:CCLK
SIM_CMD = /opt/cad/modeltech/bin/vsim
SIM_COMP_SCRIPT = simulation/$(DESIGN)_TB.do
#SIM_INIT_SCRIPT = simulation/$(DESIGN)_init.do
SIMGEN_OPTIONS = -p $(FPGA_ARCH) -lang $(LANGUAGE)
SRC_HDL = plasma.vhd alu.vhd control.vhd mem_ctrl.vhd mult.vhd shifter.vhd bus_mux.vhd ddr_ctrl.vhd mlite_cpu.vhd pc_next.vhd cache.vhd eth_dma.vhd mlite_pack.vhd pipeline.vhd reg_bank.vhd uart.vhd plasma_3e.vhd ram_image.vhd
all: bits
remake: clean-build all
clean:
rm -rf *~ */*~ a.out *.log *.key *.edf *.ps trace.dat
rm -rf *.bit rm -rf simulation/work simulation/*wlf
clean-build:
rm -rf build
cleanall: clean
rm -rf build work $(DESIGN).bit
bits: $(DESIGN).bit
#
# Synthesis
#
build/project.src:
@[ -d build ] || mkdir build
@rm -f $@
for i in $(SRC); do echo verilog work ../$$i >> $@; done
for i in $(SRC_HDL); do echo VHDL work ../$$i >> $@; done
build/project.xst: build/project.src
echo "run" > $@
echo "-top $(DESIGN) " >> $@
echo "-p $(DEVICE)" >> $@
echo "-opt_mode Area" >> $@
echo "-opt_level 1" >> $@
echo "-ifn project.src" >> $@
echo "-ifmt mixed" >> $@
echo "-ofn project.ngc" >> $@
echo "-ofmt NGC" >> $@
echo "-rtlview yes" >> $@
build/project.ngc: build/project.xst $(SRC)
cd build && xst -ifn project.xst -ofn project.log
build/project.ngd: build/project.ngc $(PINS)
cd build && ngdbuild -p $(DEVICE) project.ngc -uc ../$(PINS)
build/project.ncd: build/project.ngd
cd build && map -pr b -p $(DEVICE) project
build/project_r.ncd: build/project.ncd
cd build && par -w project project_r.ncd
build/project_r.twr: build/project_r.ncd
cd build && trce -v 25 project_r.ncd project.pcf
$(DESIGN).bit: build/project_r.ncd build/project_r.twr
cd build && bitgen project_r.ncd -l -w $(BGFLAGS)
@mv -f build/project_r.bit $@
upload: $(DESIGN).bit
LD_PRELOAD=/usr/lib/libusb-driver.so impact -batch prog.cmd
sim:
cd simulation; $(SIM_CMD) -do $(DESIGN)_TB.do

15
plasma/logic/_impact.cmd Normal file
View File

@@ -0,0 +1,15 @@
setMode -bs
setMode -bs
setCable -port auto
Identify
identifyMPM
assignFile -p 1 -file "/home/cain/Embedded/plasma/work/Example/logic/plasma_3e.bit"
Program -p 1 -defaultVersion 0
Program -p 1 -defaultVersion 0
Program -p 1 -defaultVersion 0
Program -p 1 -defaultVersion 0
assignFile -p 1 -file "/home/cain/Embedded/plasma/work/Example/logic/plasma_3e.bit"
Program -p 1 -defaultVersion 0
Program -p 1 -defaultVersion 0
Program -p 1 -defaultVersion 0
saveProjectFile -file "/home/cain/Embedded/plasma/work/Example/logic/default.ipf"

61
plasma/logic/alu.vhd Normal file
View File

@@ -0,0 +1,61 @@
---------------------------------------------------------------------
-- TITLE: Arithmetic Logic Unit
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 2/8/01
-- FILENAME: alu.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Implements the ALU.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.mlite_pack.all;
entity alu is
generic(alu_type : string := "DEFAULT");
port(a_in : in std_logic_vector(31 downto 0);
b_in : in std_logic_vector(31 downto 0);
alu_function : in alu_function_type;
c_alu : out std_logic_vector(31 downto 0));
end; --alu
architecture logic of alu is
signal do_add : std_logic;
signal sum : std_logic_vector(32 downto 0);
signal less_than : std_logic;
begin
do_add <= '1' when alu_function = ALU_ADD else '0';
sum <= bv_adder(a_in, b_in, do_add);
less_than <= sum(32) when a_in(31) = b_in(31) or alu_function = ALU_LESS_THAN
else a_in(31);
GENERIC_ALU: if alu_type = "DEFAULT" generate
c_alu <= sum(31 downto 0) when alu_function=ALU_ADD or
alu_function=ALU_SUBTRACT else
ZERO(31 downto 1) & less_than when alu_function=ALU_LESS_THAN or
alu_function=ALU_LESS_THAN_SIGNED else
a_in or b_in when alu_function=ALU_OR else
a_in and b_in when alu_function=ALU_AND else
a_in xor b_in when alu_function=ALU_XOR else
a_in nor b_in when alu_function=ALU_NOR else
ZERO;
end generate;
AREA_OPTIMIZED_ALU: if alu_type/="DEFAULT" generate
c_alu <= sum(31 downto 0) when alu_function=ALU_ADD or
alu_function=ALU_SUBTRACT else (others => 'Z');
c_alu <= ZERO(31 downto 1) & less_than when alu_function=ALU_LESS_THAN or
alu_function=ALU_LESS_THAN_SIGNED else
(others => 'Z');
c_alu <= a_in or b_in when alu_function=ALU_OR else (others => 'Z');
c_alu <= a_in and b_in when alu_function=ALU_AND else (others => 'Z');
c_alu <= a_in xor b_in when alu_function=ALU_XOR else (others => 'Z');
c_alu <= a_in nor b_in when alu_function=ALU_NOR else (others => 'Z');
c_alu <= ZERO when alu_function=ALU_NOTHING else (others => 'Z');
end generate;
end; --architecture logic

136
plasma/logic/bus_mux.vhd Normal file
View File

@@ -0,0 +1,136 @@
---------------------------------------------------------------------
-- TITLE: Bus Multiplexer / Signal Router
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 2/8/01
-- FILENAME: bus_mux.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- This entity is the main signal router.
-- It multiplexes signals from multiple sources to the correct location.
-- The outputs are as follows:
-- a_bus : goes to the ALU
-- b_bus : goes to the ALU
-- reg_dest_out : goes to the register bank
-- take_branch : goes to pc_next
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.mlite_pack.all;
entity bus_mux is
port(imm_in : in std_logic_vector(15 downto 0);
reg_source : in std_logic_vector(31 downto 0);
a_mux : in a_source_type;
a_out : out std_logic_vector(31 downto 0);
reg_target : in std_logic_vector(31 downto 0);
b_mux : in b_source_type;
b_out : out std_logic_vector(31 downto 0);
c_bus : in std_logic_vector(31 downto 0);
c_memory : in std_logic_vector(31 downto 0);
c_pc : in std_logic_vector(31 downto 2);
c_pc_plus4 : in std_logic_vector(31 downto 2);
c_mux : in c_source_type;
reg_dest_out : out std_logic_vector(31 downto 0);
branch_func : in branch_function_type;
take_branch : out std_logic);
end; --entity bus_mux
architecture logic of bus_mux is
begin
--Determine value of a_bus
amux: process(reg_source, imm_in, a_mux, c_pc)
begin
case a_mux is
when A_FROM_REG_SOURCE =>
a_out <= reg_source;
when A_FROM_IMM10_6 =>
a_out <= ZERO(31 downto 5) & imm_in(10 downto 6);
when A_FROM_PC =>
a_out <= c_pc & "00";
when others =>
a_out <= c_pc & "00";
end case;
end process;
--Determine value of b_bus
bmux: process(reg_target, imm_in, b_mux)
begin
case b_mux is
when B_FROM_REG_TARGET =>
b_out <= reg_target;
when B_FROM_IMM =>
b_out <= ZERO(31 downto 16) & imm_in;
when B_FROM_SIGNED_IMM =>
if imm_in(15) = '0' then
b_out(31 downto 16) <= ZERO(31 downto 16);
else
b_out(31 downto 16) <= "1111111111111111";
end if;
b_out(15 downto 0) <= imm_in;
when B_FROM_IMMX4 =>
if imm_in(15) = '0' then
b_out(31 downto 18) <= "00000000000000";
else
b_out(31 downto 18) <= "11111111111111";
end if;
b_out(17 downto 0) <= imm_in & "00";
when others =>
b_out <= reg_target;
end case;
end process;
--Determine value of c_bus
cmux: process(c_bus, c_memory, c_pc, c_pc_plus4, imm_in, c_mux)
begin
case c_mux is
when C_FROM_ALU => -- | C_FROM_SHIFT | C_FROM_MULT =>
reg_dest_out <= c_bus;
when C_FROM_MEMORY =>
reg_dest_out <= c_memory;
when C_FROM_PC =>
reg_dest_out <= c_pc(31 downto 2) & "00";
when C_FROM_PC_PLUS4 =>
reg_dest_out <= c_pc_plus4 & "00";
when C_FROM_IMM_SHIFT16 =>
reg_dest_out <= imm_in & ZERO(15 downto 0);
when others =>
reg_dest_out <= c_bus;
end case;
end process;
--Determine value of take_branch
pc_mux: process(branch_func, reg_source, reg_target)
variable is_equal : std_logic;
begin
if reg_source = reg_target then
is_equal := '1';
else
is_equal := '0';
end if;
case branch_func is
when BRANCH_LTZ =>
take_branch <= reg_source(31);
when BRANCH_LEZ =>
take_branch <= reg_source(31) or is_equal;
when BRANCH_EQ =>
take_branch <= is_equal;
when BRANCH_NE =>
take_branch <= not is_equal;
when BRANCH_GEZ =>
take_branch <= not reg_source(31);
when BRANCH_GTZ =>
take_branch <= not reg_source(31) and not is_equal;
when BRANCH_YES =>
take_branch <= '1';
when others =>
take_branch <= '0';
end case;
end process;
end; --architecture logic

175
plasma/logic/cache.vhd Normal file
View File

@@ -0,0 +1,175 @@
---------------------------------------------------------------------
-- TITLE: Cache Controller
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 12/22/08
-- FILENAME: cache.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Control 4KB unified cache that uses the upper 4KB of the 8KB
-- internal RAM. Only lowest 2MB of DDR is cached.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
library UNISIM;
use UNISIM.vcomponents.all;
use work.mlite_pack.all;
entity cache is
generic(memory_type : string := "DEFAULT");
port(clk : in std_logic;
reset : in std_logic;
address_next : in std_logic_vector(31 downto 2);
byte_we_next : in std_logic_vector(3 downto 0);
cpu_address : in std_logic_vector(31 downto 2);
mem_busy : in std_logic;
cache_check : out std_logic; --Stage1: address_next in first 2MB DDR
cache_checking : out std_logic; --Stage2: cache checking
cache_miss : out std_logic); --Stage2-3: cache miss
end; --cache
architecture logic of cache is
subtype state_type is std_logic_vector(1 downto 0);
constant STATE_CHECK : state_type := "00";
constant STATE_CHECKING : state_type := "01";
constant STATE_MISSED : state_type := "10";
constant STATE_WRITING : state_type := "11";
signal state_reg : state_type;
signal state : state_type;
signal state_next : state_type;
signal cache_address : std_logic_vector(10 downto 0);
signal cache_tag_in : std_logic_vector(8 downto 0);
signal cache_tag_reg : std_logic_vector(8 downto 0);
signal cache_tag_out : std_logic_vector(8 downto 0);
signal cache_we : std_logic;
begin
cache_proc: process(clk, reset, mem_busy, cache_address, cache_we,
state_reg, state, state_next,
address_next, byte_we_next, cache_tag_in, --Stage1
cache_tag_reg, cache_tag_out, --Stage2
cpu_address) --Stage3
begin
case state_reg is
when STATE_CHECK =>
cache_checking <= '0';
cache_miss <= '0';
state <= STATE_CHECK;
when STATE_CHECKING =>
cache_checking <= '1';
if cache_tag_out /= cache_tag_reg or cache_tag_out = ONES(8 downto 0) then
cache_miss <= '1';
state <= STATE_MISSED;
else
cache_miss <= '0';
state <= STATE_CHECK;
end if;
cache_we <= '0';
when STATE_MISSED =>
cache_checking <= '0';
cache_miss <= '1';
cache_we <= '1';
if mem_busy = '1' then
state <= STATE_MISSED;
else
state <= STATE_CHECK;
end if;
when STATE_WRITING =>
cache_checking <= '0';
cache_miss <= '0';
cache_we <= '0';
if mem_busy = '1' then
state <= STATE_WRITING;
else
state <= STATE_CHECK;
end if;
when others =>
cache_checking <= '0';
cache_miss <= '0';
cache_we <= '0';
state <= STATE_CHECK;
end case; --state
if state = STATE_CHECK and state_reg /= STATE_MISSED then
cache_address <= '0' & address_next(11 downto 2);
if address_next(30 downto 21) = "0010000000" then --first 2MB of DDR
cache_check <= '1';
if byte_we_next = "0000" then
cache_we <= '0';
state_next <= STATE_CHECKING;
else
cache_we <= '1';
state_next <= STATE_WRITING;
end if;
else
cache_check <= '0';
cache_we <= '0';
state_next <= STATE_CHECK;
end if;
else
cache_address <= '0' & cpu_address(11 downto 2);
cache_check <= '0';
state_next <= state;
end if;
if byte_we_next = "0000" or byte_we_next = "1111" then
cache_tag_in <= address_next(20 downto 12);
else
cache_tag_in <= ONES(8 downto 0); --invalid tag
end if;
if reset = '1' then
state_reg <= STATE_CHECK;
cache_tag_reg <= ZERO(8 downto 0);
elsif rising_edge(clk) then
state_reg <= state_next;
if state = STATE_CHECK and state_reg /= STATE_MISSED then
cache_tag_reg <= cache_tag_in;
end if;
end if;
end process;
cache_xilinx: if memory_type = "XILINX_16X" generate
begin
cache_tag: RAMB16_S9 --Xilinx specific
port map (
DO => cache_tag_out(7 downto 0),
DOP => cache_tag_out(8 downto 8),
ADDR => cache_address, --registered
CLK => clk,
DI => cache_tag_in(7 downto 0), --registered
DIP => cache_tag_in(8 downto 8),
EN => '1',
SSR => ZERO(0),
WE => cache_we);
end generate; --cache_xilinx
cache_generic: if memory_type /= "XILINX_16X" generate
begin
cache_tag: process(clk, cache_address, cache_tag_in, cache_we)
constant ADDRESS_WIDTH : natural := 10;
type storage_array is
array(natural range 0 to 2 ** ADDRESS_WIDTH - 1) of
std_logic_vector(8 downto 0);
variable storage : storage_array;
variable index : natural := 0;
begin
if rising_edge(clk) then
index := conv_integer(cache_address(ADDRESS_WIDTH-1 downto 0));
if cache_we = '1' then
storage(index) := cache_tag_in;
end if;
cache_tag_out <= storage(index);
end if;
end process; --cache_tag
end generate; --cache_generic
end; --logic

658
plasma/logic/code.txt Normal file
View File

@@ -0,0 +1,658 @@
3c1c0000
379c8a34
3c040000
34840a48
3c050000
34a50a64
3c1d0000
37bd0c60
ac800000
0085182a
1460fffd
24840004
0c0001d5
00000000
0800000e
23bdff98
afa10010
afa20014
afa30018
afa4001c
afa50020
afa60024
afa70028
afa8002c
afa90030
afaa0034
afab0038
afac003c
afad0040
afae0044
afaf0048
afb8004c
afb90050
afbf0054
401a7000
235afffc
afba0058
0000d810
afbb005c
0000d812
afbb0060
23a50000
3c062000
8cc40020
8cc60010
0c00020a
00862024
8fa10010
8fa20014
8fa30018
8fa4001c
8fa50020
8fa60024
8fa70028
8fa8002c
8fa90030
8faa0034
8fab0038
8fac003c
8fad0040
8fae0044
8faf0048
8fb8004c
8fb90050
8fbf0054
8fba0058
8fbb005c
03600011
8fbb0060
03600013
23bd0068
341b0001
03400008
409b6000
40026000
03e00008
40846000
3c050000
24a50160
8ca60000
ac06003c
8ca60004
ac060040
8ca60008
ac060044
8ca6000c
03e00008
ac060048
3c1a1000
375a003c
03400008
00000000
ac900000
ac910004
ac920008
ac93000c
ac940010
ac950014
ac960018
ac97001c
ac9e0020
ac9c0024
ac9d0028
ac9f002c
03e00008
34020000
8c900000
8c910004
8c920008
8c93000c
8c940010
8c950014
8c960018
8c97001c
8c9e0020
8c9c0024
8c9d0028
8c9f002c
03e00008
34a20000
00850019
00001012
00002010
03e00008
acc40000
3c020000
24420a48
a0400008
24050007
00403825
3083000f
2862000a
10400003
00a73021
10000002
24620030
24620037
a0c20000
24a5ffff
04a1fff6
00042102
3c020000
03e00008
24420a48
3c020000
24420a58
a040000a
00803025
24050009
00404025
3c07cccc
34e7cccd
00c70019
00a82021
24a5ffff
00004810
000918c2
00031080
00431021
00021040
00c21023
24420030
a0820000
04a1fff4
00603025
3c020000
03e00008
24420a58
27bdffe0
afbf0018
afb10014
afb00010
0c000090
00808825
0c0001ef
00402025
3c040000
0c0001ef
24840980
3c023b9a
3442c9ff
0051102b
1040001e
3c030004
34634b83
00111242
00430019
3c030000
246309cc
00002810
000581c2
00101080
00431021
8c440000
0c0001ef
00000000
3c040000
0c0001ef
24840984
00101140
00501023
00021080
00501023
00021100
00501021
000210c0
00501023
00021940
00621823
00031880
00701821
00031a40
02238823
3c0205f5
3442e0ff
0051102b
10400023
3c0255e6
34423b89
02220019
3c030000
246309cc
00002810
00058642
00101080
00431021
8c440000
0c0001ef
00000000
3c040000
0c0001ef
24840990
00101040
00501021
00021180
00501023
00021080
00501023
00021100
00501023
00021140
00501021
00021200
02228823
3c02000f
3442423f
0051102b
14400005
3c020131
3c040000
0c0001ef
2484099c
3c020131
34422cff
0051102b
10400021
3c026b5f
3442ca6b
02220019
3c030000
246309cc
00002810
00058582
26020014
00021080
00431021
8c440000
0c0001ef
00000000
0c0001de
24040020
00101940
00701823
00031180
00431023
000210c0
00501021
00021880
00431021
000211c0
02228823
3c02000f
3442423f
0051102b
14400009
3c02431b
3c040000
0c0001ef
2484099c
3c02000f
3442423f
0051102b
10400017
3c02431b
3442de83
02220019
3c030000
246309cc
00002810
00058482
00101080
00431021
8c440000
0c0001ef
00000000
3c040000
0c0001ef
248409a8
00101940
00701823
00031180
00431023
000210c0
00501021
00021180
02228823
3c020001
3442869f
0051102b
10400020
3c030a7c
34635ac5
00111142
00430019
3c030000
246309cc
00002810
000581c2
00101080
00431021
8c440000
0c0001ef
00000000
3c040000
0c0001ef
24840990
00101040
00501021
00021980
00431021
00021080
00501021
00021080
00501021
00021140
02228823
2e2203e8
10400005
2e224e20
3c040000
0c0001ef
248409b4
2e224e20
1440001f
2e2203e8
3c02d1b7
34421759
02220019
3c030000
246309cc
00002810
00058342
26020014
00021080
00431021
8c440000
0c0001ef
00000000
0c0001de
24040020
00101080
00501021
000210c0
00501023
00021100
00501021
00021100
02228823
2e2203e8
10400008
3c021062
3c040000
0c0001ef
248409b4
2e2203e8
14400017
2e220064
3c021062
34424dd3
02220019
3c030000
246309cc
00002810
00058182
00101080
00431021
8c440000
0c0001ef
00000000
3c040000
0c0001ef
248409c0
00101140
00501023
00021080
00501021
000210c0
02228823
2e220064
14400017
2e220014
3c0251eb
3442851f
02220019
3c030000
246309cc
00002810
00058142
00101080
00431021
8c440000
0c0001ef
00000000
3c040000
0c0001ef
24840990
00101040
00501021
000210c0
00501021
00021080
02228823
2e220014
14400014
3c030000
3c02cccc
3442cccd
02220019
246309cc
00002810
000580c2
26020014
00021080
00431021
8c440000
0c0001ef
00000000
0c0001de
24040020
00101080
00501021
00021040
02228823
3c030000
246309cc
00111080
00431021
8c440000
0c0001ef
00000000
0c0001de
2404000d
0c0001de
2404000a
8fbf0018
8fb10014
8fb00010
03e00008
27bd0020
27bdffe8
afbf0014
afb00010
24100003
0c0000a8
02002025
00101040
1000fffc
02028021
3c022000
34420020
8c420000
00000000
30420002
14400008
3c022000
3c032000
34630020
8c620000
00000000
30420002
1040fffc
3c022000
ac440000
03e00008
00000000
27bdffe0
afb00010
00808025
afbf0018
afb10014
92020000
00000000
1040000d
2411000a
00000000
14510003
00000000
0c0001de
2404000d
92040000
0c0001de
26100001
92020000
00000000
1440fff5
00000000
8fbf0018
8fb10014
8fb00010
00001025
03e00008
27bd0020
27bdffe8
afbf0010
0c0001de
24040049
8fbf0010
00000000
03e00008
27bd0018
3c022000
34420020
8c420000
03e00008
30420001
27bdffe8
afbf0010
0c000212
00000000
1040fffd
3c022000
8c420000
8fbf0010
00000000
03e00008
27bd0018
00000000
00000000
00000000
00000000
00000000
00000000
6e696e65
74790000
65696768
74790000
73657665
6e747900
73697874
79000000
66696674
79000000
666f7274
79000000
74686972
74790000
7477656e
74790000
6e696e65
7465656e
00000000
65696768
7465656e
00000000
73657665
6e746565
6e000000
73697874
65656e00
66696674
65656e00
666f7572
7465656e
00000000
74686972
7465656e
00000000
7477656c
76650000
656c6576
656e0000
74656e00
6e696e65
00000000
65696768
74000000
73657665
6e000000
73697800
66697665
00000000
666f7572
00000000
74687265
65000000
74776f00
6f6e6500
00000000
3a200000
2062696c
6c696f6e
20000000
2068756e
64726564
20000000
6d696c6c
696f6e20
00000000
206d696c
6c696f6e
20000000
74686f75
73616e64
20000000
2074686f
7573616e
64200000
0000097c
00000978
00000974
0000096c
00000964
0000095c
00000958
00000950
00000948
00000940
0000093c
00000934
0000092c
00000920
00000914
0000090c
00000904
000008f8
000008ec
000008e0
0000097c
0000093c
000008d8
000008d0
000008c8
000008c0
000008b8
000008b0
000008a8
000008a0
00000000

481
plasma/logic/control.vhd Normal file
View File

@@ -0,0 +1,481 @@
---------------------------------------------------------------------
-- TITLE: Controller / Opcode Decoder
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 2/8/01
-- FILENAME: control.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- NOTE: MIPS(tm) is a registered trademark of MIPS Technologies.
-- MIPS Technologies does not endorse and is not associated with
-- this project.
-- DESCRIPTION:
-- Controls the CPU by decoding the opcode and generating control
-- signals to the rest of the CPU.
-- This entity decodes the MIPS(tm) opcode into a
-- Very-Long-Word-Instruction.
-- The 32-bit opcode is converted to a
-- 6+6+6+16+4+2+4+3+2+2+3+2+4 = 60 bit VLWI opcode.
-- Based on information found in:
-- "MIPS RISC Architecture" by Gerry Kane and Joe Heinrich
-- and "The Designer's Guide to VHDL" by Peter J. Ashenden
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.mlite_pack.all;
entity control is
port(opcode : in std_logic_vector(31 downto 0);
intr_signal : in std_logic;
rs_index : out std_logic_vector(5 downto 0);
rt_index : out std_logic_vector(5 downto 0);
rd_index : out std_logic_vector(5 downto 0);
imm_out : out std_logic_vector(15 downto 0);
alu_func : out alu_function_type;
shift_func : out shift_function_type;
mult_func : out mult_function_type;
branch_func : out branch_function_type;
a_source_out : out a_source_type;
b_source_out : out b_source_type;
c_source_out : out c_source_type;
pc_source_out: out pc_source_type;
mem_source_out:out mem_source_type;
exception_out: out std_logic);
end; --entity control
architecture logic of control is
begin
control_proc: process(opcode, intr_signal)
variable op, func : std_logic_vector(5 downto 0);
variable rs, rt, rd : std_logic_vector(5 downto 0);
variable rtx : std_logic_vector(4 downto 0);
variable imm : std_logic_vector(15 downto 0);
variable alu_function : alu_function_type;
variable shift_function : shift_function_type;
variable mult_function : mult_function_type;
variable a_source : a_source_type;
variable b_source : b_source_type;
variable c_source : c_source_type;
variable pc_source : pc_source_type;
variable branch_function: branch_function_type;
variable mem_source : mem_source_type;
variable is_syscall : std_logic;
begin
alu_function := ALU_NOTHING;
shift_function := SHIFT_NOTHING;
mult_function := MULT_NOTHING;
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_REG_TARGET;
c_source := C_FROM_NULL;
pc_source := FROM_INC4;
branch_function := BRANCH_EQ;
mem_source := MEM_FETCH;
op := opcode(31 downto 26);
rs := '0' & opcode(25 downto 21);
rt := '0' & opcode(20 downto 16);
rtx := opcode(20 downto 16);
rd := '0' & opcode(15 downto 11);
func := opcode(5 downto 0);
imm := opcode(15 downto 0);
is_syscall := '0';
case op is
when "000000" => --SPECIAL
case func is
when "000000" => --SLL r[rd]=r[rt]<<re;
a_source := A_FROM_IMM10_6;
c_source := C_FROM_SHIFT;
shift_function := SHIFT_LEFT_UNSIGNED;
when "000010" => --SRL r[rd]=u[rt]>>re;
a_source := A_FROM_IMM10_6;
c_source := C_FROM_shift;
shift_function := SHIFT_RIGHT_UNSIGNED;
when "000011" => --SRA r[rd]=r[rt]>>re;
a_source := A_FROM_IMM10_6;
c_source := C_FROM_SHIFT;
shift_function := SHIFT_RIGHT_SIGNED;
when "000100" => --SLLV r[rd]=r[rt]<<r[rs];
c_source := C_FROM_SHIFT;
shift_function := SHIFT_LEFT_UNSIGNED;
when "000110" => --SRLV r[rd]=u[rt]>>r[rs];
c_source := C_FROM_SHIFT;
shift_function := SHIFT_RIGHT_UNSIGNED;
when "000111" => --SRAV r[rd]=r[rt]>>r[rs];
c_source := C_FROM_SHIFT;
shift_function := SHIFT_RIGHT_SIGNED;
when "001000" => --JR s->pc_next=r[rs];
pc_source := FROM_BRANCH;
alu_function := ALU_ADD;
branch_function := BRANCH_YES;
when "001001" => --JALR r[rd]=s->pc_next; s->pc_next=r[rs];
c_source := C_FROM_PC_PLUS4;
pc_source := FROM_BRANCH;
alu_function := ALU_ADD;
branch_function := BRANCH_YES;
--when "001010" => --MOVZ if(!r[rt]) r[rd]=r[rs]; /*IV*/
--when "001011" => --MOVN if(r[rt]) r[rd]=r[rs]; /*IV*/
when "001100" => --SYSCALL
is_syscall := '1';
when "001101" => --BREAK s->wakeup=1;
is_syscall := '1';
--when "001111" => --SYNC s->wakeup=1;
when "010000" => --MFHI r[rd]=s->hi;
c_source := C_FROM_MULT;
mult_function := MULT_READ_HI;
when "010001" => --FTHI s->hi=r[rs];
mult_function := MULT_WRITE_HI;
when "010010" => --MFLO r[rd]=s->lo;
c_source := C_FROM_MULT;
mult_function := MULT_READ_LO;
when "010011" => --MTLO s->lo=r[rs];
mult_function := MULT_WRITE_LO;
when "011000" => --MULT s->lo=r[rs]*r[rt]; s->hi=0;
mult_function := MULT_SIGNED_MULT;
when "011001" => --MULTU s->lo=r[rs]*r[rt]; s->hi=0;
mult_function := MULT_MULT;
when "011010" => --DIV s->lo=r[rs]/r[rt]; s->hi=r[rs]%r[rt];
mult_function := MULT_SIGNED_DIVIDE;
when "011011" => --DIVU s->lo=r[rs]/r[rt]; s->hi=r[rs]%r[rt];
mult_function := MULT_DIVIDE;
when "100000" => --ADD r[rd]=r[rs]+r[rt];
c_source := C_FROM_ALU;
alu_function := ALU_ADD;
when "100001" => --ADDU r[rd]=r[rs]+r[rt];
c_source := C_FROM_ALU;
alu_function := ALU_ADD;
when "100010" => --SUB r[rd]=r[rs]-r[rt];
c_source := C_FROM_ALU;
alu_function := ALU_SUBTRACT;
when "100011" => --SUBU r[rd]=r[rs]-r[rt];
c_source := C_FROM_ALU;
alu_function := ALU_SUBTRACT;
when "100100" => --AND r[rd]=r[rs]&r[rt];
c_source := C_FROM_ALU;
alu_function := ALU_AND;
when "100101" => --OR r[rd]=r[rs]|r[rt];
c_source := C_FROM_ALU;
alu_function := ALU_OR;
when "100110" => --XOR r[rd]=r[rs]^r[rt];
c_source := C_FROM_ALU;
alu_function := ALU_XOR;
when "100111" => --NOR r[rd]=~(r[rs]|r[rt]);
c_source := C_FROM_ALU;
alu_function := ALU_NOR;
when "101010" => --SLT r[rd]=r[rs]<r[rt];
c_source := C_FROM_ALU;
alu_function := ALU_LESS_THAN_SIGNED;
when "101011" => --SLTU r[rd]=u[rs]<u[rt];
c_source := C_FROM_ALU;
alu_function := ALU_LESS_THAN;
when "101101" => --DADDU r[rd]=r[rs]+u[rt];
c_source := C_FROM_ALU;
alu_function := ALU_ADD;
--when "110001" => --TGEU
--when "110010" => --TLT
--when "110011" => --TLTU
--when "110100" => --TEQ
--when "110110" => --TNE
when others =>
end case;
when "000001" => --REGIMM
rt := "000000";
rd := "011111";
a_source := A_FROM_PC;
b_source := B_FROM_IMMX4;
alu_function := ALU_ADD;
pc_source := FROM_BRANCH;
branch_function := BRANCH_GTZ;
--if(test) pc=pc+imm*4
case rtx is
when "10000" => --BLTZAL r[31]=s->pc_next; branch=r[rs]<0;
c_source := C_FROM_PC_PLUS4;
branch_function := BRANCH_LTZ;
when "00000" => --BLTZ branch=r[rs]<0;
branch_function := BRANCH_LTZ;
when "10001" => --BGEZAL r[31]=s->pc_next; branch=r[rs]>=0;
c_source := C_FROM_PC_PLUS4;
branch_function := BRANCH_GEZ;
when "00001" => --BGEZ branch=r[rs]>=0;
branch_function := BRANCH_GEZ;
--when "10010" => --BLTZALL r[31]=s->pc_next; lbranch=r[rs]<0;
--when "00010" => --BLTZL lbranch=r[rs]<0;
--when "10011" => --BGEZALL r[31]=s->pc_next; lbranch=r[rs]>=0;
--when "00011" => --BGEZL lbranch=r[rs]>=0;
when others =>
end case;
when "000011" => --JAL r[31]=s->pc_next; s->pc_next=(s->pc&0xf0000000)|target;
c_source := C_FROM_PC_PLUS4;
rd := "011111";
pc_source := FROM_OPCODE25_0;
when "000010" => --J s->pc_next=(s->pc&0xf0000000)|target;
pc_source := FROM_OPCODE25_0;
when "000100" => --BEQ branch=r[rs]==r[rt];
a_source := A_FROM_PC;
b_source := B_FROM_IMMX4;
alu_function := ALU_ADD;
pc_source := FROM_BRANCH;
branch_function := BRANCH_EQ;
when "000101" => --BNE branch=r[rs]!=r[rt];
a_source := A_FROM_PC;
b_source := B_FROM_IMMX4;
alu_function := ALU_ADD;
pc_source := FROM_BRANCH;
branch_function := BRANCH_NE;
when "000110" => --BLEZ branch=r[rs]<=0;
a_source := A_FROM_PC;
b_source := b_FROM_IMMX4;
alu_function := ALU_ADD;
pc_source := FROM_BRANCH;
branch_function := BRANCH_LEZ;
when "000111" => --BGTZ branch=r[rs]>0;
a_source := A_FROM_PC;
b_source := B_FROM_IMMX4;
alu_function := ALU_ADD;
pc_source := FROM_BRANCH;
branch_function := BRANCH_GTZ;
when "001000" => --ADDI r[rt]=r[rs]+(short)imm;
b_source := B_FROM_SIGNED_IMM;
c_source := C_FROM_ALU;
rd := rt;
alu_function := ALU_ADD;
when "001001" => --ADDIU u[rt]=u[rs]+(short)imm;
b_source := B_FROM_SIGNED_IMM;
c_source := C_FROM_ALU;
rd := rt;
alu_function := ALU_ADD;
when "001010" => --SLTI r[rt]=r[rs]<(short)imm;
b_source := B_FROM_SIGNED_IMM;
c_source := C_FROM_ALU;
rd := rt;
alu_function := ALU_LESS_THAN_SIGNED;
when "001011" => --SLTIU u[rt]=u[rs]<(unsigned long)(short)imm;
b_source := B_FROM_SIGNED_IMM;
c_source := C_FROM_ALU;
rd := rt;
alu_function := ALU_LESS_THAN;
when "001100" => --ANDI r[rt]=r[rs]&imm;
b_source := B_FROM_IMM;
c_source := C_FROM_ALU;
rd := rt;
alu_function := ALU_AND;
when "001101" => --ORI r[rt]=r[rs]|imm;
b_source := B_FROM_IMM;
c_source := C_FROM_ALU;
rd := rt;
alu_function := ALU_OR;
when "001110" => --XORI r[rt]=r[rs]^imm;
b_source := B_FROM_IMM;
c_source := C_FROM_ALU;
rd := rt;
alu_function := ALU_XOR;
when "001111" => --LUI r[rt]=(imm<<16);
c_source := C_FROM_IMM_SHIFT16;
rd := rt;
when "010000" => --COP0
alu_function := ALU_OR;
c_source := C_FROM_ALU;
if opcode(23) = '0' then --move from CP0
rs := '1' & opcode(15 downto 11);
rt := "000000";
rd := '0' & opcode(20 downto 16);
else --move to CP0
rs := "000000";
rd(5) := '1';
pc_source := FROM_BRANCH; --delay possible interrupt
branch_function := BRANCH_NO;
end if;
--when "010001" => --COP1
--when "010010" => --COP2
--when "010011" => --COP3
--when "010100" => --BEQL lbranch=r[rs]==r[rt];
--when "010101" => --BNEL lbranch=r[rs]!=r[rt];
--when "010110" => --BLEZL lbranch=r[rs]<=0;
--when "010111" => --BGTZL lbranch=r[rs]>0;
when "100000" => --LB r[rt]=*(signed char*)ptr;
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
rd := rt;
c_source := C_FROM_MEMORY;
mem_source := MEM_READ8S; --address=(short)imm+r[rs];
when "100001" => --LH r[rt]=*(signed short*)ptr;
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
rd := rt;
c_source := C_FROM_MEMORY;
mem_source := MEM_READ16S; --address=(short)imm+r[rs];
when "100010" => --LWL //Not Implemented
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
rd := rt;
c_source := C_FROM_MEMORY;
mem_source := MEM_READ32;
when "100011" => --LW r[rt]=*(long*)ptr;
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
rd := rt;
c_source := C_FROM_MEMORY;
mem_source := MEM_READ32;
when "100100" => --LBU r[rt]=*(unsigned char*)ptr;
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
rd := rt;
c_source := C_FROM_MEMORY;
mem_source := MEM_READ8; --address=(short)imm+r[rs];
when "100101" => --LHU r[rt]=*(unsigned short*)ptr;
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
rd := rt;
c_source := C_FROM_MEMORY;
mem_source := MEM_READ16; --address=(short)imm+r[rs];
--when "100110" => --LWR //Not Implemented
when "101000" => --SB *(char*)ptr=(char)r[rt];
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
mem_source := MEM_WRITE8; --address=(short)imm+r[rs];
when "101001" => --SH *(short*)ptr=(short)r[rt];
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
mem_source := MEM_WRITE16;
when "101010" => --SWL //Not Implemented
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
mem_source := MEM_WRITE32; --address=(short)imm+r[rs];
when "101011" => --SW *(long*)ptr=r[rt];
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
mem_source := MEM_WRITE32; --address=(short)imm+r[rs];
--when "101110" => --SWR //Not Implemented
--when "101111" => --CACHE
--when "110000" => --LL r[rt]=*(long*)ptr;
--when "110001" => --LWC1
--when "110010" => --LWC2
--when "110011" => --LWC3
--when "110101" => --LDC1
--when "110110" => --LDC2
--when "110111" => --LDC3
--when "111000" => --SC *(long*)ptr=r[rt]; r[rt]=1;
--when "111001" => --SWC1
--when "111010" => --SWC2
--when "111011" => --SWC3
--when "111101" => --SDC1
--when "111110" => --SDC2
--when "111111" => --SDC3
when others =>
end case;
if c_source = C_FROM_NULL then
rd := "000000";
end if;
if intr_signal = '1' or is_syscall = '1' then
rs := "111111"; --interrupt vector
rt := "000000";
rd := "101110"; --save PC in EPC
alu_function := ALU_OR;
shift_function := SHIFT_NOTHING;
mult_function := MULT_NOTHING;
branch_function := BRANCH_YES;
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_REG_TARGET;
c_source := C_FROM_PC;
pc_source := FROM_LBRANCH;
mem_source := MEM_FETCH;
exception_out <= '1';
else
exception_out <= '0';
end if;
rs_index <= rs;
rt_index <= rt;
rd_index <= rd;
imm_out <= imm;
alu_func <= alu_function;
shift_func <= shift_function;
mult_func <= mult_function;
branch_func <= branch_function;
a_source_out <= a_source;
b_source_out <= b_source;
c_source_out <= c_source;
pc_source_out <= pc_source;
mem_source_out <= mem_source;
end process;
end; --logic

354
plasma/logic/ddr_ctrl.vhd Normal file
View File

@@ -0,0 +1,354 @@
---------------------------------------------------------------------
-- TITLE: DDR SDRAM Interface
-- AUTHORS: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 7/26/07
-- FILENAME: ddr_ctrl.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Double Data Rate Sychronous Dynamic Random Access Memory Interface
--
-- For: 64 MB = MT46V32M16, 512Mb, 32Mb x 16 (default)
-- ROW = address(25 downto 13)
-- BANK = address(12 downto 11)
-- COL = address(10 downto 2)
--
-- Changes are needed for 32 MB = MT46V16M16, 256Mb, 16Mb x 16
-- ROW = address(24 downto 12) -- 25 ignored
-- BANK = address(11 downto 10)
-- COL = address(9 downto 2) --also change ddr_init.c
--
-- Changes are needed for 128 MB = MT46V64M16, 1Gb, 64Mb x 16
-- ROW = address(26 downto 14)
-- BANK = address(13 downto 12)
-- COL = address(11 downto 2) --also change ddr_init.c
--
-- Requires CAS latency=2; burst size=2.
-- Requires clk changes on rising_edge(clk_2x).
-- Requires active, address, byte_we, data_w stable throughout transfer.
-- DLL mode requires 77MHz. Non-DLL mode runs at 25 MHz.
--
-- cycle_cnt 777777770000111122223333444455556666777777777777
-- clk_2x --__--__--__--__--__--__--__--__--__--__--__--__
-- clk ____----____----____----____----____----____----
-- SD_CLK ----____----____----____----____----____----____
-- cmd ____write+++WRITE+++____________________________
-- SD_DQ ~~~~~~~~~~~~~~uuuullllUUUULLLL~~~~~~~~~~~~~~~~~~
--
-- cycle_cnt 777777770000111122223333444455556666777777777777
-- clk_2x --__--__--__--__--__--__--__--__--__--__--__--__
-- clk ____----____----____----____----____----____----
-- SD_CLK ----____----____----____----____----____----____
-- cmd ____read++++________________________read++++____
-- SD_DQ ~~~~~~~~~~~~~~~~~~~~~~~~uuuullll~~~~~~~~~~~~~~~~
-- SD_DQnDLL ~~~~~~~~~~~~~~~~~~~~~~~~~~uuuullll~~~~~~~~~~~~~~
-- pause ____------------------------________------------
--
-- Must run DdrInit() to initialize DDR chip.
-- Read Micron DDR SDRAM MT46V32M16 data sheet for more details.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use work.mlite_pack.all;
entity ddr_ctrl is
port(
clk : in std_logic;
clk_2x : in std_logic;
reset_in : in std_logic;
address : in std_logic_vector(25 downto 2);
byte_we : in std_logic_vector(3 downto 0);
data_w : in std_logic_vector(31 downto 0);
data_r : out std_logic_vector(31 downto 0);
active : in std_logic;
no_start : in std_logic;
no_stop : in std_logic;
pause : out std_logic;
SD_CK_P : out std_logic; --clock_positive
SD_CK_N : out std_logic; --clock_negative
SD_CKE : out std_logic; --clock_enable
SD_BA : out std_logic_vector(1 downto 0); --bank_address
SD_A : out std_logic_vector(12 downto 0); --address(row or col)
SD_CS : out std_logic; --chip_select
SD_RAS : out std_logic; --row_address_strobe
SD_CAS : out std_logic; --column_address_strobe
SD_WE : out std_logic; --write_enable
SD_DQ : inout std_logic_vector(15 downto 0); --data
SD_UDM : out std_logic; --upper_byte_enable
SD_UDQS : inout std_logic; --upper_data_strobe
SD_LDM : out std_logic; --low_byte_enable
SD_LDQS : inout std_logic); --low_data_strobe
end; --entity ddr
architecture logic of ddr_ctrl is
--Commands for bits RAS & CAS & WE
subtype command_type is std_logic_vector(2 downto 0);
constant COMMAND_LMR : command_type := "000";
constant COMMAND_AUTO_REFRESH : command_type := "001";
constant COMMAND_PRECHARGE : command_type := "010";
constant COMMAND_ACTIVE : command_type := "011";
constant COMMAND_WRITE : command_type := "100";
constant COMMAND_READ : command_type := "101";
constant COMMAND_TERMINATE : command_type := "110";
constant COMMAND_NOP : command_type := "111";
subtype ddr_state_type is std_logic_vector(3 downto 0);
constant STATE_POWER_ON : ddr_state_type := "0000";
constant STATE_IDLE : ddr_state_type := "0001";
constant STATE_ROW_ACTIVATE : ddr_state_type := "0010";
constant STATE_ROW_ACTIVE : ddr_state_type := "0011";
constant STATE_READ : ddr_state_type := "0100";
constant STATE_READ2 : ddr_state_type := "0101";
constant STATE_READ3 : ddr_state_type := "0110";
constant STATE_PRECHARGE : ddr_state_type := "0111";
constant STATE_PRECHARGE2 : ddr_state_type := "1000";
signal state_prev : ddr_state_type;
signal refresh_cnt : std_logic_vector(7 downto 0);
signal data_write2 : std_logic_vector(47 downto 0); --write pipeline
signal byte_we_reg2 : std_logic_vector(5 downto 0); --write pipeline
signal write_active : std_logic;
signal write_prev : std_logic;
signal cycle_count : std_logic_vector(2 downto 0); --half clocks since op
signal cycle_count2 : std_logic_vector(2 downto 0); --delayed by quarter clock
signal cke_reg : std_logic;
signal clk_p : std_logic;
signal bank_open : std_logic_vector(3 downto 0);
signal data_read : std_logic_vector(31 downto 0);
begin
ddr_proc: process(clk, clk_p, clk_2x, reset_in,
address, byte_we, data_w, active, no_start, no_stop,
SD_DQ, SD_UDQS, SD_LDQS,
state_prev, refresh_cnt,
byte_we_reg2, data_write2,
cycle_count, cycle_count2, write_prev,
write_active, cke_reg, bank_open,
data_read)
type address_array_type is array(3 downto 0) of std_logic_vector(12 downto 0);
variable address_row : address_array_type;
variable command : std_logic_vector(2 downto 0); --RAS & CAS & WE
variable bank_index : integer;
variable state_current : ddr_state_type;
begin
command := COMMAND_NOP;
bank_index := conv_integer(address(12 downto 11));
state_current := state_prev;
--DDR state machine to determine state_current and command
case state_prev is
when STATE_POWER_ON =>
if active = '1' then
if byte_we /= "0000" then
command := address(6 downto 4); --LMR="000"
else
state_current := STATE_IDLE; --read transistions to STATE_IDLE
end if;
end if;
when STATE_IDLE =>
if refresh_cnt(7) = '1' then
state_current := STATE_PRECHARGE;
command := COMMAND_AUTO_REFRESH;
elsif active = '1' and no_start = '0' then
state_current := STATE_ROW_ACTIVATE;
command := COMMAND_ACTIVE;
end if;
when STATE_ROW_ACTIVATE =>
state_current := STATE_ROW_ACTIVE;
when STATE_ROW_ACTIVE =>
if refresh_cnt(7) = '1' then
if write_prev = '0' then
state_current := STATE_PRECHARGE;
command := COMMAND_PRECHARGE;
end if;
elsif active = '1' and no_start = '0' then
if bank_open(bank_index) = '0' then
state_current := STATE_ROW_ACTIVATE;
command := COMMAND_ACTIVE;
elsif address(25 downto 13) /= address_row(bank_index) then
if write_prev = '0' then
state_current := STATE_PRECHARGE;
command := COMMAND_PRECHARGE;
end if;
else
if byte_we /= "0000" then
command := COMMAND_WRITE;
elsif write_prev = '0' then
state_current := STATE_READ;
command := COMMAND_READ;
end if;
end if;
end if;
when STATE_READ =>
state_current := STATE_READ2;
when STATE_READ2 =>
state_current := STATE_READ3;
when STATE_READ3 =>
if no_stop = '0' then
state_current := STATE_ROW_ACTIVE;
end if;
when STATE_PRECHARGE =>
state_current := STATE_PRECHARGE2;
when STATE_PRECHARGE2 =>
state_current := STATE_IDLE;
when others =>
state_current := STATE_IDLE;
end case; --state_prev
--rising_edge(clk) domain registers
if reset_in = '1' then
state_prev <= STATE_POWER_ON;
cke_reg <= '0';
refresh_cnt <= ZERO(7 downto 0);
write_prev <= '0';
write_active <= '0';
bank_open <= "0000";
elsif rising_edge(clk) then
if active = '1' then
cke_reg <= '1';
end if;
if command = COMMAND_WRITE then
write_prev <= '1';
elsif cycle_count2(2 downto 1) = "11" then
write_prev <= '0';
end if;
if command = COMMAND_WRITE then
write_active <= '1';
elsif cycle_count2 = "100" then
write_active <= '0';
end if;
if command = COMMAND_ACTIVE then
bank_open(bank_index) <= '1';
address_row(bank_index) := address(25 downto 13);
end if;
if command = COMMAND_PRECHARGE then
bank_open <= "0000";
end if;
if command = COMMAND_AUTO_REFRESH then
refresh_cnt <= ZERO(7 downto 0);
else
refresh_cnt <= refresh_cnt + 1;
end if;
state_prev <= state_current;
end if; --rising_edge(clk)
--rising_edge(clk_2x) domain registers
if reset_in = '1' then
cycle_count <= "000";
elsif rising_edge(clk_2x) then
--Cycle_count
if (command = COMMAND_READ or command = COMMAND_WRITE) and clk = '1' then
cycle_count <= "000";
elsif cycle_count /= "111" then
cycle_count <= cycle_count + 1;
end if;
clk_p <= clk; --earlier version of not clk
--Read data (DLL disabled)
if cycle_count = "100" then
data_read(31 downto 16) <= SD_DQ; --data
elsif cycle_count = "101" then
data_read(15 downto 0) <= SD_DQ;
end if;
end if;
--falling_edge(clk_2x) domain registers
if reset_in = '1' then
cycle_count2 <= "000";
data_write2 <= ZERO(15 downto 0) & ZERO;
byte_we_reg2 <= "000000";
elsif falling_edge(clk_2x) then
cycle_count2 <= cycle_count;
--Write pipeline
if clk = '0' then
data_write2 <= data_write2(31 downto 16) & data_w;
byte_we_reg2 <= byte_we_reg2(3 downto 2) & byte_we;
else
data_write2(47 downto 16) <= data_write2(31 downto 0);
byte_we_reg2(5 downto 2) <= byte_we_reg2(3 downto 0);
end if;
--Read data (DLL enabled)
--if cycle_count = "100" then
-- data_read(31 downto 16) <= SD_DQ; --data
--elsif cycle_count = "101" then
-- data_read(15 downto 0) <= SD_DQ;
--end if;
end if;
data_r <= data_read;
--Write data
if write_active = '1' then
SD_UDQS <= clk_p; --upper_data_strobe
SD_LDQS <= clk_p; --low_data_strobe
SD_DQ <= data_write2(47 downto 32); --data
SD_UDM <= not byte_we_reg2(5); --upper_byte_enable
SD_LDM <= not byte_we_reg2(4); --low_byte_enable
else
SD_UDQS <= 'Z'; --upper_data_strobe
SD_LDQS <= 'Z'; --low_data_strobe
SD_DQ <= "ZZZZZZZZZZZZZZZZ"; --data
SD_UDM <= 'Z';
SD_LDM <= 'Z';
end if;
--DDR control signals
SD_CK_P <= clk_p; --clock_positive
SD_CK_N <= not clk_p; --clock_negative
SD_CKE <= cke_reg; --clock_enable
SD_BA <= address(12 downto 11); --bank_address
if command = COMMAND_ACTIVE or state_current = STATE_POWER_ON then
SD_A <= address(25 downto 13); --address row
elsif command = COMMAND_READ or command = COMMAND_WRITE then
SD_A <= "000" & address(10 downto 2) & "0"; --address col
else
SD_A <= "0010000000000"; --PERCHARGE all banks
end if;
SD_CS <= not cke_reg; --chip_select
SD_RAS <= command(2); --row_address_strobe
SD_CAS <= command(1); --column_address_strobe
SD_WE <= command(0); --write_enable
if active = '1' and state_current /= STATE_POWER_ON and
command /= COMMAND_WRITE and state_prev /= STATE_READ3 then
pause <= '1';
else
pause <= '0';
end if;
end process; --ddr_proc
end; --architecture logic

BIN
plasma/logic/default.ipf Normal file

Binary file not shown.

Binary file not shown.

183
plasma/logic/eth_dma.vhd Normal file
View File

@@ -0,0 +1,183 @@
---------------------------------------------------------------------
-- TITLE: Ethernet DMA
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 12/27/07
-- FILENAME: eth_dma.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Ethernet DMA (Direct Memory Access) controller.
-- Reads four bits and writes four bits from/to the Ethernet PHY each
-- 2.5 MHz clock cycle. Received data is DMAed starting at 0x13ff0000
-- transmit data is read from 0x13fd0000.
-- To send a packet write bytes/4 to Ethernet send register.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use work.mlite_pack.all;
entity eth_dma is port(
clk : in std_logic; --25 MHz
reset : in std_logic;
enable_eth : in std_logic; --enable receive DMA
select_eth : in std_logic;
rec_isr : out std_logic; --data received
send_isr : out std_logic; --transmit done
address : out std_logic_vector(31 downto 2); --to DDR
byte_we : out std_logic_vector(3 downto 0);
data_write : out std_logic_vector(31 downto 0);
data_read : in std_logic_vector(31 downto 0);
pause_in : in std_logic;
mem_address : in std_logic_vector(31 downto 2); --from CPU
mem_byte_we : in std_logic_vector(3 downto 0);
data_w : in std_logic_vector(31 downto 0);
pause_out : out std_logic;
E_RX_CLK : in std_logic; --2.5 MHz receive
E_RX_DV : in std_logic; --data valid
E_RXD : in std_logic_vector(3 downto 0); --receive nibble
E_TX_CLK : in std_logic; --2.5 MHz transmit
E_TX_EN : out std_logic; --transmit enable
E_TXD : out std_logic_vector(3 downto 0)); --transmit nibble
end; --entity eth_dma
architecture logic of eth_dma is
signal rec_clk : std_logic_vector(1 downto 0); --receive
signal rec_store : std_logic_vector(31 downto 0); --to DDR
signal rec_data : std_logic_vector(27 downto 0);
signal rec_cnt : std_logic_vector(2 downto 0); --nibbles
signal rec_words : std_logic_vector(13 downto 0);
signal rec_dma : std_logic_vector(1 downto 0); --active & request
signal rec_done : std_logic;
signal send_clk : std_logic_vector(1 downto 0); --transmit
signal send_read : std_logic_vector(31 downto 0); --from DDR
signal send_data : std_logic_vector(31 downto 0);
signal send_cnt : std_logic_vector(2 downto 0); --nibbles
signal send_words : std_logic_vector(8 downto 0);
signal send_level : std_logic_vector(8 downto 0);
signal send_dma : std_logic_vector(1 downto 0); --active & request
signal send_enable: std_logic;
begin --architecture
dma_proc: process(clk, reset, enable_eth, select_eth,
data_read, pause_in, mem_address, mem_byte_we, data_w,
E_RX_CLK, E_RX_DV, E_RXD, E_TX_CLK,
rec_clk, rec_store, rec_data,
rec_cnt, rec_words, rec_dma, rec_done,
send_clk, send_read, send_data, send_cnt, send_words,
send_level, send_dma, send_enable)
begin
if reset = '1' then
rec_clk <= "00";
rec_cnt <= "000";
rec_words <= ZERO(13 downto 0);
rec_dma <= "00";
rec_done <= '0';
send_clk <= "00";
send_cnt <= "000";
send_words <= ZERO(8 downto 0);
send_level <= ZERO(8 downto 0);
send_dma <= "00";
send_enable <= '0';
elsif rising_edge(clk) then
--Receive nibble on low->high E_RX_CLK. Send to DDR every 32 bits.
rec_clk <= rec_clk(0) & E_RX_CLK;
if rec_clk = "01" and enable_eth = '1' then
if E_RX_DV = '1' or rec_cnt /= "000" then
if rec_cnt = "111" then
rec_store <= rec_data & E_RXD;
rec_dma(0) <= '1'; --request DMA
end if;
rec_data <= rec_data(23 downto 0) & E_RXD;
rec_cnt <= rec_cnt + 1;
end if;
end if;
--Set transmit count or clear receive interrupt
if select_eth = '1' then
if mem_byte_we /= "0000" then
send_cnt <= "000";
send_words <= ZERO(8 downto 0);
send_level <= data_w(8 downto 0);
send_dma(0) <= '1';
else
rec_done <= '0';
end if;
end if;
--Transmit nibble on low->high E_TX_CLK. Get 32 bits from DDR.
send_clk <= send_clk(0) & E_TX_CLK;
if send_clk = "01" then
if send_cnt = "111" then
if send_words /= send_level then
send_data <= send_read;
send_dma(0) <= '1';
send_enable <= '1';
else
send_enable <= '0';
end if;
else
send_data(31 downto 4) <= send_data(27 downto 0);
end if;
send_cnt <= send_cnt + 1;
end if;
--Pick which type of DMA operation: bit0 = request; bit1 = active
if pause_in = '0' then
if rec_dma(1) = '1' then
rec_dma <= "00"; --DMA done
rec_words <= rec_words + 1;
if E_RX_DV = '0' then
rec_done <= '1';
end if;
elsif send_dma(1) = '1' then
send_dma <= "00";
send_words <= send_words + 1;
send_read <= data_read;
elsif rec_dma(0) = '1' then
rec_dma(1) <= '1'; --start DMA
elsif send_dma(0) = '1' then
send_dma(1) <= '1'; --start DMA
end if;
end if;
end if; --rising_edge(clk)
E_TXD <= send_data(31 downto 28);
E_TX_EN <= send_enable;
rec_isr <= rec_done;
if send_words = send_level then
send_isr <= '1';
else
send_isr <= '0';
end if;
if rec_dma(1) = '1' then
address <= "0001001111111111" & rec_words; --0x13ff0000
byte_we <= "1111";
data_write <= rec_store;
pause_out <= '1'; --to CPU
elsif send_dma(1) = '1' then
address <= "000100111111111000000" & send_words; --0x13fe0000
byte_we <= "0000";
data_write <= data_w;
pause_out <= '1';
else
address <= mem_address; --Send request from CPU to DDR
byte_we <= mem_byte_we;
data_write <= data_w;
pause_out <= '0';
end if;
end process;
end; --architecture logic

196
plasma/logic/mem_ctrl.vhd Normal file
View File

@@ -0,0 +1,196 @@
---------------------------------------------------------------------
-- TITLE: Memory Controller
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 1/31/01
-- FILENAME: mem_ctrl.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Memory controller for the Plasma CPU.
-- Supports Big or Little Endian mode.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.mlite_pack.all;
entity mem_ctrl is
port(clk : in std_logic;
reset_in : in std_logic;
pause_in : in std_logic;
nullify_op : in std_logic;
address_pc : in std_logic_vector(31 downto 2);
opcode_out : out std_logic_vector(31 downto 0);
address_in : in std_logic_vector(31 downto 0);
mem_source : in mem_source_type;
data_write : in std_logic_vector(31 downto 0);
data_read : out std_logic_vector(31 downto 0);
pause_out : out std_logic;
address_next : out std_logic_vector(31 downto 2);
byte_we_next : out std_logic_vector(3 downto 0);
address : out std_logic_vector(31 downto 2);
byte_we : out std_logic_vector(3 downto 0);
data_w : out std_logic_vector(31 downto 0);
data_r : in std_logic_vector(31 downto 0));
end; --entity mem_ctrl
architecture logic of mem_ctrl is
--"00" = big_endian; "11" = little_endian
constant ENDIAN_MODE : std_logic_vector(1 downto 0) := "00";
signal opcode_reg : std_logic_vector(31 downto 0);
signal next_opcode_reg : std_logic_vector(31 downto 0);
signal address_reg : std_logic_vector(31 downto 2);
signal byte_we_reg : std_logic_vector(3 downto 0);
signal mem_state_reg : std_logic;
constant STATE_ADDR : std_logic := '0';
constant STATE_ACCESS : std_logic := '1';
begin
mem_proc: process(clk, reset_in, pause_in, nullify_op,
address_pc, address_in, mem_source, data_write,
data_r, opcode_reg, next_opcode_reg, mem_state_reg,
address_reg, byte_we_reg)
variable address_var : std_logic_vector(31 downto 2);
variable data_read_var : std_logic_vector(31 downto 0);
variable data_write_var : std_logic_vector(31 downto 0);
variable opcode_next : std_logic_vector(31 downto 0);
variable byte_we_var : std_logic_vector(3 downto 0);
variable mem_state_next : std_logic;
variable pause_var : std_logic;
variable bits : std_logic_vector(1 downto 0);
begin
byte_we_var := "0000";
pause_var := '0';
data_read_var := ZERO;
data_write_var := ZERO;
mem_state_next := mem_state_reg;
opcode_next := opcode_reg;
case mem_source is
when MEM_READ32 =>
data_read_var := data_r;
when MEM_READ16 | MEM_READ16S =>
if address_in(1) = ENDIAN_MODE(1) then
data_read_var(15 downto 0) := data_r(31 downto 16);
else
data_read_var(15 downto 0) := data_r(15 downto 0);
end if;
if mem_source = MEM_READ16 or data_read_var(15) = '0' then
data_read_var(31 downto 16) := ZERO(31 downto 16);
else
data_read_var(31 downto 16) := ONES(31 downto 16);
end if;
when MEM_READ8 | MEM_READ8S =>
bits := address_in(1 downto 0) xor ENDIAN_MODE;
case bits is
when "00" => data_read_var(7 downto 0) := data_r(31 downto 24);
when "01" => data_read_var(7 downto 0) := data_r(23 downto 16);
when "10" => data_read_var(7 downto 0) := data_r(15 downto 8);
when others => data_read_var(7 downto 0) := data_r(7 downto 0);
end case;
if mem_source = MEM_READ8 or data_read_var(7) = '0' then
data_read_var(31 downto 8) := ZERO(31 downto 8);
else
data_read_var(31 downto 8) := ONES(31 downto 8);
end if;
when MEM_WRITE32 =>
data_write_var := data_write;
byte_we_var := "1111";
when MEM_WRITE16 =>
data_write_var := data_write(15 downto 0) & data_write(15 downto 0);
if address_in(1) = ENDIAN_MODE(1) then
byte_we_var := "1100";
else
byte_we_var := "0011";
end if;
when MEM_WRITE8 =>
data_write_var := data_write(7 downto 0) & data_write(7 downto 0) &
data_write(7 downto 0) & data_write(7 downto 0);
bits := address_in(1 downto 0) xor ENDIAN_MODE;
case bits is
when "00" =>
byte_we_var := "1000";
when "01" =>
byte_we_var := "0100";
when "10" =>
byte_we_var := "0010";
when others =>
byte_we_var := "0001";
end case;
when others =>
end case;
if mem_source = MEM_FETCH then --opcode fetch
address_var := address_pc;
opcode_next := data_r;
mem_state_next := STATE_ADDR;
else
if mem_state_reg = STATE_ADDR then
if pause_in = '0' then
address_var := address_in(31 downto 2);
mem_state_next := STATE_ACCESS;
pause_var := '1';
else
address_var := address_pc;
byte_we_var := "0000";
end if;
else --STATE_ACCESS
if pause_in = '0' then
address_var := address_pc;
opcode_next := next_opcode_reg;
mem_state_next := STATE_ADDR;
byte_we_var := "0000";
else
address_var := address_in(31 downto 2);
byte_we_var := "0000";
end if;
end if;
end if;
if nullify_op = '1' and pause_in = '0' then
opcode_next := ZERO; --NOP after beql
end if;
if reset_in = '1' then
mem_state_reg <= STATE_ADDR;
opcode_reg <= ZERO;
next_opcode_reg <= ZERO;
address_reg <= ZERO(31 downto 2);
byte_we_reg <= "0000";
elsif rising_edge(clk) then
if pause_in = '0' then
address_reg <= address_var;
byte_we_reg <= byte_we_var;
mem_state_reg <= mem_state_next;
opcode_reg <= opcode_next;
if mem_state_reg = STATE_ADDR then
next_opcode_reg <= data_r;
end if;
end if;
end if;
opcode_out <= opcode_reg;
data_read <= data_read_var;
pause_out <= pause_var;
address_next <= address_var;
byte_we_next <= byte_we_var;
address <= address_reg;
byte_we <= byte_we_reg;
data_w <= data_write_var;
end process; --data_proc
end; --architecture logic

342
plasma/logic/mlite_cpu.vhd Normal file
View File

@@ -0,0 +1,342 @@
---------------------------------------------------------------------
-- TITLE: Plasma CPU core
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 2/15/01
-- FILENAME: mlite_cpu.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- NOTE: MIPS(tm) and MIPS I(tm) are registered trademarks of MIPS
-- Technologies. MIPS Technologies does not endorse and is not
-- associated with this project.
-- DESCRIPTION:
-- Top level VHDL document that ties the nine other entities together.
--
-- Executes all MIPS I(tm) opcodes but exceptions and non-aligned
-- memory accesses. Based on information found in:
-- "MIPS RISC Architecture" by Gerry Kane and Joe Heinrich
-- and "The Designer's Guide to VHDL" by Peter J. Ashenden
--
-- The CPU is implemented as a two or three stage pipeline.
-- An add instruction would take the following steps (see cpu.gif):
-- Stage #0:
-- 1. The "pc_next" entity passes the program counter (PC) to the
-- "mem_ctrl" entity which fetches the opcode from memory.
-- Stage #1:
-- 2. The memory returns the opcode.
-- Stage #2:
-- 3. "Mem_ctrl" passes the opcode to the "control" entity.
-- 4. "Control" converts the 32-bit opcode to a 60-bit VLWI opcode
-- and sends control signals to the other entities.
-- 5. Based on the rs_index and rt_index control signals, "reg_bank"
-- sends the 32-bit reg_source and reg_target to "bus_mux".
-- 6. Based on the a_source and b_source control signals, "bus_mux"
-- multiplexes reg_source onto a_bus and reg_target onto b_bus.
-- Stage #3 (part of stage #2 if using two stage pipeline):
-- 7. Based on the alu_func control signals, "alu" adds the values
-- from a_bus and b_bus and places the result on c_bus.
-- 8. Based on the c_source control signals, "bus_bux" multiplexes
-- c_bus onto reg_dest.
-- 9. Based on the rd_index control signal, "reg_bank" saves
-- reg_dest into the correct register.
-- Stage #3b:
-- 10. Read or write memory if needed.
--
-- All signals are active high.
-- Here are the signals for writing a character to address 0xffff
-- when using a two stage pipeline:
--
-- Program:
-- addr value opcode
-- =============================
-- 3c: 00000000 nop
-- 40: 34040041 li $a0,0x41
-- 44: 3405ffff li $a1,0xffff
-- 48: a0a40000 sb $a0,0($a1)
-- 4c: 00000000 nop
-- 50: 00000000 nop
--
-- intr_in mem_pause
-- reset_in byte_we Stages
-- ns address data_w data_r 40 44 48 4c 50
-- 3600 0 0 00000040 00000000 34040041 0 0 1
-- 3700 0 0 00000044 00000000 3405FFFF 0 0 2 1
-- 3800 0 0 00000048 00000000 A0A40000 0 0 2 1
-- 3900 0 0 0000004C 41414141 00000000 0 0 2 1
-- 4000 0 0 0000FFFC 41414141 XXXXXX41 1 0 3 2
-- 4100 0 0 00000050 00000000 00000000 0 0 1
---------------------------------------------------------------------
library ieee;
use work.mlite_pack.all;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity mlite_cpu is
generic(memory_type : string := "XILINX_16X"; --ALTERA_LPM, or DUAL_PORT_
mult_type : string := "DEFAULT"; --AREA_OPTIMIZED
shifter_type : string := "DEFAULT"; --AREA_OPTIMIZED
alu_type : string := "DEFAULT"; --AREA_OPTIMIZED
pipeline_stages : natural := 2); --2 or 3
port(clk : in std_logic;
reset_in : in std_logic;
intr_in : in std_logic;
address_next : out std_logic_vector(31 downto 2); --for synch ram
byte_we_next : out std_logic_vector(3 downto 0);
address : out std_logic_vector(31 downto 2);
byte_we : out std_logic_vector(3 downto 0);
data_w : out std_logic_vector(31 downto 0);
data_r : in std_logic_vector(31 downto 0);
mem_pause : in std_logic);
end; --entity mlite_cpu
architecture logic of mlite_cpu is
--When using a two stage pipeline "sigD <= sig".
--When using a three stage pipeline "sigD <= sig when rising_edge(clk)",
-- so sigD is delayed by one clock cycle.
signal opcode : std_logic_vector(31 downto 0);
signal rs_index : std_logic_vector(5 downto 0);
signal rt_index : std_logic_vector(5 downto 0);
signal rd_index : std_logic_vector(5 downto 0);
signal rd_indexD : std_logic_vector(5 downto 0);
signal reg_source : std_logic_vector(31 downto 0);
signal reg_target : std_logic_vector(31 downto 0);
signal reg_dest : std_logic_vector(31 downto 0);
signal reg_destD : std_logic_vector(31 downto 0);
signal a_bus : std_logic_vector(31 downto 0);
signal a_busD : std_logic_vector(31 downto 0);
signal b_bus : std_logic_vector(31 downto 0);
signal b_busD : std_logic_vector(31 downto 0);
signal c_bus : std_logic_vector(31 downto 0);
signal c_alu : std_logic_vector(31 downto 0);
signal c_shift : std_logic_vector(31 downto 0);
signal c_mult : std_logic_vector(31 downto 0);
signal c_memory : std_logic_vector(31 downto 0);
signal imm : std_logic_vector(15 downto 0);
signal pc_future : std_logic_vector(31 downto 2);
signal pc_current : std_logic_vector(31 downto 2);
signal pc_plus4 : std_logic_vector(31 downto 2);
signal alu_func : alu_function_type;
signal alu_funcD : alu_function_type;
signal shift_func : shift_function_type;
signal shift_funcD : shift_function_type;
signal mult_func : mult_function_type;
signal mult_funcD : mult_function_type;
signal branch_func : branch_function_type;
signal take_branch : std_logic;
signal a_source : a_source_type;
signal b_source : b_source_type;
signal c_source : c_source_type;
signal pc_source : pc_source_type;
signal mem_source : mem_source_type;
signal pause_mult : std_logic;
signal pause_ctrl : std_logic;
signal pause_pipeline : std_logic;
signal pause_any : std_logic;
signal pause_non_ctrl : std_logic;
signal pause_bank : std_logic;
signal nullify_op : std_logic;
signal intr_enable : std_logic;
signal intr_signal : std_logic;
signal exception_sig : std_logic;
signal reset_reg : std_logic_vector(3 downto 0);
signal reset : std_logic;
begin --architecture
pause_any <= (mem_pause or pause_ctrl) or (pause_mult or pause_pipeline);
pause_non_ctrl <= (mem_pause or pause_mult) or pause_pipeline;
pause_bank <= (mem_pause or pause_ctrl or pause_mult) and not pause_pipeline;
nullify_op <= '1' when (pc_source = FROM_LBRANCH and take_branch = '0')
or intr_signal = '1' or exception_sig = '1'
else '0';
c_bus <= c_alu or c_shift or c_mult;
reset <= '1' when reset_in = '1' or reset_reg /= "1111" else '0';
--synchronize reset and interrupt pins
intr_proc: process(clk, reset_in, reset_reg, intr_in, intr_enable,
pc_source, pc_current, pause_any)
begin
if reset_in = '1' then
reset_reg <= "0000";
intr_signal <= '0';
elsif rising_edge(clk) then
if reset_reg /= "1111" then
reset_reg <= reset_reg + 1;
end if;
--don't try to interrupt a multi-cycle instruction
if pause_any = '0' then
if intr_in = '1' and intr_enable = '1' and
pc_source = FROM_INC4 then
--the epc will contain pc+4
intr_signal <= '1';
else
intr_signal <= '0';
end if;
end if;
end if;
end process;
u1_pc_next: pc_next PORT MAP (
clk => clk,
reset_in => reset,
take_branch => take_branch,
pause_in => pause_any,
pc_new => c_bus(31 downto 2),
opcode25_0 => opcode(25 downto 0),
pc_source => pc_source,
pc_future => pc_future,
pc_current => pc_current,
pc_plus4 => pc_plus4);
u2_mem_ctrl: mem_ctrl
PORT MAP (
clk => clk,
reset_in => reset,
pause_in => pause_non_ctrl,
nullify_op => nullify_op,
address_pc => pc_future,
opcode_out => opcode,
address_in => c_bus,
mem_source => mem_source,
data_write => reg_target,
data_read => c_memory,
pause_out => pause_ctrl,
address_next => address_next,
byte_we_next => byte_we_next,
address => address,
byte_we => byte_we,
data_w => data_w,
data_r => data_r);
u3_control: control PORT MAP (
opcode => opcode,
intr_signal => intr_signal,
rs_index => rs_index,
rt_index => rt_index,
rd_index => rd_index,
imm_out => imm,
alu_func => alu_func,
shift_func => shift_func,
mult_func => mult_func,
branch_func => branch_func,
a_source_out => a_source,
b_source_out => b_source,
c_source_out => c_source,
pc_source_out=> pc_source,
mem_source_out=> mem_source,
exception_out=> exception_sig);
u4_reg_bank: reg_bank
generic map(memory_type => memory_type)
port map (
clk => clk,
reset_in => reset,
pause => pause_bank,
rs_index => rs_index,
rt_index => rt_index,
rd_index => rd_indexD,
reg_source_out => reg_source,
reg_target_out => reg_target,
reg_dest_new => reg_destD,
intr_enable => intr_enable);
u5_bus_mux: bus_mux port map (
imm_in => imm,
reg_source => reg_source,
a_mux => a_source,
a_out => a_bus,
reg_target => reg_target,
b_mux => b_source,
b_out => b_bus,
c_bus => c_bus,
c_memory => c_memory,
c_pc => pc_current,
c_pc_plus4 => pc_plus4,
c_mux => c_source,
reg_dest_out => reg_dest,
branch_func => branch_func,
take_branch => take_branch);
u6_alu: alu
generic map (alu_type => alu_type)
port map (
a_in => a_busD,
b_in => b_busD,
alu_function => alu_funcD,
c_alu => c_alu);
u7_shifter: shifter
generic map (shifter_type => shifter_type)
port map (
value => b_busD,
shift_amount => a_busD(4 downto 0),
shift_func => shift_funcD,
c_shift => c_shift);
u8_mult: mult
generic map (mult_type => mult_type)
port map (
clk => clk,
reset_in => reset,
a => a_busD,
b => b_busD,
mult_func => mult_funcD,
c_mult => c_mult,
pause_out => pause_mult);
pipeline2: if pipeline_stages <= 2 generate
a_busD <= a_bus;
b_busD <= b_bus;
alu_funcD <= alu_func;
shift_funcD <= shift_func;
mult_funcD <= mult_func;
rd_indexD <= rd_index;
reg_destD <= reg_dest;
pause_pipeline <= '0';
end generate; --pipeline2
pipeline3: if pipeline_stages > 2 generate
--When operating in three stage pipeline mode, the following signals
--are delayed by one clock cycle: a_bus, b_bus, alu/shift/mult_func,
--c_source, and rd_index.
u9_pipeline: pipeline port map (
clk => clk,
reset => reset,
a_bus => a_bus,
a_busD => a_busD,
b_bus => b_bus,
b_busD => b_busD,
alu_func => alu_func,
alu_funcD => alu_funcD,
shift_func => shift_func,
shift_funcD => shift_funcD,
mult_func => mult_func,
mult_funcD => mult_funcD,
reg_dest => reg_dest,
reg_destD => reg_destD,
rd_index => rd_index,
rd_indexD => rd_indexD,
rs_index => rs_index,
rt_index => rt_index,
pc_source => pc_source,
mem_source => mem_source,
a_source => a_source,
b_source => b_source,
c_source => c_source,
c_bus => c_bus,
pause_any => pause_any,
pause_pipeline => pause_pipeline);
end generate; --pipeline3
end; --architecture logic

542
plasma/logic/mlite_pack.vhd Normal file
View File

@@ -0,0 +1,542 @@
---------------------------------------------------------------------
-- TITLE: Plasma Misc. Package
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 2/15/01
-- FILENAME: mlite_pack.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Data types, constants, and add functions needed for the Plasma CPU.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
package mlite_pack is
constant ZERO : std_logic_vector(31 downto 0) :=
"00000000000000000000000000000000";
constant ONES : std_logic_vector(31 downto 0) :=
"11111111111111111111111111111111";
--make HIGH_Z equal to ZERO if compiler complains
constant HIGH_Z : std_logic_vector(31 downto 0) :=
"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
subtype alu_function_type is std_logic_vector(3 downto 0);
constant ALU_NOTHING : alu_function_type := "0000";
constant ALU_ADD : alu_function_type := "0001";
constant ALU_SUBTRACT : alu_function_type := "0010";
constant ALU_LESS_THAN : alu_function_type := "0011";
constant ALU_LESS_THAN_SIGNED : alu_function_type := "0100";
constant ALU_OR : alu_function_type := "0101";
constant ALU_AND : alu_function_type := "0110";
constant ALU_XOR : alu_function_type := "0111";
constant ALU_NOR : alu_function_type := "1000";
subtype shift_function_type is std_logic_vector(1 downto 0);
constant SHIFT_NOTHING : shift_function_type := "00";
constant SHIFT_LEFT_UNSIGNED : shift_function_type := "01";
constant SHIFT_RIGHT_SIGNED : shift_function_type := "11";
constant SHIFT_RIGHT_UNSIGNED : shift_function_type := "10";
subtype mult_function_type is std_logic_vector(3 downto 0);
constant MULT_NOTHING : mult_function_type := "0000";
constant MULT_READ_LO : mult_function_type := "0001";
constant MULT_READ_HI : mult_function_type := "0010";
constant MULT_WRITE_LO : mult_function_type := "0011";
constant MULT_WRITE_HI : mult_function_type := "0100";
constant MULT_MULT : mult_function_type := "0101";
constant MULT_SIGNED_MULT : mult_function_type := "0110";
constant MULT_DIVIDE : mult_function_type := "0111";
constant MULT_SIGNED_DIVIDE : mult_function_type := "1000";
subtype a_source_type is std_logic_vector(1 downto 0);
constant A_FROM_REG_SOURCE : a_source_type := "00";
constant A_FROM_IMM10_6 : a_source_type := "01";
constant A_FROM_PC : a_source_type := "10";
subtype b_source_type is std_logic_vector(1 downto 0);
constant B_FROM_REG_TARGET : b_source_type := "00";
constant B_FROM_IMM : b_source_type := "01";
constant B_FROM_SIGNED_IMM : b_source_type := "10";
constant B_FROM_IMMX4 : b_source_type := "11";
subtype c_source_type is std_logic_vector(2 downto 0);
constant C_FROM_NULL : c_source_type := "000";
constant C_FROM_ALU : c_source_type := "001";
constant C_FROM_SHIFT : c_source_type := "001"; --same as alu
constant C_FROM_MULT : c_source_type := "001"; --same as alu
constant C_FROM_MEMORY : c_source_type := "010";
constant C_FROM_PC : c_source_type := "011";
constant C_FROM_PC_PLUS4 : c_source_type := "100";
constant C_FROM_IMM_SHIFT16: c_source_type := "101";
constant C_FROM_REG_SOURCEN: c_source_type := "110";
subtype pc_source_type is std_logic_vector(1 downto 0);
constant FROM_INC4 : pc_source_type := "00";
constant FROM_OPCODE25_0 : pc_source_type := "01";
constant FROM_BRANCH : pc_source_type := "10";
constant FROM_LBRANCH : pc_source_type := "11";
subtype branch_function_type is std_logic_vector(2 downto 0);
constant BRANCH_LTZ : branch_function_type := "000";
constant BRANCH_LEZ : branch_function_type := "001";
constant BRANCH_EQ : branch_function_type := "010";
constant BRANCH_NE : branch_function_type := "011";
constant BRANCH_GEZ : branch_function_type := "100";
constant BRANCH_GTZ : branch_function_type := "101";
constant BRANCH_YES : branch_function_type := "110";
constant BRANCH_NO : branch_function_type := "111";
-- mode(32=1,16=2,8=3), signed, write
subtype mem_source_type is std_logic_vector(3 downto 0);
constant MEM_FETCH : mem_source_type := "0000";
constant MEM_READ32 : mem_source_type := "0100";
constant MEM_WRITE32 : mem_source_type := "0101";
constant MEM_READ16 : mem_source_type := "1000";
constant MEM_READ16S : mem_source_type := "1010";
constant MEM_WRITE16 : mem_source_type := "1001";
constant MEM_READ8 : mem_source_type := "1100";
constant MEM_READ8S : mem_source_type := "1110";
constant MEM_WRITE8 : mem_source_type := "1101";
function bv_adder(a : in std_logic_vector;
b : in std_logic_vector;
do_add: in std_logic) return std_logic_vector;
function bv_negate(a : in std_logic_vector) return std_logic_vector;
function bv_increment(a : in std_logic_vector(31 downto 2)
) return std_logic_vector;
function bv_inc(a : in std_logic_vector
) return std_logic_vector;
-- For Altera
COMPONENT lpm_ram_dp
generic (
LPM_WIDTH : natural; -- MUST be greater than 0
LPM_WIDTHAD : natural; -- MUST be greater than 0
LPM_NUMWORDS : natural := 0;
LPM_INDATA : string := "REGISTERED";
LPM_OUTDATA : string := "REGISTERED";
LPM_RDADDRESS_CONTROL : string := "REGISTERED";
LPM_WRADDRESS_CONTROL : string := "REGISTERED";
LPM_FILE : string := "UNUSED";
LPM_TYPE : string := "LPM_RAM_DP";
USE_EAB : string := "OFF";
INTENDED_DEVICE_FAMILY : string := "UNUSED";
RDEN_USED : string := "TRUE";
LPM_HINT : string := "UNUSED");
port (
RDCLOCK : in std_logic := '0';
RDCLKEN : in std_logic := '1';
RDADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
RDEN : in std_logic := '1';
DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
WRADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
WREN : in std_logic;
WRCLOCK : in std_logic := '0';
WRCLKEN : in std_logic := '1';
Q : out std_logic_vector(LPM_WIDTH-1 downto 0));
END COMPONENT;
-- For Altera
component LPM_RAM_DQ
generic (
LPM_WIDTH : natural; -- MUST be greater than 0
LPM_WIDTHAD : natural; -- MUST be greater than 0
LPM_NUMWORDS : natural := 0;
LPM_INDATA : string := "REGISTERED";
LPM_ADDRESS_CONTROL: string := "REGISTERED";
LPM_OUTDATA : string := "REGISTERED";
LPM_FILE : string := "UNUSED";
LPM_TYPE : string := "LPM_RAM_DQ";
USE_EAB : string := "OFF";
INTENDED_DEVICE_FAMILY : string := "UNUSED";
LPM_HINT : string := "UNUSED");
port (
DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
ADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
INCLOCK : in std_logic := '0';
OUTCLOCK : in std_logic := '0';
WE : in std_logic;
Q : out std_logic_vector(LPM_WIDTH-1 downto 0));
end component;
-- For Xilinx
component RAM16X1D
-- synthesis translate_off
generic (INIT : bit_vector := X"16");
-- synthesis translate_on
port (DPO : out STD_ULOGIC;
SPO : out STD_ULOGIC;
A0 : in STD_ULOGIC;
A1 : in STD_ULOGIC;
A2 : in STD_ULOGIC;
A3 : in STD_ULOGIC;
D : in STD_ULOGIC;
DPRA0 : in STD_ULOGIC;
DPRA1 : in STD_ULOGIC;
DPRA2 : in STD_ULOGIC;
DPRA3 : in STD_ULOGIC;
WCLK : in STD_ULOGIC;
WE : in STD_ULOGIC);
end component;
component pc_next
port(clk : in std_logic;
reset_in : in std_logic;
pc_new : in std_logic_vector(31 downto 2);
take_branch : in std_logic;
pause_in : in std_logic;
opcode25_0 : in std_logic_vector(25 downto 0);
pc_source : in pc_source_type;
pc_future : out std_logic_vector(31 downto 2);
pc_current : out std_logic_vector(31 downto 2);
pc_plus4 : out std_logic_vector(31 downto 2));
end component;
component mem_ctrl
port(clk : in std_logic;
reset_in : in std_logic;
pause_in : in std_logic;
nullify_op : in std_logic;
address_pc : in std_logic_vector(31 downto 2);
opcode_out : out std_logic_vector(31 downto 0);
address_in : in std_logic_vector(31 downto 0);
mem_source : in mem_source_type;
data_write : in std_logic_vector(31 downto 0);
data_read : out std_logic_vector(31 downto 0);
pause_out : out std_logic;
address_next : out std_logic_vector(31 downto 2);
byte_we_next : out std_logic_vector(3 downto 0);
address : out std_logic_vector(31 downto 2);
byte_we : out std_logic_vector(3 downto 0);
data_w : out std_logic_vector(31 downto 0);
data_r : in std_logic_vector(31 downto 0));
end component;
component control
port(opcode : in std_logic_vector(31 downto 0);
intr_signal : in std_logic;
rs_index : out std_logic_vector(5 downto 0);
rt_index : out std_logic_vector(5 downto 0);
rd_index : out std_logic_vector(5 downto 0);
imm_out : out std_logic_vector(15 downto 0);
alu_func : out alu_function_type;
shift_func : out shift_function_type;
mult_func : out mult_function_type;
branch_func : out branch_function_type;
a_source_out : out a_source_type;
b_source_out : out b_source_type;
c_source_out : out c_source_type;
pc_source_out: out pc_source_type;
mem_source_out:out mem_source_type;
exception_out: out std_logic);
end component;
component reg_bank
generic(memory_type : string := "XILINX_16X");
port(clk : in std_logic;
reset_in : in std_logic;
pause : in std_logic;
rs_index : in std_logic_vector(5 downto 0);
rt_index : in std_logic_vector(5 downto 0);
rd_index : in std_logic_vector(5 downto 0);
reg_source_out : out std_logic_vector(31 downto 0);
reg_target_out : out std_logic_vector(31 downto 0);
reg_dest_new : in std_logic_vector(31 downto 0);
intr_enable : out std_logic);
end component;
component bus_mux
port(imm_in : in std_logic_vector(15 downto 0);
reg_source : in std_logic_vector(31 downto 0);
a_mux : in a_source_type;
a_out : out std_logic_vector(31 downto 0);
reg_target : in std_logic_vector(31 downto 0);
b_mux : in b_source_type;
b_out : out std_logic_vector(31 downto 0);
c_bus : in std_logic_vector(31 downto 0);
c_memory : in std_logic_vector(31 downto 0);
c_pc : in std_logic_vector(31 downto 2);
c_pc_plus4 : in std_logic_vector(31 downto 2);
c_mux : in c_source_type;
reg_dest_out : out std_logic_vector(31 downto 0);
branch_func : in branch_function_type;
take_branch : out std_logic);
end component;
component alu
generic(alu_type : string := "DEFAULT");
port(a_in : in std_logic_vector(31 downto 0);
b_in : in std_logic_vector(31 downto 0);
alu_function : in alu_function_type;
c_alu : out std_logic_vector(31 downto 0));
end component;
component shifter
generic(shifter_type : string := "DEFAULT" );
port(value : in std_logic_vector(31 downto 0);
shift_amount : in std_logic_vector(4 downto 0);
shift_func : in shift_function_type;
c_shift : out std_logic_vector(31 downto 0));
end component;
component mult
generic(mult_type : string := "DEFAULT");
port(clk : in std_logic;
reset_in : in std_logic;
a, b : in std_logic_vector(31 downto 0);
mult_func : in mult_function_type;
c_mult : out std_logic_vector(31 downto 0);
pause_out : out std_logic);
end component;
component pipeline
port(clk : in std_logic;
reset : in std_logic;
a_bus : in std_logic_vector(31 downto 0);
a_busD : out std_logic_vector(31 downto 0);
b_bus : in std_logic_vector(31 downto 0);
b_busD : out std_logic_vector(31 downto 0);
alu_func : in alu_function_type;
alu_funcD : out alu_function_type;
shift_func : in shift_function_type;
shift_funcD : out shift_function_type;
mult_func : in mult_function_type;
mult_funcD : out mult_function_type;
reg_dest : in std_logic_vector(31 downto 0);
reg_destD : out std_logic_vector(31 downto 0);
rd_index : in std_logic_vector(5 downto 0);
rd_indexD : out std_logic_vector(5 downto 0);
rs_index : in std_logic_vector(5 downto 0);
rt_index : in std_logic_vector(5 downto 0);
pc_source : in pc_source_type;
mem_source : in mem_source_type;
a_source : in a_source_type;
b_source : in b_source_type;
c_source : in c_source_type;
c_bus : in std_logic_vector(31 downto 0);
pause_any : in std_logic;
pause_pipeline : out std_logic);
end component;
component mlite_cpu
generic(memory_type : string := "XILINX_16X"; --ALTERA_LPM, or DUAL_PORT_
mult_type : string := "DEFAULT";
shifter_type : string := "DEFAULT";
alu_type : string := "DEFAULT";
pipeline_stages : natural := 2); --2 or 3
port(clk : in std_logic;
reset_in : in std_logic;
intr_in : in std_logic;
address_next : out std_logic_vector(31 downto 2); --for synch ram
byte_we_next : out std_logic_vector(3 downto 0);
address : out std_logic_vector(31 downto 2);
byte_we : out std_logic_vector(3 downto 0);
data_w : out std_logic_vector(31 downto 0);
data_r : in std_logic_vector(31 downto 0);
mem_pause : in std_logic);
end component;
component cache
generic(memory_type : string := "DEFAULT");
port(clk : in std_logic;
reset : in std_logic;
address_next : in std_logic_vector(31 downto 2);
byte_we_next : in std_logic_vector(3 downto 0);
cpu_address : in std_logic_vector(31 downto 2);
mem_busy : in std_logic;
cache_check : out std_logic; --Stage1: address_next in first 2MB DDR
cache_checking : out std_logic; --Stage2: cache checking
cache_miss : out std_logic); --Stage2-3: cache miss
end component; --cache
component ram
generic(memory_type : string := "DEFAULT");
port(clk : in std_logic;
enable : in std_logic;
write_byte_enable : in std_logic_vector(3 downto 0);
address : in std_logic_vector(31 downto 2);
data_write : in std_logic_vector(31 downto 0);
data_read : out std_logic_vector(31 downto 0));
end component; --ram
component uart
generic(log_file : string := "UNUSED");
port(clk : in std_logic;
reset : in std_logic;
enable_read : in std_logic;
enable_write : in std_logic;
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
uart_read : in std_logic;
uart_write : out std_logic;
busy_write : out std_logic;
data_avail : out std_logic);
end component; --uart
component eth_dma
port(clk : in std_logic; --25 MHz
reset : in std_logic;
enable_eth : in std_logic;
select_eth : in std_logic;
rec_isr : out std_logic;
send_isr : out std_logic;
address : out std_logic_vector(31 downto 2); --to DDR
byte_we : out std_logic_vector(3 downto 0);
data_write : out std_logic_vector(31 downto 0);
data_read : in std_logic_vector(31 downto 0);
pause_in : in std_logic;
mem_address : in std_logic_vector(31 downto 2); --from CPU
mem_byte_we : in std_logic_vector(3 downto 0);
data_w : in std_logic_vector(31 downto 0);
pause_out : out std_logic;
E_RX_CLK : in std_logic; --2.5 MHz receive
E_RX_DV : in std_logic; --data valid
E_RXD : in std_logic_vector(3 downto 0); --receive nibble
E_TX_CLK : in std_logic; --2.5 MHz transmit
E_TX_EN : out std_logic; --transmit enable
E_TXD : out std_logic_vector(3 downto 0)); --transmit nibble
end component; --eth_dma
component plasma
generic(memory_type : string := "XILINX_X16"; --"DUAL_PORT_" "ALTERA_LPM";
log_file : string := "UNUSED";
ethernet : std_logic := '0';
use_cache : std_logic := '0');
port(clk : in std_logic;
reset : in std_logic;
uart_write : out std_logic;
uart_read : in std_logic;
address : out std_logic_vector(31 downto 2);
byte_we : out std_logic_vector(3 downto 0);
data_write : out std_logic_vector(31 downto 0);
data_read : in std_logic_vector(31 downto 0);
mem_pause_in : in std_logic;
no_ddr_start : out std_logic;
no_ddr_stop : out std_logic;
gpio0_out : out std_logic_vector(31 downto 0);
gpioA_in : in std_logic_vector(31 downto 0));
end component; --plasma
component ddr_ctrl
port(clk : in std_logic;
clk_2x : in std_logic;
reset_in : in std_logic;
address : in std_logic_vector(25 downto 2);
byte_we : in std_logic_vector(3 downto 0);
data_w : in std_logic_vector(31 downto 0);
data_r : out std_logic_vector(31 downto 0);
active : in std_logic;
no_start : in std_logic;
no_stop : in std_logic;
pause : out std_logic;
SD_CK_P : out std_logic; --clock_positive
SD_CK_N : out std_logic; --clock_negative
SD_CKE : out std_logic; --clock_enable
SD_BA : out std_logic_vector(1 downto 0); --bank_address
SD_A : out std_logic_vector(12 downto 0); --address(row or col)
SD_CS : out std_logic; --chip_select
SD_RAS : out std_logic; --row_address_strobe
SD_CAS : out std_logic; --column_address_strobe
SD_WE : out std_logic; --write_enable
SD_DQ : inout std_logic_vector(15 downto 0); --data
SD_UDM : out std_logic; --upper_byte_enable
SD_UDQS : inout std_logic; --upper_data_strobe
SD_LDM : out std_logic; --low_byte_enable
SD_LDQS : inout std_logic); --low_data_strobe
end component; --ddr
end; --package mlite_pack
package body mlite_pack is
function bv_adder(a : in std_logic_vector;
b : in std_logic_vector;
do_add: in std_logic) return std_logic_vector is
variable carry_in : std_logic;
variable bb : std_logic_vector(a'length-1 downto 0);
variable result : std_logic_vector(a'length downto 0);
begin
if do_add = '1' then
bb := b;
carry_in := '0';
else
bb := not b;
carry_in := '1';
end if;
for index in 0 to a'length-1 loop
result(index) := a(index) xor bb(index) xor carry_in;
carry_in := (carry_in and (a(index) or bb(index))) or
(a(index) and bb(index));
end loop;
result(a'length) := carry_in xnor do_add;
return result;
end; --function
function bv_negate(a : in std_logic_vector) return std_logic_vector is
variable carry_in : std_logic;
variable not_a : std_logic_vector(a'length-1 downto 0);
variable result : std_logic_vector(a'length-1 downto 0);
begin
not_a := not a;
carry_in := '1';
for index in a'reverse_range loop
result(index) := not_a(index) xor carry_in;
carry_in := carry_in and not_a(index);
end loop;
return result;
end; --function
function bv_increment(a : in std_logic_vector(31 downto 2)
) return std_logic_vector is
variable carry_in : std_logic;
variable result : std_logic_vector(31 downto 2);
begin
carry_in := '1';
for index in 2 to 31 loop
result(index) := a(index) xor carry_in;
carry_in := a(index) and carry_in;
end loop;
return result;
end; --function
function bv_inc(a : in std_logic_vector
) return std_logic_vector is
variable carry_in : std_logic;
variable result : std_logic_vector(a'length-1 downto 0);
begin
carry_in := '1';
for index in 0 to a'length-1 loop
result(index) := a(index) xor carry_in;
carry_in := a(index) and carry_in;
end loop;
return result;
end; --function
end; --package body

208
plasma/logic/mult.vhd Normal file
View File

@@ -0,0 +1,208 @@
---------------------------------------------------------------------
-- TITLE: Multiplication and Division Unit
-- AUTHORS: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 1/31/01
-- FILENAME: mult.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Implements the multiplication and division unit in 32 clocks.
--
-- To reduce space, compile your code using the flag "-mno-mul" which
-- will use software base routines in math.c if USE_SW_MULT is defined.
-- Then remove references to the entity mult in mlite_cpu.vhd.
--
-- MULTIPLICATION
-- long64 answer = 0
-- for(i = 0; i < 32; ++i)
-- {
-- answer = (answer >> 1) + (((b&1)?a:0) << 31);
-- b = b >> 1;
-- }
--
-- DIVISION
-- long upper=a, lower=0;
-- a = b << 31;
-- for(i = 0; i < 32; ++i)
-- {
-- lower = lower << 1;
-- if(upper >= a && a && b < 2)
-- {
-- upper = upper - a;
-- lower |= 1;
-- }
-- a = ((b&2) << 30) | (a >> 1);
-- b = b >> 1;
-- }
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;
use work.mlite_pack.all;
entity mult is
generic(mult_type : string := "DEFAULT");
port(clk : in std_logic;
reset_in : in std_logic;
a, b : in std_logic_vector(31 downto 0);
mult_func : in mult_function_type;
c_mult : out std_logic_vector(31 downto 0);
pause_out : out std_logic);
end; --entity mult
architecture logic of mult is
constant MODE_MULT : std_logic := '1';
constant MODE_DIV : std_logic := '0';
signal mode_reg : std_logic;
signal negate_reg : std_logic;
signal sign_reg : std_logic;
signal sign2_reg : std_logic;
signal count_reg : std_logic_vector(5 downto 0);
signal aa_reg : std_logic_vector(31 downto 0);
signal bb_reg : std_logic_vector(31 downto 0);
signal upper_reg : std_logic_vector(31 downto 0);
signal lower_reg : std_logic_vector(31 downto 0);
signal a_neg : std_logic_vector(31 downto 0);
signal b_neg : std_logic_vector(31 downto 0);
signal sum : std_logic_vector(32 downto 0);
begin
-- Result
c_mult <= lower_reg when mult_func = MULT_READ_LO and negate_reg = '0' else
bv_negate(lower_reg) when mult_func = MULT_READ_LO
and negate_reg = '1' else
upper_reg when mult_func = MULT_READ_HI else
ZERO;
pause_out <= '1' when (count_reg /= "000000") and
(mult_func = MULT_READ_LO or mult_func = MULT_READ_HI) else '0';
-- ABS and remainder signals
a_neg <= bv_negate(a);
b_neg <= bv_negate(b);
sum <= bv_adder(upper_reg, aa_reg, mode_reg);
--multiplication/division unit
mult_proc: process(clk, reset_in, a, b, mult_func,
a_neg, b_neg, sum, sign_reg, mode_reg, negate_reg,
count_reg, aa_reg, bb_reg, upper_reg, lower_reg)
variable count : std_logic_vector(2 downto 0);
begin
count := "001";
if reset_in = '1' then
mode_reg <= '0';
negate_reg <= '0';
sign_reg <= '0';
sign2_reg <= '0';
count_reg <= "000000";
aa_reg <= ZERO;
bb_reg <= ZERO;
upper_reg <= ZERO;
lower_reg <= ZERO;
elsif rising_edge(clk) then
case mult_func is
when MULT_WRITE_LO =>
lower_reg <= a;
negate_reg <= '0';
when MULT_WRITE_HI =>
upper_reg <= a;
negate_reg <= '0';
when MULT_MULT =>
mode_reg <= MODE_MULT;
aa_reg <= a;
bb_reg <= b;
upper_reg <= ZERO;
count_reg <= "100000";
negate_reg <= '0';
sign_reg <= '0';
sign2_reg <= '0';
when MULT_SIGNED_MULT =>
mode_reg <= MODE_MULT;
if b(31) = '0' then
aa_reg <= a;
bb_reg <= b;
sign_reg <= a(31);
else
aa_reg <= a_neg;
bb_reg <= b_neg;
sign_reg <= a_neg(31);
end if;
sign2_reg <= '0';
upper_reg <= ZERO;
count_reg <= "100000";
negate_reg <= '0';
when MULT_DIVIDE =>
mode_reg <= MODE_DIV;
aa_reg <= b(0) & ZERO(30 downto 0);
bb_reg <= b;
upper_reg <= a;
count_reg <= "100000";
negate_reg <= '0';
when MULT_SIGNED_DIVIDE =>
mode_reg <= MODE_DIV;
if b(31) = '0' then
aa_reg(31) <= b(0);
bb_reg <= b;
else
aa_reg(31) <= b_neg(0);
bb_reg <= b_neg;
end if;
if a(31) = '0' then
upper_reg <= a;
else
upper_reg <= a_neg;
end if;
aa_reg(30 downto 0) <= ZERO(30 downto 0);
count_reg <= "100000";
negate_reg <= a(31) xor b(31);
when others =>
if count_reg /= "000000" then
if mode_reg = MODE_MULT then
-- Multiplication
if bb_reg(0) = '1' then
upper_reg <= (sign_reg xor sum(32)) & sum(31 downto 1);
lower_reg <= sum(0) & lower_reg(31 downto 1);
sign2_reg <= sign2_reg or sign_reg;
sign_reg <= '0';
bb_reg <= '0' & bb_reg(31 downto 1);
-- The following six lines are optional for speedup
--elsif bb_reg(3 downto 0) = "0000" and sign2_reg = '0' and
-- count_reg(5 downto 2) /= "0000" then
-- upper_reg <= "0000" & upper_reg(31 downto 4);
-- lower_reg <= upper_reg(3 downto 0) & lower_reg(31 downto 4);
-- count := "100";
-- bb_reg <= "0000" & bb_reg(31 downto 4);
else
upper_reg <= sign2_reg & upper_reg(31 downto 1);
lower_reg <= upper_reg(0) & lower_reg(31 downto 1);
bb_reg <= '0' & bb_reg(31 downto 1);
end if;
else
-- Division
if sum(32) = '0' and aa_reg /= ZERO and
bb_reg(31 downto 1) = ZERO(31 downto 1) then
upper_reg <= sum(31 downto 0);
lower_reg(0) <= '1';
else
lower_reg(0) <= '0';
end if;
aa_reg <= bb_reg(1) & aa_reg(31 downto 1);
lower_reg(31 downto 1) <= lower_reg(30 downto 0);
bb_reg <= '0' & bb_reg(31 downto 1);
end if;
count_reg <= count_reg - count;
end if; --count
end case;
end if;
end process;
end; --architecture logic

71
plasma/logic/pc_next.vhd Normal file
View File

@@ -0,0 +1,71 @@
---------------------------------------------------------------------
-- TITLE: Program Counter Next
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 2/8/01
-- FILENAME: pc_next.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Implements the Program Counter logic.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.mlite_pack.all;
entity pc_next is
port(clk : in std_logic;
reset_in : in std_logic;
pc_new : in std_logic_vector(31 downto 2);
take_branch : in std_logic;
pause_in : in std_logic;
opcode25_0 : in std_logic_vector(25 downto 0);
pc_source : in pc_source_type;
pc_future : out std_logic_vector(31 downto 2);
pc_current : out std_logic_vector(31 downto 2);
pc_plus4 : out std_logic_vector(31 downto 2));
end; --pc_next
architecture logic of pc_next is
signal pc_reg : std_logic_vector(31 downto 2);
begin
pc_select: process(clk, reset_in, pc_new, take_branch, pause_in,
opcode25_0, pc_source, pc_reg)
variable pc_inc : std_logic_vector(31 downto 2);
variable pc_next : std_logic_vector(31 downto 2);
begin
pc_inc := bv_increment(pc_reg); --pc_reg+1
case pc_source is
when FROM_INC4 =>
pc_next := pc_inc;
when FROM_OPCODE25_0 =>
pc_next := pc_reg(31 downto 28) & opcode25_0;
when FROM_BRANCH | FROM_LBRANCH =>
if take_branch = '1' then
pc_next := pc_new;
else
pc_next := pc_inc;
end if;
when others =>
pc_next := pc_inc;
end case;
if pause_in = '1' then
pc_next := pc_reg;
end if;
if reset_in = '1' then
pc_reg <= ZERO(31 downto 2);
pc_next := pc_reg;
elsif rising_edge(clk) then
pc_reg <= pc_next;
end if;
pc_future <= pc_next;
pc_current <= pc_reg;
pc_plus4 <= pc_inc;
end process;
end; --logic

139
plasma/logic/pipeline.vhd Normal file
View File

@@ -0,0 +1,139 @@
---------------------------------------------------------------------
-- TITLE: Pipeline
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 6/24/02
-- FILENAME: pipeline.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Controls the three stage pipeline by delaying the signals:
-- a_bus, b_bus, alu/shift/mult_func, c_source, and rs_index.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.mlite_pack.all;
--Note: sigD <= sig after rising_edge(clk)
entity pipeline is
port(clk : in std_logic;
reset : in std_logic;
a_bus : in std_logic_vector(31 downto 0);
a_busD : out std_logic_vector(31 downto 0);
b_bus : in std_logic_vector(31 downto 0);
b_busD : out std_logic_vector(31 downto 0);
alu_func : in alu_function_type;
alu_funcD : out alu_function_type;
shift_func : in shift_function_type;
shift_funcD : out shift_function_type;
mult_func : in mult_function_type;
mult_funcD : out mult_function_type;
reg_dest : in std_logic_vector(31 downto 0);
reg_destD : out std_logic_vector(31 downto 0);
rd_index : in std_logic_vector(5 downto 0);
rd_indexD : out std_logic_vector(5 downto 0);
rs_index : in std_logic_vector(5 downto 0);
rt_index : in std_logic_vector(5 downto 0);
pc_source : in pc_source_type;
mem_source : in mem_source_type;
a_source : in a_source_type;
b_source : in b_source_type;
c_source : in c_source_type;
c_bus : in std_logic_vector(31 downto 0);
pause_any : in std_logic;
pause_pipeline : out std_logic);
end; --entity pipeline
architecture logic of pipeline is
signal rd_index_reg : std_logic_vector(5 downto 0);
signal reg_dest_reg : std_logic_vector(31 downto 0);
signal reg_dest_delay : std_logic_vector(31 downto 0);
signal c_source_reg : c_source_type;
signal pause_enable_reg : std_logic;
begin
--When operating in three stage pipeline mode, the following signals
--are delayed by one clock cycle: a_bus, b_bus, alu/shift/mult_func,
--c_source, and rd_index.
pipeline3: process(clk, reset, a_bus, b_bus, alu_func, shift_func, mult_func,
rd_index, rd_index_reg, pause_any, pause_enable_reg,
rs_index, rt_index,
pc_source, mem_source, a_source, b_source, c_source, c_source_reg,
reg_dest, reg_dest_reg, reg_dest_delay, c_bus)
variable pause_mult_clock : std_logic;
variable freeze_pipeline : std_logic;
begin
if (pc_source /= FROM_INC4 and pc_source /= FROM_OPCODE25_0) or
mem_source /= MEM_FETCH or
(mult_func = MULT_READ_LO or mult_func = MULT_READ_HI) then
pause_mult_clock := '1';
else
pause_mult_clock := '0';
end if;
freeze_pipeline := not (pause_mult_clock and pause_enable_reg) and pause_any;
pause_pipeline <= pause_mult_clock and pause_enable_reg;
rd_indexD <= rd_index_reg;
-- The value written back into the register bank, signal reg_dest is tricky.
-- If reg_dest comes from the ALU via the signal c_bus, it is already delayed
-- into stage #3, because a_busD and b_busD are delayed. If reg_dest comes from
-- c_memory, pc_current, or pc_plus4 then reg_dest hasn't yet been delayed into
-- stage #3.
-- Instead of delaying c_memory, pc_current, and pc_plus4, these signals
-- are multiplexed into reg_dest which is then delayed. The decision to use
-- the already delayed c_bus or the delayed value of reg_dest (reg_dest_reg) is
-- based on a delayed value of c_source (c_source_reg).
if c_source_reg = C_FROM_ALU then
reg_dest_delay <= c_bus; --delayed by 1 clock cycle via a_busD & b_busD
else
reg_dest_delay <= reg_dest_reg; --need to delay 1 clock cycle from reg_dest
end if;
reg_destD <= reg_dest_delay;
if reset = '1' then
a_busD <= ZERO;
b_busD <= ZERO;
alu_funcD <= ALU_NOTHING;
shift_funcD <= SHIFT_NOTHING;
mult_funcD <= MULT_NOTHING;
reg_dest_reg <= ZERO;
c_source_reg <= "000";
rd_index_reg <= "000000";
pause_enable_reg <= '0';
elsif rising_edge(clk) then
if freeze_pipeline = '0' then
if (rs_index = "000000" or rs_index /= rd_index_reg) or
(a_source /= A_FROM_REG_SOURCE or pause_enable_reg = '0') then
a_busD <= a_bus;
else
a_busD <= reg_dest_delay; --rs from previous operation (bypass stage)
end if;
if (rt_index = "000000" or rt_index /= rd_index_reg) or
(b_source /= B_FROM_REG_TARGET or pause_enable_reg = '0') then
b_busD <= b_bus;
else
b_busD <= reg_dest_delay; --rt from previous operation
end if;
alu_funcD <= alu_func;
shift_funcD <= shift_func;
mult_funcD <= mult_func;
reg_dest_reg <= reg_dest;
c_source_reg <= c_source;
rd_index_reg <= rd_index;
end if;
if pause_enable_reg = '0' and pause_any = '0' then
pause_enable_reg <= '1'; --enable pause_pipeline
elsif pause_mult_clock = '1' then
pause_enable_reg <= '0'; --disable pause_pipeline
end if;
end if;
end process; --pipeline3
end; --logic

301
plasma/logic/plasma.vhd Normal file
View File

@@ -0,0 +1,301 @@
---------------------------------------------------------------------
-- TITLE: Plasma (CPU core with memory)
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 6/4/02
-- FILENAME: plasma.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- This entity combines the CPU core with memory and a UART.
--
-- Memory Map:
-- 0x00000000 - 0x0000ffff Internal RAM (8KB)
-- 0x10000000 - 0x100fffff External RAM (1MB)
-- Access all Misc registers with 32-bit accesses
-- 0x20000000 Uart Write (will pause CPU if busy)
-- 0x20000000 Uart Read
-- 0x20000010 IRQ Mask
-- 0x20000020 IRQ Status
-- 0x20000030 GPIO0 Out Set bits
-- 0x20000040 GPIO0 Out Clear bits
-- 0x20000050 GPIOA In
-- 0x20000060 Counter
-- 0x20000070 Ethernet transmit count
-- IRQ bits:
-- 7 GPIO31
-- 6 ^GPIO31
-- 5 EthernetSendDone
-- 4 EthernetReceive
-- 3 Counter(18)
-- 2 ^Counter(18)
-- 1 ^UartWriteBusy
-- 0 UartDataAvailable
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.mlite_pack.all;
entity plasma is
generic(memory_type : string := "XILINX_16X"; --"DUAL_PORT_" "ALTERA_LPM";
log_file : string := "UNUSED";
ethernet : std_logic := '0';
use_cache : std_logic := '0');
port(clk : in std_logic;
reset : in std_logic;
uart_write : out std_logic;
uart_read : in std_logic;
address : out std_logic_vector(31 downto 2);
byte_we : out std_logic_vector(3 downto 0);
data_write : out std_logic_vector(31 downto 0);
data_read : in std_logic_vector(31 downto 0);
mem_pause_in : in std_logic;
no_ddr_start : out std_logic;
no_ddr_stop : out std_logic;
gpio0_out : out std_logic_vector(31 downto 0);
gpioA_in : in std_logic_vector(31 downto 0));
end; --entity plasma
architecture logic of plasma is
signal address_next : std_logic_vector(31 downto 2);
signal byte_we_next : std_logic_vector(3 downto 0);
signal cpu_address : std_logic_vector(31 downto 0);
signal cpu_byte_we : std_logic_vector(3 downto 0);
signal cpu_data_w : std_logic_vector(31 downto 0);
signal cpu_data_r : std_logic_vector(31 downto 0);
signal cpu_pause : std_logic;
signal data_read_uart : std_logic_vector(7 downto 0);
signal write_enable : std_logic;
signal eth_pause_in : std_logic;
signal eth_pause : std_logic;
signal mem_busy : std_logic;
signal enable_misc : std_logic;
signal enable_uart : std_logic;
signal enable_uart_read : std_logic;
signal enable_uart_write : std_logic;
signal enable_eth : std_logic;
signal gpio0_reg : std_logic_vector(31 downto 0);
signal uart_write_busy : std_logic;
signal uart_data_avail : std_logic;
signal irq_mask_reg : std_logic_vector(7 downto 0);
signal irq_status : std_logic_vector(7 downto 0);
signal irq : std_logic;
signal irq_eth_rec : std_logic;
signal irq_eth_send : std_logic;
signal counter_reg : std_logic_vector(31 downto 0);
signal ram_enable : std_logic;
signal ram_byte_we : std_logic_vector(3 downto 0);
signal ram_address : std_logic_vector(31 downto 2);
signal ram_data_w : std_logic_vector(31 downto 0);
signal ram_data_r : std_logic_vector(31 downto 0);
signal cache_check : std_logic;
signal cache_checking : std_logic;
signal cache_miss : std_logic;
signal cache_hit : std_logic;
begin --architecture
write_enable <= '1' when cpu_byte_we /= "0000" else '0';
mem_busy <= eth_pause or mem_pause_in;
cache_hit <= cache_checking and not cache_miss;
cpu_pause <= (uart_write_busy and enable_uart and write_enable) or --UART busy
cache_miss or --Cache wait
(cpu_address(28) and not cache_hit and mem_busy); --DDR or flash --DDR in use
irq_status <= gpioA_in(31) & not gpioA_in(31) &
irq_eth_send & irq_eth_rec &
counter_reg(18) & not counter_reg(18) &
not uart_write_busy & uart_data_avail;
irq <= '1' when (irq_status and irq_mask_reg) /= ZERO(7 downto 0) else '0';
gpio0_out(31 downto 29) <= gpio0_reg(31 downto 29);
gpio0_out(23 downto 0) <= gpio0_reg(23 downto 0);
enable_misc <= '1' when cpu_address(30 downto 28) = "010" else '0';
enable_uart <= '1' when enable_misc = '1' and cpu_address(7 downto 4) = "0000" else '0';
enable_uart_read <= enable_uart and not write_enable;
enable_uart_write <= enable_uart and write_enable;
enable_eth <= '1' when enable_misc = '1' and cpu_address(7 downto 4) = "0111" else '0';
cpu_address(1 downto 0) <= "00";
u1_cpu: mlite_cpu
generic map (memory_type => memory_type)
PORT MAP (
clk => clk,
reset_in => reset,
intr_in => irq,
address_next => address_next, --before rising_edge(clk)
byte_we_next => byte_we_next,
address => cpu_address(31 downto 2), --after rising_edge(clk)
byte_we => cpu_byte_we,
data_w => cpu_data_w,
data_r => cpu_data_r,
mem_pause => cpu_pause);
opt_cache: if use_cache = '0' generate
cache_check <= '0';
cache_checking <= '0';
cache_miss <= '0';
end generate;
opt_cache2: if use_cache = '1' generate
--Control 4KB unified cache that uses the upper 4KB of the 8KB
--internal RAM. Only lowest 2MB of DDR is cached.
u_cache: cache
generic map (memory_type => memory_type)
PORT MAP (
clk => clk,
reset => reset,
address_next => address_next,
byte_we_next => byte_we_next,
cpu_address => cpu_address(31 downto 2),
mem_busy => mem_busy,
cache_check => cache_check, --Stage1: address_next in first 2MB DDR
cache_checking => cache_checking, --Stage2
cache_miss => cache_miss); --Stage3
end generate; --opt_cache2
no_ddr_start <= not eth_pause and cache_checking;
no_ddr_stop <= not eth_pause and cache_miss;
eth_pause_in <= mem_pause_in or (not eth_pause and cache_miss and not cache_checking);
misc_proc: process(clk, reset, cpu_address, enable_misc,
ram_data_r, data_read, data_read_uart, cpu_pause,
irq_mask_reg, irq_status, gpio0_reg, write_enable,
cache_checking,
gpioA_in, counter_reg, cpu_data_w)
begin
case cpu_address(30 downto 28) is
when "000" => --internal RAM
cpu_data_r <= ram_data_r;
when "001" => --external RAM
if cache_checking = '1' then
cpu_data_r <= ram_data_r; --cache
else
cpu_data_r <= data_read; --DDR
end if;
when "010" => --misc
case cpu_address(6 downto 4) is
when "000" => --uart
cpu_data_r <= ZERO(31 downto 8) & data_read_uart;
when "001" => --irq_mask
cpu_data_r <= ZERO(31 downto 8) & irq_mask_reg;
when "010" => --irq_status
cpu_data_r <= ZERO(31 downto 8) & irq_status;
when "011" => --gpio0
cpu_data_r <= gpio0_reg;
when "101" => --gpioA
cpu_data_r <= gpioA_in;
when "110" => --counter
cpu_data_r <= counter_reg;
when others =>
cpu_data_r <= gpioA_in;
end case;
when "011" => --flash
cpu_data_r <= data_read;
when others =>
cpu_data_r <= ZERO;
end case;
if reset = '1' then
irq_mask_reg <= ZERO(7 downto 0);
gpio0_reg <= ZERO;
counter_reg <= ZERO;
elsif rising_edge(clk) then
if cpu_pause = '0' then
if enable_misc = '1' and write_enable = '1' then
if cpu_address(6 downto 4) = "001" then
irq_mask_reg <= cpu_data_w(7 downto 0);
elsif cpu_address(6 downto 4) = "011" then
gpio0_reg <= gpio0_reg or cpu_data_w;
elsif cpu_address(6 downto 4) = "100" then
gpio0_reg <= gpio0_reg and not cpu_data_w;
end if;
end if;
end if;
counter_reg <= bv_inc(counter_reg);
end if;
end process;
ram_enable <= '1' when address_next(30 downto 28) = "000" or
cache_check = '1' or cache_miss = '1' else '0';
ram_byte_we <= byte_we_next when cache_miss = '0' else "1111";
ram_address(31 downto 13) <= ZERO(31 downto 13);
ram_address(12 downto 2) <= (address_next(12) or cache_check) & address_next(11 downto 2)
when cache_miss = '0' else
'1' & cpu_address(11 downto 2); --Update cache after cache miss
ram_data_w <= cpu_data_w when cache_miss = '0' else data_read;
u2_ram: ram
generic map (memory_type => memory_type)
port map (
clk => clk,
enable => ram_enable,
write_byte_enable => ram_byte_we,
address => ram_address,
data_write => ram_data_w,
data_read => ram_data_r);
u3_uart: uart
generic map (log_file => log_file)
port map(
clk => clk,
reset => reset,
enable_read => enable_uart_read,
enable_write => enable_uart_write,
data_in => cpu_data_w(7 downto 0),
data_out => data_read_uart,
uart_read => uart_read,
uart_write => uart_write,
busy_write => uart_write_busy,
data_avail => uart_data_avail);
dma_gen: if ethernet = '0' generate
address <= cpu_address(31 downto 2);
byte_we <= cpu_byte_we;
data_write <= cpu_data_w;
eth_pause <= '0';
gpio0_out(28 downto 24) <= ZERO(28 downto 24);
irq_eth_rec <= '0';
irq_eth_send <= '0';
end generate;
dma_gen2: if ethernet = '1' generate
u4_eth: eth_dma
port map(
clk => clk,
reset => reset,
enable_eth => gpio0_reg(24),
select_eth => enable_eth,
rec_isr => irq_eth_rec,
send_isr => irq_eth_send,
address => address, --to DDR
byte_we => byte_we,
data_write => data_write,
data_read => data_read,
pause_in => eth_pause_in,
mem_address => cpu_address(31 downto 2), --from CPU
mem_byte_we => cpu_byte_we,
data_w => cpu_data_w,
pause_out => eth_pause,
E_RX_CLK => gpioA_in(20),
E_RX_DV => gpioA_in(19),
E_RXD => gpioA_in(18 downto 15),
E_TX_CLK => gpioA_in(14),
E_TX_EN => gpio0_out(28),
E_TXD => gpio0_out(27 downto 24));
end generate;
end; --architecture logic

279
plasma/logic/plasma_3e.ucf Normal file
View File

@@ -0,0 +1,279 @@
#####################################################
### SPARTAN-3E STARTER KIT BOARD CONSTRAINTS FILE
#####################################################
# ==== Analog-to-Digital Converter (ADC) ====
# some connections shared with SPI Flash, DAC, ADC, and AMP
#NET "AD_CONV" LOC = "P11" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ;
# ==== Programmable Gain Amplifier (AMP) ====
# some connections shared with SPI Flash, DAC, ADC, and AMP
#NET "AMP_CS" LOC = "N7" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ;
#NET "AMP_DOUT" LOC = "E18" | IOSTANDARD = LVCMOS33 ;
#NET "AMP_SHDN" LOC = "P7" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ;
# ==== Pushbuttons (BTN) ====
NET "BTN_EAST" LOC = "H13" | IOSTANDARD = LVTTL | PULLDOWN ;
NET "BTN_NORTH" LOC = "V4" | IOSTANDARD = LVTTL | PULLDOWN ;
NET "BTN_SOUTH" LOC = "K17" | IOSTANDARD = LVTTL | PULLDOWN ;
NET "BTN_WEST" LOC = "D18" | IOSTANDARD = LVTTL | PULLDOWN ;
# ==== Clock inputs (CLK) ====
NET "CLK_50MHZ" LOC = "C9" | IOSTANDARD = LVCMOS33 ;
# Define clock period for 50 MHz oscillator (40%/60% duty-cycle)
NET "CLK_50MHZ" PERIOD = 20 ns HIGH 40 %;
#NET "CLK_AUX" LOC = "B8" | IOSTANDARD = LVCMOS33 ;
#NET "CLK_SMA" LOC = "A10" | IOSTANDARD = LVCMOS33 ;
# ==== Digital-to-Analog Converter (DAC) ====
# some connections shared with SPI Flash, DAC, ADC, and AMP
#NET "DAC_CLR" LOC = "P8" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
#NET "DAC_CS" LOC = "N8" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
# ==== 1-Wire Secure EEPROM (DS)
#NET "DS_WIRE" LOC = "U4" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
# ==== Ethernet PHY (E) ====
#NET "E_COL" LOC = "U6" | IOSTANDARD = LVCMOS33 ;
#NET "E_CRS" LOC = "U13" | IOSTANDARD = LVCMOS33 ;
NET "E_MDC" LOC = "P9" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "E_MDIO" LOC = "U5" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "E_RX_CLK" LOC = "V3" | IOSTANDARD = LVCMOS33 ;
NET "E_RX_DV" LOC = "V2" | IOSTANDARD = LVCMOS33 ;
NET "E_RXD<0>" LOC = "V8" | IOSTANDARD = LVCMOS33 ;
NET "E_RXD<1>" LOC = "T11" | IOSTANDARD = LVCMOS33 ;
NET "E_RXD<2>" LOC = "U11" | IOSTANDARD = LVCMOS33 ;
NET "E_RXD<3>" LOC = "V14" | IOSTANDARD = LVCMOS33 ;
#NET "E_RXD<4>" LOC = "U14" | IOSTANDARD = LVCMOS33 ;
NET "E_TX_CLK" LOC = "T7" | IOSTANDARD = LVCMOS33 ;
NET "E_TX_EN" LOC = "P15" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "E_TXD<0>" LOC = "R11" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "E_TXD<1>" LOC = "T15" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "E_TXD<2>" LOC = "R5" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "E_TXD<3>" LOC = "T5" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
#NET "E_TXD<4>" LOC = "R6" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
# ==== FPGA Configuration Mode, INIT_B Pins (FPGA) ====
#NET "FPGA_M0" LOC = "M10" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
#NET "FPGA_M1" LOC = "V11" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
#NET "FPGA_M2" LOC = "T10" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
#NET "FPGA_INIT_B" LOC = "T3" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4 ;
#NET "FPGA_RDWR_B" LOC = "U10" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 4 ;
#NET "FPGA_HSWAP" LOC = "B3" | IOSTANDARD = LVCMOS33 ;
# ==== FX2 Connector (FX2) ====
#NET "FX2_CLKIN" LOC = "E10" | IOSTANDARD = LVCMOS33 ;
#NET "FX2_CLKIO" LOC = "D9" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_CLKOUT" LOC = "D10" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
# These four connections are shared with the J1 6-pin accessory header
#NET "FX2_IO<1>" LOC = "B4" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<2>" LOC = "A4" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<3>" LOC = "D5" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<4>" LOC = "C5" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
# These four connections are shared with the J2 6-pin accessory header
#NET "FX2_IO<5>" LOC = "A6" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<6>" LOC = "B6" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<7>" LOC = "E7" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<8>" LOC = "F7" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
# These four connections are shared with the J4 6-pin accessory header
#NET "FX2_IO<9>" LOC = "D7" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<10>" LOC = "C7" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<11>" LOC = "F8" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<12>" LOC = "E8" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
# The discrete LEDs are shared with the following 8 FX2 connections
#NET "FX2_IO<13>" LOC = "F9" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<14>" LOC = "E9" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<15>" LOC = "D11" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<16>" LOC = "C11" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<17>" LOC = "F11" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<18>" LOC = "E11" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<19>" LOC = "E12" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<20>" LOC = "F12" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<21>" LOC = "A13" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<22>" LOC = "B13" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<23>" LOC = "A14" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<24>" LOC = "B14" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<25>" LOC = "C14" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<26>" LOC = "D14" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<27>" LOC = "A16" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<28>" LOC = "B16" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<29>" LOC = "E13" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<30>" LOC = "C4" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<31>" LOC = "B11" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<32>" LOC = "A11" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<33>" LOC = "A8" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<34>" LOC = "G9" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IP<35>" LOC = "D12" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IP<36>" LOC = "C12" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IP<37>" LOC = "A15" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IP<38>" LOC = "B15" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IO<39>" LOC = "C3" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
#NET "FX2_IP<40>" LOC = "C15" | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 8 ;
# ==== 6-pin header J1 ====
# These are shared connections with the FX2 connector
#NET "J1<0>" LOC = "B4" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ;
#NET "J1<1>" LOC = "A4" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ;
#NET "J1<2>" LOC = "D5" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ;
#NET "J1<3>" LOC = "C5" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ;
# ==== 6-pin header J2 ====
# These are shared connections with the FX2 connector
#NET "J2<0>" LOC = "A6" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ;
#NET "J2<1>" LOC = "B6" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ;
#NET "J2<2>" LOC = "E7" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ;
#NET "J2<3>" LOC = "F7" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ;
# ==== 6-pin header J4 ====
# These are shared connections with the FX2 connector
#NET "J4<0>" LOC = "D7" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ;
#NET "J4<1>" LOC = "C7" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ;
#NET "J4<2>" LOC = "F8" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ;
#NET "J4<3>" LOC = "E8" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 6 ;
# ==== Character LCD (LCD) ====
#NET "LCD_E" LOC = "M18" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
#NET "LCD_RS" LOC = "L18" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
#NET "LCD_RW" LOC = "L17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
# LCD data connections are shared with StrataFlash connections SF_D<11:8>
#NET "SF_D<8>" LOC = "R15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
#NET "SF_D<9>" LOC = "R16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
#NET "SF_D<10>" LOC = "P17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
#NET "SF_D<11>" LOC = "M15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
# ==== Discrete LEDs (LED) ====
# These are shared connections with the FX2 connector
NET "LED<0>" LOC = "F12" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "LED<1>" LOC = "E12" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "LED<2>" LOC = "E11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "LED<3>" LOC = "F11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "LED<4>" LOC = "C11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "LED<5>" LOC = "D11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "LED<6>" LOC = "E9" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
NET "LED<7>" LOC = "F9" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ;
# ==== PS/2 Mouse/Keyboard Port (PS2) ====
NET "PS2_CLK" LOC = "G14" | IOSTANDARD = LVCMOS33 ;
NET "PS2_DATA" LOC = "G13" | IOSTANDARD = LVCMOS33 ;
# ==== Rotary Pushbutton Switch (ROT) ====
NET "ROT_A" LOC = "K18" | IOSTANDARD = LVTTL | PULLUP ;
NET "ROT_B" LOC = "G18" | IOSTANDARD = LVTTL | PULLUP ;
NET "ROT_CENTER" LOC = "V16" | IOSTANDARD = LVTTL | PULLDOWN ;
# ==== RS-232 Serial Ports (RS232) ====
NET "RS232_DCE_RXD" LOC = "R7" | IOSTANDARD = LVTTL ;
NET "RS232_DCE_TXD" LOC = "M14" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = SLOW ;
#NET "RS232_DTE_RXD" LOC = "U8" | IOSTANDARD = LVTTL ;
#NET "RS232_DTE_TXD" LOC = "M13" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = SLOW ;
# ==== DDR SDRAM (SD) ==== (I/O Bank 3, VCCO=2.5V)
NET "SD_A<0>" LOC = "T1" | IOSTANDARD = SSTL2_I ;
NET "SD_A<1>" LOC = "R3" | IOSTANDARD = SSTL2_I ;
NET "SD_A<2>" LOC = "R2" | IOSTANDARD = SSTL2_I ;
NET "SD_A<3>" LOC = "P1" | IOSTANDARD = SSTL2_I ;
NET "SD_A<4>" LOC = "F4" | IOSTANDARD = SSTL2_I ;
NET "SD_A<5>" LOC = "H4" | IOSTANDARD = SSTL2_I ;
NET "SD_A<6>" LOC = "H3" | IOSTANDARD = SSTL2_I ;
NET "SD_A<7>" LOC = "H1" | IOSTANDARD = SSTL2_I ;
NET "SD_A<8>" LOC = "H2" | IOSTANDARD = SSTL2_I ;
NET "SD_A<9>" LOC = "N4" | IOSTANDARD = SSTL2_I ;
NET "SD_A<10>" LOC = "T2" | IOSTANDARD = SSTL2_I ;
NET "SD_A<11>" LOC = "N5" | IOSTANDARD = SSTL2_I ;
NET "SD_A<12>" LOC = "P2" | IOSTANDARD = SSTL2_I ;
NET "SD_BA<0>" LOC = "K5" | IOSTANDARD = SSTL2_I ;
NET "SD_BA<1>" LOC = "K6" | IOSTANDARD = SSTL2_I ;
NET "SD_CAS" LOC = "C2" | IOSTANDARD = SSTL2_I ;
NET "SD_CK_N" LOC = "J4" | IOSTANDARD = SSTL2_I ;
NET "SD_CK_P" LOC = "J5" | IOSTANDARD = SSTL2_I ;
NET "SD_CKE" LOC = "K3" | IOSTANDARD = SSTL2_I ;
NET "SD_CS" LOC = "K4" | IOSTANDARD = SSTL2_I ;
NET "SD_DQ<0>" LOC = "L2" | IOSTANDARD = SSTL2_I ;
NET "SD_DQ<1>" LOC = "L1" | IOSTANDARD = SSTL2_I ;
NET "SD_DQ<2>" LOC = "L3" | IOSTANDARD = SSTL2_I ;
NET "SD_DQ<3>" LOC = "L4" | IOSTANDARD = SSTL2_I ;
NET "SD_DQ<4>" LOC = "M3" | IOSTANDARD = SSTL2_I ;
NET "SD_DQ<5>" LOC = "M4" | IOSTANDARD = SSTL2_I ;
NET "SD_DQ<6>" LOC = "M5" | IOSTANDARD = SSTL2_I ;
NET "SD_DQ<7>" LOC = "M6" | IOSTANDARD = SSTL2_I ;
NET "SD_DQ<8>" LOC = "E2" | IOSTANDARD = SSTL2_I ;
NET "SD_DQ<9>" LOC = "E1" | IOSTANDARD = SSTL2_I ;
NET "SD_DQ<10>" LOC = "F1" | IOSTANDARD = SSTL2_I ;
NET "SD_DQ<11>" LOC = "F2" | IOSTANDARD = SSTL2_I ;
NET "SD_DQ<12>" LOC = "G6" | IOSTANDARD = SSTL2_I ;
NET "SD_DQ<13>" LOC = "G5" | IOSTANDARD = SSTL2_I ;
NET "SD_DQ<14>" LOC = "H6" | IOSTANDARD = SSTL2_I ;
NET "SD_DQ<15>" LOC = "H5" | IOSTANDARD = SSTL2_I ;
NET "SD_LDM" LOC = "J2" | IOSTANDARD = SSTL2_I ;
NET "SD_LDQS" LOC = "L6" | IOSTANDARD = SSTL2_I ;
NET "SD_RAS" LOC = "C1" | IOSTANDARD = SSTL2_I ;
NET "SD_UDM" LOC = "J1" | IOSTANDARD = SSTL2_I ;
NET "SD_UDQS" LOC = "G3" | IOSTANDARD = SSTL2_I ;
NET "SD_WE" LOC = "D1" | IOSTANDARD = SSTL2_I ;
# Path to allow connection to top DCM connection
#NET "SD_CK_FB" LOC = "B9" | IOSTANDARD = LVCMOS33 ;
# Prohibit VREF pins
CONFIG PROHIBIT = D2;
CONFIG PROHIBIT = G4;
CONFIG PROHIBIT = J6;
CONFIG PROHIBIT = L5;
CONFIG PROHIBIT = R4;
# ==== Intel StrataFlash Parallel NOR Flash (SF) ====
NET "SF_A<0>" LOC = "H17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<1>" LOC = "J13" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<2>" LOC = "J12" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<3>" LOC = "J14" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<4>" LOC = "J15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<5>" LOC = "J16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<6>" LOC = "J17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<7>" LOC = "K14" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<8>" LOC = "K15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<9>" LOC = "K12" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<10>" LOC = "K13" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<11>" LOC = "L15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<12>" LOC = "L16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<13>" LOC = "T18" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<14>" LOC = "R18" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<15>" LOC = "T17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<16>" LOC = "U18" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<17>" LOC = "T16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<18>" LOC = "U15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<19>" LOC = "V15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<20>" LOC = "T12" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<21>" LOC = "V13" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<22>" LOC = "V12" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<23>" LOC = "N11" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_A<24>" LOC = "A11" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_BYTE" LOC = "C17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_CE0" LOC = "D16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_D<1>" LOC = "P10" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_D<2>" LOC = "R10" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_D<3>" LOC = "V9" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_D<4>" LOC = "U9" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_D<5>" LOC = "R9" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_D<6>" LOC = "M9" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_D<7>" LOC = "N9" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_D<8>" LOC = "R15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_D<9>" LOC = "R16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_D<10>" LOC = "P17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_D<11>" LOC = "M15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_D<12>" LOC = "M16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_D<13>" LOC = "P6" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_D<14>" LOC = "R8" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_D<15>" LOC = "T8" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_OE" LOC = "C18" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "SF_STS" LOC = "B18" | IOSTANDARD = LVCMOS33 ;
NET "SF_WE" LOC = "D17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
# ==== STMicro SPI serial Flash (SPI) ====
# some connections shared with SPI Flash, DAC, ADC, and AMP
NET "SPI_MISO" LOC = "N10" | IOSTANDARD = LVCMOS33 ;
#NET "SPI_MOSI" LOC = "T4" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ;
#NET "SPI_SCK" LOC = "U16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ;
#NET "SPI_SS_B" LOC = "U3" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ;
#NET "SPI_ALT_CS_JP11" LOC = "R12" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ;
# ==== Slide Switches (SW) ====
NET "SW<0>" LOC = "L13" | IOSTANDARD = LVTTL | PULLUP ;
NET "SW<1>" LOC = "L14" | IOSTANDARD = LVTTL | PULLUP ;
NET "SW<2>" LOC = "H18" | IOSTANDARD = LVTTL | PULLUP ;
NET "SW<3>" LOC = "N17" | IOSTANDARD = LVTTL | PULLUP ;
# ==== VGA Port (VGA) ====
NET "VGA_BLUE" LOC = "G15" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ;
NET "VGA_GREEN" LOC = "H15" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ;
NET "VGA_HSYNC" LOC = "F15" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ;
NET "VGA_RED" LOC = "H14" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ;
NET "VGA_VSYNC" LOC = "F14" | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ;
# ==== Xilinx CPLD (XC) ====
#NET "XC_CMD<0>" LOC = "P18" | IOSTANDARD = LVTTL | DRIVE = 4 | SLEW = SLOW ;
#NET "XC_CMD<1>" LOC = "N18" | IOSTANDARD = LVTTL | DRIVE = 4 | SLEW = SLOW ;
#NET "XC_CPLD_EN" LOC = "B10" | IOSTANDARD = LVTTL ;
#NET "XC_D<0>" LOC = "G16" | IOSTANDARD = LVTTL | DRIVE = 4 | SLEW = SLOW ;
#NET "XC_D<1>" LOC = "F18" | IOSTANDARD = LVTTL | DRIVE = 4 | SLEW = SLOW ;
#NET "XC_D<2>" LOC = "F17" | IOSTANDARD = LVTTL | DRIVE = 4 | SLEW = SLOW ;
#NET "XC_TRIG" LOC = "R17" | IOSTANDARD = LVCMOS33 ;
#NET "XC_GCK0" LOC = "H16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
#NET "GCLK10" LOC = "C9" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;
NET "CLK_50MHZ" TNM_NET = "CLK_50MHZ";
NET "clk_reg1" TNM_NET = "clk_reg1";
TIMESPEC "TS_clk_reg1" = PERIOD "clk_reg1" 40 ns HIGH 50 %;

277
plasma/logic/plasma_3e.vhd Normal file
View File

@@ -0,0 +1,277 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
--use work.mlite_pack.all;
entity plasma_3e is
port(CLK_50MHZ : in std_logic;
RS232_DCE_RXD : in std_logic;
RS232_DCE_TXD : out std_logic;
SD_CK_P : out std_logic; --DDR SDRAM clock_positive
SD_CK_N : out std_logic; --clock_negative
SD_CKE : out std_logic; --clock_enable
SD_BA : out std_logic_vector(1 downto 0); --bank_address
SD_A : out std_logic_vector(12 downto 0); --address(row or col)
SD_CS : out std_logic; --chip_select
SD_RAS : out std_logic; --row_address_strobe
SD_CAS : out std_logic; --column_address_strobe
SD_WE : out std_logic; --write_enable
SD_DQ : inout std_logic_vector(15 downto 0); --data
SD_UDM : out std_logic; --upper_byte_enable
SD_UDQS : inout std_logic; --upper_data_strobe
SD_LDM : out std_logic; --low_byte_enable
SD_LDQS : inout std_logic; --low_data_strobe
E_MDC : out std_logic; --Ethernet PHY
E_MDIO : inout std_logic; --management data in/out
E_RX_CLK : in std_logic; --receive clock
E_RX_DV : in std_logic; --data valid
E_RXD : in std_logic_vector(3 downto 0);
E_TX_CLK : in std_logic; --transmit clock
E_TX_EN : out std_logic; --data valid
E_TXD : out std_logic_vector(3 downto 0);
SF_CE0 : out std_logic; --NOR flash
SF_OE : out std_logic;
SF_WE : out std_logic;
SF_BYTE : out std_logic;
SF_STS : in std_logic; --status
SF_A : out std_logic_vector(24 downto 0);
SF_D : inout std_logic_vector(15 downto 1);
SPI_MISO : inout std_logic;
VGA_VSYNC : out std_logic; --VGA port
VGA_HSYNC : out std_logic;
VGA_RED : out std_logic;
VGA_GREEN : out std_logic;
VGA_BLUE : out std_logic;
PS2_CLK : in std_logic; --Keyboard
PS2_DATA : in std_logic;
LED : out std_logic_vector(7 downto 0);
ROT_CENTER : in std_logic;
ROT_A : in std_logic;
ROT_B : in std_logic;
BTN_EAST : in std_logic;
BTN_NORTH : in std_logic;
BTN_SOUTH : in std_logic;
BTN_WEST : in std_logic;
SW : in std_logic_vector(3 downto 0));
end; --entity plasma_if
architecture logic of plasma_3e is
component plasma
generic(memory_type : string := "XILINX_16X"; --"DUAL_PORT_" "ALTERA_LPM";
log_file : string := "UNUSED";
ethernet : std_logic := '0';
use_cache : std_logic := '0');
port(clk : in std_logic;
reset : in std_logic;
uart_write : out std_logic;
uart_read : in std_logic;
address : out std_logic_vector(31 downto 2);
byte_we : out std_logic_vector(3 downto 0);
data_write : out std_logic_vector(31 downto 0);
data_read : in std_logic_vector(31 downto 0);
mem_pause_in : in std_logic;
no_ddr_start : out std_logic;
no_ddr_stop : out std_logic;
gpio0_out : out std_logic_vector(31 downto 0);
gpioA_in : in std_logic_vector(31 downto 0));
end component; --plasma
component ddr_ctrl
port(clk : in std_logic;
clk_2x : in std_logic;
reset_in : in std_logic;
address : in std_logic_vector(25 downto 2);
byte_we : in std_logic_vector(3 downto 0);
data_w : in std_logic_vector(31 downto 0);
data_r : out std_logic_vector(31 downto 0);
active : in std_logic;
no_start : in std_logic;
no_stop : in std_logic;
pause : out std_logic;
SD_CK_P : out std_logic; --clock_positive
SD_CK_N : out std_logic; --clock_negative
SD_CKE : out std_logic; --clock_enable
SD_BA : out std_logic_vector(1 downto 0); --bank_address
SD_A : out std_logic_vector(12 downto 0); --address(row or col)
SD_CS : out std_logic; --chip_select
SD_RAS : out std_logic; --row_address_strobe
SD_CAS : out std_logic; --column_address_strobe
SD_WE : out std_logic; --write_enable
SD_DQ : inout std_logic_vector(15 downto 0); --data
SD_UDM : out std_logic; --upper_byte_enable
SD_UDQS : inout std_logic; --upper_data_strobe
SD_LDM : out std_logic; --low_byte_enable
SD_LDQS : inout std_logic); --low_data_strobe
end component; --ddr
signal clk_reg : std_logic;
signal address : std_logic_vector(31 downto 2);
signal data_write : std_logic_vector(31 downto 0);
signal data_read : std_logic_vector(31 downto 0);
signal data_r_ddr : std_logic_vector(31 downto 0);
signal byte_we : std_logic_vector(3 downto 0);
signal write_enable : std_logic;
signal pause_ddr : std_logic;
signal pause : std_logic;
signal no_ddr_start : std_logic;
signal no_ddr_stop : std_logic;
signal ddr_active : std_logic;
signal flash_active : std_logic;
signal flash_cnt : std_logic_vector(1 downto 0);
signal flash_we : std_logic;
signal reset : std_logic;
signal gpio0_out : std_logic_vector(31 downto 0);
signal gpio0_in : std_logic_vector(31 downto 0);
begin --architecture
--Divide 50 MHz clock by two
clk_div: process(reset, CLK_50MHZ, clk_reg)
begin
if reset = '1' then
clk_reg <= '0';
elsif rising_edge(CLK_50MHZ) then
clk_reg <= not clk_reg;
end if;
end process; --clk_div
reset <= ROT_CENTER;
E_TX_EN <= gpio0_out(28); --Ethernet
E_TXD <= gpio0_out(27 downto 24);
E_MDC <= gpio0_out(23);
E_MDIO <= gpio0_out(21) when gpio0_out(22) = '1' else 'Z';
VGA_VSYNC <= gpio0_out(20);
VGA_HSYNC <= gpio0_out(19);
VGA_RED <= gpio0_out(18);
VGA_GREEN <= gpio0_out(17);
VGA_BLUE <= gpio0_out(16);
LED <= gpio0_out(7 downto 0);
gpio0_in(31 downto 21) <= (others => '0');
gpio0_in(20 downto 13) <= E_RX_CLK & E_RX_DV & E_RXD & E_TX_CLK & E_MDIO;
gpio0_in(12 downto 10) <= SF_STS & PS2_CLK & PS2_DATA;
gpio0_in(9 downto 0) <= ROT_A & ROT_B & BTN_EAST & BTN_NORTH &
BTN_SOUTH & BTN_WEST & SW;
ddr_active <= '1' when address(31 downto 28) = "0001" else '0';
flash_active <= '1' when address(31 downto 28) = "0011" else '0';
write_enable <= '1' when byte_we /= "0000" else '0';
u1_plama: plasma
generic map (memory_type => "XILINX_16X",
log_file => "UNUSED",
ethernet => '1',
use_cache => '1')
--generic map (memory_type => "DUAL_PORT_",
-- log_file => "output2.txt",
-- ethernet => '1')
PORT MAP (
clk => clk_reg,
reset => reset,
uart_write => RS232_DCE_TXD,
uart_read => RS232_DCE_RXD,
address => address,
byte_we => byte_we,
data_write => data_write,
data_read => data_read,
mem_pause_in => pause,
no_ddr_start => no_ddr_start,
no_ddr_stop => no_ddr_stop,
gpio0_out => gpio0_out,
gpioA_in => gpio0_in);
u2_ddr: ddr_ctrl
port map (
clk => clk_reg,
clk_2x => CLK_50MHZ,
reset_in => reset,
address => address(25 downto 2),
byte_we => byte_we,
data_w => data_write,
data_r => data_r_ddr,
active => ddr_active,
no_start => no_ddr_start,
no_stop => no_ddr_stop,
pause => pause_ddr,
SD_CK_P => SD_CK_P, --clock_positive
SD_CK_N => SD_CK_N, --clock_negative
SD_CKE => SD_CKE, --clock_enable
SD_BA => SD_BA, --bank_address
SD_A => SD_A, --address(row or col)
SD_CS => SD_CS, --chip_select
SD_RAS => SD_RAS, --row_address_strobe
SD_CAS => SD_CAS, --column_address_strobe
SD_WE => SD_WE, --write_enable
SD_DQ => SD_DQ, --data
SD_UDM => SD_UDM, --upper_byte_enable
SD_UDQS => SD_UDQS, --upper_data_strobe
SD_LDM => SD_LDM, --low_byte_enable
SD_LDQS => SD_LDQS); --low_data_strobe
--Flash control (only lower 16-bit data lines connected)
flash_ctrl: process(reset, clk_reg, flash_active, write_enable,
flash_cnt, pause_ddr)
begin
if reset = '1' then
flash_cnt <= "00";
flash_we <= '1';
elsif rising_edge(clk_reg) then
if flash_active = '0' then
flash_cnt <= "00";
flash_we <= '1';
else
if write_enable = '1' and flash_cnt(1) = '0' then
flash_we <= '0';
else
flash_we <= '1';
end if;
if flash_cnt /= "11" then
flash_cnt <= flash_cnt + 1;
end if;
end if;
end if; --rising_edge(clk_reg)
if pause_ddr = '1' or (flash_active = '1' and flash_cnt /= "11") then
pause <= '1';
else
pause <= '0';
end if;
end process; --flash_ctrl
SF_CE0 <= not flash_active;
SF_OE <= write_enable or not flash_active;
SF_WE <= flash_we;
SF_BYTE <= '1'; --16-bit access
SF_A <= address(25 downto 2) & '0' when flash_active = '1' else
"0000000000000000000000000";
SF_D <= data_write(15 downto 1) when
flash_active = '1' and write_enable = '1'
else "ZZZZZZZZZZZZZZZ";
SPI_MISO <= data_write(0) when
flash_active = '1' and write_enable = '1'
else 'Z';
data_read(31 downto 16) <= data_r_ddr(31 downto 16);
data_read(15 downto 0) <= data_r_ddr(15 downto 0) when flash_active = '0'
else SF_D & SPI_MISO;
end; --architecture logic

111
plasma/logic/plasma_if.ucf Normal file
View File

@@ -0,0 +1,111 @@
NET "clk_in" TNM_NET = "clk_in";
TIMESPEC "TS_clk_in" = PERIOD "clk_in" 20 ns HIGH 50 %;
#NET "clk_reg1" TNM_NET = "clk_reg1";
#TIMESPEC "TS_clk_reg1" = PERIOD "clk_reg1" 40 ns HIGH 50 %;
NET "clk_reg1" TNM_NET = "clk_reg1";
TIMESPEC "TS_clk_reg1" = PERIOD "clk_reg1" 39.9 ns HIGH 50 %;
#PACE: Start of Constraints generated by PACE
#PACE: Start of PACE I/O Pin Assignments
NET "clk_in" LOC = "T9";
NET "gpio0_out<0>" LOC = "K12";
NET "gpio0_out<10>" LOC = "N15";
NET "gpio0_out<11>" LOC = "P15";
NET "gpio0_out<12>" LOC = "R16";
NET "gpio0_out<13>" LOC = "F13";
NET "gpio0_out<14>" LOC = "N16";
NET "gpio0_out<15>" LOC = "P16";
NET "gpio0_out<16>" LOC = "E13";
NET "gpio0_out<17>" LOC = "F14";
NET "gpio0_out<18>" LOC = "G14";
NET "gpio0_out<19>" LOC = "D14";
NET "gpio0_out<1>" LOC = "P14";
NET "gpio0_out<24>" LOC = "R12";
NET "gpio0_out<25>" LOC = "T12";
NET "gpio0_out<26>" LOC = "R11";
NET "gpio0_out<27>" LOC = "R9";
NET "gpio0_out<28>" LOC = "T10";
NET "gpio0_out<2>" LOC = "L12";
NET "gpio0_out<3>" LOC = "N14";
NET "gpio0_out<4>" LOC = "P13";
NET "gpio0_out<5>" LOC = "N12";
NET "gpio0_out<6>" LOC = "P12";
NET "gpio0_out<7>" LOC = "P11";
NET "gpio0_out<8>" LOC = "E14";
NET "gpio0_out<9>" LOC = "G13";
NET "gpioA_in<0>" LOC = "F12";
NET "gpioA_in<10>" LOC = "L13";
NET "gpioA_in<1>" LOC = "G12";
NET "gpioA_in<2>" LOC = "H14";
NET "gpioA_in<30>" LOC = "M15";
NET "gpioA_in<31>" LOC = "M16";
NET "gpioA_in<3>" LOC = "H13";
NET "gpioA_in<4>" LOC = "J14";
NET "gpioA_in<5>" LOC = "J13";
NET "gpioA_in<6>" LOC = "K14";
NET "gpioA_in<7>" LOC = "K13";
NET "gpioA_in<8>" LOC = "M13";
NET "gpioA_in<9>" LOC = "M14";
NET "ram_address<10>" LOC = "E3";
NET "ram_address<11>" LOC = "E4";
NET "ram_address<12>" LOC = "G5";
NET "ram_address<13>" LOC = "H3";
NET "ram_address<14>" LOC = "H4";
NET "ram_address<15>" LOC = "J4";
NET "ram_address<16>" LOC = "J3";
NET "ram_address<17>" LOC = "K3";
NET "ram_address<18>" LOC = "K5";
NET "ram_address<19>" LOC = "L3";
NET "ram_address<2>" LOC = "L5";
NET "ram_address<3>" LOC = "N3";
NET "ram_address<4>" LOC = "M4";
NET "ram_address<5>" LOC = "M3";
NET "ram_address<6>" LOC = "L4";
NET "ram_address<7>" LOC = "G4";
NET "ram_address<8>" LOC = "F3";
NET "ram_address<9>" LOC = "F4";
NET "ram_ce1_n" LOC = "P7";
NET "ram_ce2_n" LOC = "N5";
NET "ram_data<0>" LOC = "P2";
NET "ram_data<10>" LOC = "G1";
NET "ram_data<11>" LOC = "F5";
NET "ram_data<12>" LOC = "C3";
NET "ram_data<13>" LOC = "K2";
NET "ram_data<14>" LOC = "M1";
NET "ram_data<15>" LOC = "N1";
NET "ram_data<16>" LOC = "N7";
NET "ram_data<17>" LOC = "T8";
NET "ram_data<18>" LOC = "R6";
NET "ram_data<19>" LOC = "T5";
NET "ram_data<1>" LOC = "N2";
NET "ram_data<20>" LOC = "R5";
NET "ram_data<21>" LOC = "C2";
NET "ram_data<22>" LOC = "C1";
NET "ram_data<23>" LOC = "B1";
NET "ram_data<24>" LOC = "D3";
NET "ram_data<25>" LOC = "P8";
NET "ram_data<26>" LOC = "F2";
NET "ram_data<27>" LOC = "H1";
NET "ram_data<28>" LOC = "J2";
NET "ram_data<29>" LOC = "L2";
NET "ram_data<2>" LOC = "M2";
NET "ram_data<30>" LOC = "P1";
NET "ram_data<31>" LOC = "R1";
NET "ram_data<3>" LOC = "K1";
NET "ram_data<4>" LOC = "J1";
NET "ram_data<5>" LOC = "G2";
NET "ram_data<6>" LOC = "E1";
NET "ram_data<7>" LOC = "D1";
NET "ram_data<8>" LOC = "D2";
NET "ram_data<9>" LOC = "E2";
NET "ram_lb1_n" LOC = "P6";
NET "ram_lb2_n" LOC = "P5";
NET "ram_oe_n" LOC = "K4";
NET "ram_ub1_n" LOC = "T4";
NET "ram_ub2_n" LOC = "R4";
NET "ram_we_n" LOC = "G3";
NET "reset" LOC = "L14";
NET "uart_read" LOC = "T13";
NET "uart_write" LOC = "R13";
#PACE: Start of PACE Area Constraints
#PACE: Start of PACE Prohibit Constraints
#PACE: End of Constraints generated by PACE

152
plasma/logic/plasma_if.vhd Normal file
View File

@@ -0,0 +1,152 @@
---------------------------------------------------------------------
-- TITLE: Plamsa Interface (clock divider and interface to FPGA board)
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 6/6/02
-- FILENAME: plasma_if.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- This entity divides the clock by two and interfaces to the
-- Altera EP20K200EFC484-2X FPGA board.
-- Xilinx Spartan-3 XC3S200FT256-4 FPGA.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
--use work.mlite_pack.all;
entity plasma_if is
port(clk_in : in std_logic;
reset : in std_logic;
uart_read : in std_logic;
uart_write : out std_logic;
ram_address : out std_logic_vector(31 downto 2);
ram_data : inout std_logic_vector(31 downto 0);
ram_ce1_n : out std_logic;
ram_ub1_n : out std_logic;
ram_lb1_n : out std_logic;
ram_ce2_n : out std_logic;
ram_ub2_n : out std_logic;
ram_lb2_n : out std_logic;
ram_we_n : out std_logic;
ram_oe_n : out std_logic;
gpio0_out : out std_logic_vector(31 downto 0);
gpioA_in : in std_logic_vector(31 downto 0));
end; --entity plasma_if
architecture logic of plasma_if is
component plasma
generic(memory_type : string := "XILINX_16X"; --"DUAL_PORT_" "ALTERA_LPM";
log_file : string := "UNUSED");
port(clk : in std_logic;
reset : in std_logic;
uart_write : out std_logic;
uart_read : in std_logic;
address : out std_logic_vector(31 downto 2);
byte_we : out std_logic_vector(3 downto 0);
data_write : out std_logic_vector(31 downto 0);
data_read : in std_logic_vector(31 downto 0);
mem_pause_in : in std_logic;
gpio0_out : out std_logic_vector(31 downto 0);
gpioA_in : in std_logic_vector(31 downto 0));
end component; --plasma
signal clk_reg : std_logic;
signal we_n_next : std_logic;
signal we_n_reg : std_logic;
signal mem_address : std_logic_vector(31 downto 2);
signal data_write : std_logic_vector(31 downto 0);
signal data_reg : std_logic_vector(31 downto 0);
signal byte_we : std_logic_vector(3 downto 0);
signal mem_pause_in : std_logic;
begin --architecture
--Divide 50 MHz clock by two
clk_div: process(reset, clk_in, clk_reg, we_n_next)
begin
if reset = '1' then
clk_reg <= '0';
elsif rising_edge(clk_in) then
clk_reg <= not clk_reg;
end if;
if reset = '1' then
we_n_reg <= '1';
data_reg <= (others => '0');
elsif falling_edge(clk_in) then
we_n_reg <= we_n_next or not clk_reg;
data_reg <= ram_data;
end if;
end process; --clk_div
mem_pause_in <= '0';
ram_address <= mem_address(31 downto 2);
ram_we_n <= we_n_reg;
--For Xilinx Spartan-3 Starter Kit
ram_control:
process(clk_reg, mem_address, byte_we, data_write)
begin
if mem_address(30 downto 28) = "001" then --RAM
ram_ce1_n <= '0';
ram_ce2_n <= '0';
if byte_we = "0000" then --read
ram_data <= (others => 'Z');
ram_ub1_n <= '0';
ram_lb1_n <= '0';
ram_ub2_n <= '0';
ram_lb2_n <= '0';
we_n_next <= '1';
ram_oe_n <= '0';
else --write
if clk_reg = '1' then
ram_data <= (others => 'Z');
else
ram_data <= data_write;
end if;
ram_ub1_n <= not byte_we(3);
ram_lb1_n <= not byte_we(2);
ram_ub2_n <= not byte_we(1);
ram_lb2_n <= not byte_we(0);
we_n_next <= '0';
ram_oe_n <= '1';
end if;
else
ram_data <= (others => 'Z');
ram_ce1_n <= '1';
ram_ub1_n <= '1';
ram_lb1_n <= '1';
ram_ce2_n <= '1';
ram_ub2_n <= '1';
ram_lb2_n <= '1';
we_n_next <= '1';
ram_oe_n <= '1';
end if;
end process; --ram_control
u1_plama: plasma
generic map (memory_type => "XILINX_16X",
log_file => "UNUSED")
PORT MAP (
clk => clk_reg,
reset => reset,
uart_write => uart_write,
uart_read => uart_read,
address => mem_address,
byte_we => byte_we,
data_write => data_write,
data_read => data_reg,
mem_pause_in => mem_pause_in,
gpio0_out => gpio0_out,
gpioA_in => gpioA_in);
end; --architecture logic

6
plasma/logic/prog.cmd Normal file
View File

@@ -0,0 +1,6 @@
setmode -bscan
setcable -p auto
identify
assignfile -p 1 -file plasma_3e.bit
program -p 1
quit

176
plasma/logic/ram.vhd Normal file
View File

@@ -0,0 +1,176 @@
---------------------------------------------------------------------
-- TITLE: Random Access Memory
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 4/21/01
-- FILENAME: ram.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Implements the RAM, reads the executable from either "code.txt",
-- or for Altera "code[0-3].hex".
-- Modified from "The Designer's Guide to VHDL" by Peter J. Ashenden
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_misc.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_textio.all;
use std.textio.all;
use work.mlite_pack.all;
entity ram is
generic(memory_type : string := "DEFAULT");
port(clk : in std_logic;
enable : in std_logic;
write_byte_enable : in std_logic_vector(3 downto 0);
address : in std_logic_vector(31 downto 2);
data_write : in std_logic_vector(31 downto 0);
data_read : out std_logic_vector(31 downto 0));
end; --entity ram
architecture logic of ram is
constant ADDRESS_WIDTH : natural := 13;
begin
generic_ram:
if memory_type /= "ALTERA_LPM" generate
begin
--Simulate a synchronous RAM
ram_proc: process(clk, enable, write_byte_enable,
address, data_write) --mem_write, mem_sel
variable mem_size : natural := 2 ** ADDRESS_WIDTH;
variable data : std_logic_vector(31 downto 0);
subtype word is std_logic_vector(data_write'length-1 downto 0);
type storage_array is
array(natural range 0 to mem_size/4 - 1) of word;
variable storage : storage_array;
variable index : natural := 0;
file load_file : text open read_mode is "code.txt";
variable hex_file_line : line;
begin
--Load in the ram executable image
if index = 0 then
while not endfile(load_file) loop
--The following two lines had to be commented out for synthesis
readline(load_file, hex_file_line);
hread(hex_file_line, data);
storage(index) := data;
index := index + 1;
end loop;
end if;
if rising_edge(clk) then
index := conv_integer(address(ADDRESS_WIDTH-1 downto 2));
data := storage(index);
if enable = '1' then
if write_byte_enable(0) = '1' then
data(7 downto 0) := data_write(7 downto 0);
end if;
if write_byte_enable(1) = '1' then
data(15 downto 8) := data_write(15 downto 8);
end if;
if write_byte_enable(2) = '1' then
data(23 downto 16) := data_write(23 downto 16);
end if;
if write_byte_enable(3) = '1' then
data(31 downto 24) := data_write(31 downto 24);
end if;
end if;
if write_byte_enable /= "0000" then
storage(index) := data;
end if;
end if;
data_read <= data;
end process;
end generate; --generic_ram
altera_ram:
if memory_type = "ALTERA_LPM" generate
signal byte_we : std_logic_vector(3 downto 0);
begin
byte_we <= write_byte_enable when enable = '1' else "0000";
lpm_ram_io_component0 : lpm_ram_dq
GENERIC MAP (
intended_device_family => "UNUSED",
lpm_width => 8,
lpm_widthad => ADDRESS_WIDTH-2,
lpm_indata => "REGISTERED",
lpm_address_control => "REGISTERED",
lpm_outdata => "UNREGISTERED",
lpm_file => "code0.hex",
use_eab => "ON",
lpm_type => "LPM_RAM_DQ")
PORT MAP (
data => data_write(31 downto 24),
address => address(ADDRESS_WIDTH-1 downto 2),
inclock => clk,
we => byte_we(3),
q => data_read(31 downto 24));
lpm_ram_io_component1 : lpm_ram_dq
GENERIC MAP (
intended_device_family => "UNUSED",
lpm_width => 8,
lpm_widthad => ADDRESS_WIDTH-2,
lpm_indata => "REGISTERED",
lpm_address_control => "REGISTERED",
lpm_outdata => "UNREGISTERED",
lpm_file => "code1.hex",
use_eab => "ON",
lpm_type => "LPM_RAM_DQ")
PORT MAP (
data => data_write(23 downto 16),
address => address(ADDRESS_WIDTH-1 downto 2),
inclock => clk,
we => byte_we(2),
q => data_read(23 downto 16));
lpm_ram_io_component2 : lpm_ram_dq
GENERIC MAP (
intended_device_family => "UNUSED",
lpm_width => 8,
lpm_widthad => ADDRESS_WIDTH-2,
lpm_indata => "REGISTERED",
lpm_address_control => "REGISTERED",
lpm_outdata => "UNREGISTERED",
lpm_file => "code2.hex",
use_eab => "ON",
lpm_type => "LPM_RAM_DQ")
PORT MAP (
data => data_write(15 downto 8),
address => address(ADDRESS_WIDTH-1 downto 2),
inclock => clk,
we => byte_we(1),
q => data_read(15 downto 8));
lpm_ram_io_component3 : lpm_ram_dq
GENERIC MAP (
intended_device_family => "UNUSED",
lpm_width => 8,
lpm_widthad => ADDRESS_WIDTH-2,
lpm_indata => "REGISTERED",
lpm_address_control => "REGISTERED",
lpm_outdata => "UNREGISTERED",
lpm_file => "code3.hex",
use_eab => "ON",
lpm_type => "LPM_RAM_DQ")
PORT MAP (
data => data_write(7 downto 0),
address => address(ADDRESS_WIDTH-1 downto 2),
inclock => clk,
we => byte_we(0),
q => data_read(7 downto 0));
end generate; --altera_ram
--For XILINX see ram_xilinx.vhd
end; --architecture logic

350
plasma/logic/ram_image.vhd Normal file
View File

@@ -0,0 +1,350 @@
---------------------------------------------------------------------
-- TITLE: Random Access Memory for Xilinx
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 11/06/05
-- FILENAME: ram_xilinx.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Implements the RAM for Spartan 3 Xilinx FPGA
--
-- Compile the MIPS C and assembly code into "test.axf".
-- Run convert.exe to change "test.axf" to "code.txt" which
-- will contain the hex values of the opcodes.
-- Next run "ram_image ram_xilinx.vhd code.txt ram_image.vhd",
-- to create the "ram_image.vhd" file that will have the opcodes
-- correctly placed inside the INIT_00 => strings.
-- Then include ram_image.vhd in the simulation/synthesis.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_misc.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use work.mlite_pack.all;
library UNISIM;
use UNISIM.vcomponents.all;
entity ram is
generic(memory_type : string := "DEFAULT");
port(clk : in std_logic;
enable : in std_logic;
write_byte_enable : in std_logic_vector(3 downto 0);
address : in std_logic_vector(31 downto 2);
data_write : in std_logic_vector(31 downto 0);
data_read : out std_logic_vector(31 downto 0));
end; --entity ram
architecture logic of ram is
begin
RAMB16_S9_inst0 : RAMB16_S9
generic map (
INIT_00 => X"afafafafafafafafafafafafafafafaf2308000c241400ac273c243c243c273c",
INIT_01 => X"8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f8f230c008c8c3caf00af00af2340afaf",
INIT_02 => X"acacacac0003373cac038cac8cac8cac8c243c40034040033423038f038f8f8f",
INIT_03 => X"000300ac0300000034038c8c8c8c8c8c8c8c8c8c8c8c3403acacacacacacacac",
INIT_04 => X"1c24001030008c24ac24ac9424003c00180003241c24a4248c0018ac2400003c",
INIT_05 => X"a00024241028302400a03c24243c3c0003001030008cacac242400003c000300",
INIT_06 => X"100010000c00102a0200260c24af08af2424240000afafafafaf270103001424",
INIT_07 => X"240c001a001427038f8f8f8f8f8f8f02240c240c000824102c24142c24142e24",
INIT_08 => X"3c240c3c240c3c240c3c240c3caf0cafafafafafafafafaf270008260c24240c",
INIT_09 => X"3c3c3c3c3c3c003c3c0c003c240c3c3c1430248c3c1030008c34ac3c3c24240c",
INIT_0A => X"0c3c240c3c270c260c260c260c260c240c3c240c3c240c3c240c3c240c3c240c",
INIT_0B => X"3c3c08240c3c000c000c8e0000008c0024003c3c102c260000142c2400000c24",
INIT_0C => X"3c3c080002a208000c000c00000c240c3c0008923c08ae000c000c00000c240c",
INIT_0D => X"080216a002260c00000010000c240c3c3c080216260c900200000010000c240c",
INIT_0E => X"0010000c240c3c3c08240c000c000c0014002490020000000010000c240c3c3c",
INIT_0F => X"240c3c021402240c000c260c8c021032021002240c000c260c8c02240c3c0000",
INIT_10 => X"14343c000c240c3c3c0800003c0016260c262610000c3c120008a23c243c3c08",
INIT_11 => X"0c000c2608240c3c000c020c240c3c00000c240c3c020c3c083c0c003c000c00",
INIT_12 => X"00100082260c00240800100080afafaf270003ac001030008c343c3c08240c00",
INIT_13 => X"2424142c3002242400afafafaf272703008f8f8f00140082000c2682000c2414",
INIT_14 => X"24243c3c2703008f8c3c10000caf2730038c343c240827038f8f8f8f0216260c",
INIT_15 => X"740a00616d20423a003531303241656c62747267650a24038c0014ac00248c3c",
INIT_16 => X"617965330a7769796532006f61796531006e706e724f303030206e6569612020",
INIT_17 => X"4600753900736838006979656137617965613673647475350a62697965340079",
INIT_18 => X"37336820660a0d786e6e0a786e750a3d6541206820720a3e00616f446f42316f",
INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000")
port map (
DO => data_read(31 downto 24),
DOP => open,
ADDR => address(12 downto 2),
CLK => clk,
DI => data_write(31 downto 24),
DIP => ZERO(0 downto 0),
EN => enable,
SSR => ZERO(0),
WE => write_byte_enable(3));
RAMB16_S9_inst1 : RAMB16_S9
generic map (
INIT_00 => X"b8afaeadacabaaa9a8a7a6a5a4a3a2a1bd000000a560a4a0bd1d8404a5059c1c",
INIT_01 => X"b9b8afaeadacabaaa9a8a7a6a5a4a3a2a1a50086c6c406bb00bb00ba5a1abfb9",
INIT_02 => X"9392919000405a1a06e0a606a606a606a6a50584e0029b401bbd60bb60bbbabf",
INIT_03 => X"00e000c4e0000085a2e09f9d9c9e979695949392919002e09f9d9c9e97969594",
INIT_04 => X"c0c60040420062636284658205620205c000e084c0a582c6a200c0a202a20502",
INIT_05 => X"c2e5070740a285634040036642020300e000404200828283020382040200e000",
INIT_06 => X"54405300000040220312310090b000bf1514130000b1b2b3b4b5bd00e004c3c6",
INIT_07 => X"040000208095bde0b0b1b2b3b4b5bf4004000400000090404282404282400250",
INIT_08 => X"04840004840004840004840004b000b1b2b3b4b5b6b7bebfbd12003100040400",
INIT_09 => X"021e171615144002060000048400041543420382146063004342830204038400",
INIT_0A => X"0002440002c400e400c400a40084004400024400024400024400024400024400",
INIT_0B => X"0202004400024000000044008000444383030402406203000040424240000044",
INIT_0C => X"0202000040500040004000400000440002000044020050400040004000004400",
INIT_0D => X"0000136251100000004040000044000202000011100044420000404000004400",
INIT_0E => X"404000004400020200040040000000a0a683a543420000004040000044000202",
INIT_0F => X"4400020060130400400030004450400200601304004000300044504400020000",
INIT_10 => X"4363030000440002020000400240535200101040000002110000501311120200",
INIT_11 => X"0000000300440002400040004400024000004400020000020006000004000000",
INIT_12 => X"00400002100040110080400082b1bfb0bd00e0a40040420062a3050200040040",
INIT_13 => X"646440624312111080bfb0b1b2bdbde000b0b1bf004000024000100200000451",
INIT_14 => X"63440302bde000bf6203400000bfbd42e06263030400bde0b0b1b2bf12111000",
INIT_15 => X"6957007320666f0a003a39313170726f6f686f73744742e0a200834045848205",
INIT_16 => X"64206d2e006f74206d2e007264206d2e007374752074303078616b206d726266",
INIT_17 => X"2e006d2e0075652e0074206d772e64206d772e73646f6d2e007974206d2e0074",
INIT_18 => X"3834207769430a3e2074433e206556207364006569654120007320526d203270",
INIT_19 => X"0004000080240080000000000000000000000000000000000000000000000000",
INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000")
port map (
DO => data_read(23 downto 16),
DOP => open,
ADDR => address(12 downto 2),
CLK => clk,
DI => data_write(23 downto 16),
DIP => ZERO(0 downto 0),
EN => enable,
SSR => ZERO(0),
WE => write_byte_enable(2));
RAMB16_S9_inst2 : RAMB16_S9
generic map (
INIT_00 => X"00000000000000000000000000000000ff00000100ff18000e000f000c008c00",
INIT_01 => X"000000000000000000000000000000000000022000002000d800d800ff700000",
INIT_02 => X"0000000000000010000000000000000000010060006060000000000000000000",
INIT_03 => X"0000000000201000000000000000000000000000000000000000000000000000",
INIT_04 => X"ffff00ff00000000000000000018301800000000ff0000ff0000000000282830",
INIT_05 => X"001000000000000c4000000d0d0000000000ff00000000000000202030000000",
INIT_06 => X"002000000200000090190002ff00000000000088900000000000ff100021ffff",
INIT_07 => X"0002000080ff00000000000000000010000200020000ff0000ffff00ffff00ff",
INIT_08 => X"000a02000c02000a02000a02000002000000000000000000ff9100ff02000002",
INIT_09 => X"000000000000f810000028100a02000000ff3c00000000000000002030000a02",
INIT_0A => X"02000b02000b020b020b020b020b020b02000b02000b02000b02000b02000a02",
INIT_0B => X"0000010b0200200200000000000000100c100000ff00ff90000000ff8000020c",
INIT_0C => X"00000100f80001200280002000000c0200000100000100200280002000000c02",
INIT_0D => X"0188ff00180002888098ff00000c0200000110ff00020010108088ff00000c02",
INIT_0E => X"980000000c0200000100022002000010ff20000010102028300000000c020000",
INIT_0F => X"0c020088ff180002200200000010ff0088001800022002000000100c02008880",
INIT_10 => X"ff561200000c0200000100f81080ff0002ff00ff000210008002001027100001",
INIT_11 => X"022000ff010b0200200220000c02009000000c02002002000100002810200000",
INIT_12 => X"00000000000220000280000000000000ff00000010ff00000000200001000220",
INIT_13 => X"000000000010ff009000000000ff00001000000000ff000020020000000200ff",
INIT_14 => X"0c0c0000000000000020ff000200ff0000000020000200000000000010ffff02",
INIT_15 => X"6e61006866726f0000343a30207220616f656d20697200000000ff0010000010",
INIT_16 => X"20726f20007265776f20006420726f20003a69204d680a303174656c6179696f",
INIT_17 => X"20007020006d63200065776f20200a726f20200a72207020007465776f200065",
INIT_18 => X"3e353169726f002068206f2068206100736400786e7364000068662020663879",
INIT_19 => X"0020000000202800000804040404040404040408040407070606060606050500",
INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000")
port map (
DO => data_read(15 downto 8),
DOP => open,
ADDR => address(12 downto 2),
CLK => clk,
DI => data_write(15 downto 8),
DIP => ZERO(0 downto 0),
EN => enable,
SSR => ZERO(0),
WE => write_byte_enable(1));
RAMB16_S9_inst3 : RAMB16_S9
generic map (
INIT_00 => X"4c4844403c3834302c2824201c181410980e000704fd2a00f8001000fc00f001",
INIT_01 => X"504c4844403c3834302c2824201c181410008a2410200060125c1058fc005450",
INIT_02 => X"0c08040000083c0048080c440840043c006000000800000801681360115c5854",
INIT_03 => X"00080c000810121900082c2824201c1814100c08040000082c2824201c181410",
INIT_04 => X"f4fe00fc80000004000200004021004011000802fb0400fe00000700ff214000",
INIT_05 => X"00213037020a0fff21080007000000000800fc8000000000d020214000000800",
INIT_06 => X"0c210e009100121021000145c910db28080d0a212114181c2024d0210802f7ff",
INIT_07 => X"0845000821d930081014181c202428210a450d4500d4a9111a9fed1abff10ad0",
INIT_08 => X"00d44f00344f00c84f00a84f00109c14181c2024282c3034c802d8ff45082045",
INIT_09 => X"000000000000090002802100e44f00000cff1c00001001000050000000ffe04f",
INIT_0A => X"4f00fc4f00f04fe04fc84fb44fa04f884f00704f00584f00404f00284f00f84f",
INIT_0B => X"0000406c4f00214f00b100000800002184800000d416cf2100c20ad021009120",
INIT_0C => X"0000400009003f214f21b12100c5444f00007600004000214f21b12100c5444f",
INIT_0D => X"4021fb002101912121218900c5544f00004021fb014500212121219a00c5544f",
INIT_0E => X"211e00c5544f0000400a45214f00b121fb21010021212121217600c5544f0000",
INIT_0F => X"644f0021f42b2045214f04b10021f00f210e2b2045214f04b10021644f002121",
INIT_10 => X"1f783400c5684f00004000090021f30191ff01fb008c000b210a001010000040",
INIT_11 => X"4f21b1cf6a6c4f00214f21b1384f002100c5244f0021450040028f210021a300",
INIT_12 => X"000d00000145210a6021160000141810e000080021fc020000200000400a4521",
INIT_13 => X"5730020a0f06fc1c211c101418e020082110141800f500002145010000450df8",
INIT_14 => X"fcdc0000180800100000fd008c10e80108002000494520081014181c06f8fc45",
INIT_15 => X"6769000a6c6f74000038300032200064742020666e6584080000fb0021040000",
INIT_16 => X"6265724d00642072724d000a7765724d000a6f4f656500303020646967206e72",
INIT_17 => X"43000a44000a6b43000a72726d520065726d52006561204a00652072724d000a",
INIT_18 => X"203632746d6e00006569750065696c002072003e20736400000a6c7444724b20",
INIT_19 => X"00001010200000207060fcfcfcfcfcfcfcfcfc08fcfc6404c07c6c3c30fcd400",
INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000")
port map (
DO => data_read(7 downto 0),
DOP => open,
ADDR => address(12 downto 2),
CLK => clk,
DI => data_write(7 downto 0),
DIP => ZERO(0 downto 0),
EN => enable,
SSR => ZERO(0),
WE => write_byte_enable(0));
end; --architecture logic

350
plasma/logic/ram_xilinx.vhd Normal file
View File

@@ -0,0 +1,350 @@
---------------------------------------------------------------------
-- TITLE: Random Access Memory for Xilinx
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 11/06/05
-- FILENAME: ram_xilinx.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Implements the RAM for Spartan 3 Xilinx FPGA
--
-- Compile the MIPS C and assembly code into "test.axf".
-- Run convert.exe to change "test.axf" to "code.txt" which
-- will contain the hex values of the opcodes.
-- Next run "ram_image ram_xilinx.vhd code.txt ram_image.vhd",
-- to create the "ram_image.vhd" file that will have the opcodes
-- correctly placed inside the INIT_00 => strings.
-- Then include ram_image.vhd in the simulation/synthesis.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_misc.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use work.mlite_pack.all;
library UNISIM;
use UNISIM.vcomponents.all;
entity ram is
generic(memory_type : string := "DEFAULT");
port(clk : in std_logic;
enable : in std_logic;
write_byte_enable : in std_logic_vector(3 downto 0);
address : in std_logic_vector(31 downto 2);
data_write : in std_logic_vector(31 downto 0);
data_read : out std_logic_vector(31 downto 0));
end; --entity ram
architecture logic of ram is
begin
RAMB16_S9_inst0 : RAMB16_S9
generic map (
INIT_00 => X"000000000000000000000000000000000000000000000000000000000c080400",
INIT_01 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000")
port map (
DO => data_read(31 downto 24),
DOP => open,
ADDR => address(12 downto 2),
CLK => clk,
DI => data_write(31 downto 24),
DIP => ZERO(0 downto 0),
EN => enable,
SSR => ZERO(0),
WE => write_byte_enable(3));
RAMB16_S9_inst1 : RAMB16_S9
generic map (
INIT_00 => X"000000000000000000000000000000000000000000000000000000000d090501",
INIT_01 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000")
port map (
DO => data_read(23 downto 16),
DOP => open,
ADDR => address(12 downto 2),
CLK => clk,
DI => data_write(23 downto 16),
DIP => ZERO(0 downto 0),
EN => enable,
SSR => ZERO(0),
WE => write_byte_enable(2));
RAMB16_S9_inst2 : RAMB16_S9
generic map (
INIT_00 => X"000000000000000000000000000000000000000000000000000000000e0a0602",
INIT_01 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000")
port map (
DO => data_read(15 downto 8),
DOP => open,
ADDR => address(12 downto 2),
CLK => clk,
DI => data_write(15 downto 8),
DIP => ZERO(0 downto 0),
EN => enable,
SSR => ZERO(0),
WE => write_byte_enable(1));
RAMB16_S9_inst3 : RAMB16_S9
generic map (
INIT_00 => X"000000000000000000000000000000000000000000000000000000000f0b0703",
INIT_01 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000",
INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000")
port map (
DO => data_read(7 downto 0),
DOP => open,
ADDR => address(12 downto 2),
CLK => clk,
DI => data_write(7 downto 0),
DIP => ZERO(0 downto 0),
EN => enable,
SSR => ZERO(0),
WE => write_byte_enable(0));
end; --architecture logic

323
plasma/logic/reg_bank.vhd Normal file
View File

@@ -0,0 +1,323 @@
---------------------------------------------------------------------
-- TITLE: Register Bank
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 2/2/01
-- FILENAME: reg_bank.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Implements a register bank with 32 registers that are 32-bits wide.
-- There are two read-ports and one write port.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use work.mlite_pack.all;
--library UNISIM; --May need to uncomment for ModelSim
--use UNISIM.vcomponents.all; --May need to uncomment for ModelSim
entity reg_bank is
generic(memory_type : string := "XILINX_16X");
port(clk : in std_logic;
reset_in : in std_logic;
pause : in std_logic;
rs_index : in std_logic_vector(5 downto 0);
rt_index : in std_logic_vector(5 downto 0);
rd_index : in std_logic_vector(5 downto 0);
reg_source_out : out std_logic_vector(31 downto 0);
reg_target_out : out std_logic_vector(31 downto 0);
reg_dest_new : in std_logic_vector(31 downto 0);
intr_enable : out std_logic);
end; --entity reg_bank
--------------------------------------------------------------------
-- The ram_block architecture attempts to use TWO dual-port memories.
-- Different FPGAs and ASICs need different implementations.
-- Choose one of the RAM implementations below.
-- I need feedback on this section!
--------------------------------------------------------------------
architecture ram_block of reg_bank is
signal intr_enable_reg : std_logic;
type ram_type is array(31 downto 0) of std_logic_vector(31 downto 0);
--controls access to dual-port memories
signal addr_read1, addr_read2 : std_logic_vector(4 downto 0);
signal addr_write : std_logic_vector(4 downto 0);
signal data_out1, data_out2 : std_logic_vector(31 downto 0);
signal write_enable : std_logic;
begin
reg_proc: process(clk, rs_index, rt_index, rd_index, reg_dest_new,
intr_enable_reg, data_out1, data_out2, reset_in, pause)
begin
--setup for first dual-port memory
if rs_index = "101110" then --reg_epc CP0 14
addr_read1 <= "00000";
else
addr_read1 <= rs_index(4 downto 0);
end if;
case rs_index is
when "000000" => reg_source_out <= ZERO;
when "101100" => reg_source_out <= ZERO(31 downto 1) & intr_enable_reg;
--interrupt vector address = 0x3c
when "111111" => reg_source_out <= ZERO(31 downto 8) & "00111100";
when others => reg_source_out <= data_out1;
end case;
--setup for second dual-port memory
addr_read2 <= rt_index(4 downto 0);
case rt_index is
when "000000" => reg_target_out <= ZERO;
when others => reg_target_out <= data_out2;
end case;
--setup write port for both dual-port memories
if rd_index /= "000000" and rd_index /= "101100" and pause = '0' then
write_enable <= '1';
else
write_enable <= '0';
end if;
if rd_index = "101110" then --reg_epc CP0 14
addr_write <= "00000";
else
addr_write <= rd_index(4 downto 0);
end if;
if reset_in = '1' then
intr_enable_reg <= '0';
elsif rising_edge(clk) then
if rd_index = "101110" then --reg_epc CP0 14
intr_enable_reg <= '0'; --disable interrupts
elsif rd_index = "101100" then
intr_enable_reg <= reg_dest_new(0);
end if;
end if;
intr_enable <= intr_enable_reg;
end process;
--------------------------------------------------------------
---- Pick only ONE of the dual-port RAM implementations below!
--------------------------------------------------------------
-- Option #1
-- One tri-port RAM, two read-ports, one write-port
-- 32 registers 32-bits wide
tri_port_mem:
if memory_type = "TRI_PORT_X" generate
ram_proc: process(clk, addr_read1, addr_read2,
addr_write, reg_dest_new, write_enable)
variable tri_port_ram : ram_type := (others => ZERO);
begin
data_out1 <= tri_port_ram(conv_integer(addr_read1));
data_out2 <= tri_port_ram(conv_integer(addr_read2));
if rising_edge(clk) then
if write_enable = '1' then
tri_port_ram(conv_integer(addr_write)) := reg_dest_new;
end if;
end if;
end process;
end generate; --tri_port_mem
-- Option #2
-- Two dual-port RAMs, each with one read-port and one write-port
dual_port_mem:
if memory_type = "DUAL_PORT_" generate
ram_proc2: process(clk, addr_read1, addr_read2,
addr_write, reg_dest_new, write_enable)
variable dual_port_ram1 : ram_type := (others => ZERO);
variable dual_port_ram2 : ram_type := (others => ZERO);
begin
data_out1 <= dual_port_ram1(conv_integer(addr_read1));
data_out2 <= dual_port_ram2(conv_integer(addr_read2));
if rising_edge(clk) then
if write_enable = '1' then
dual_port_ram1(conv_integer(addr_write)) := reg_dest_new;
dual_port_ram2(conv_integer(addr_write)) := reg_dest_new;
end if;
end if;
end process;
end generate; --dual_port_mem
-- Option #3
-- RAM16X1D: 16 x 1 positive edge write, asynchronous read dual-port
-- distributed RAM for all Xilinx FPGAs
-- From library UNISIM; use UNISIM.vcomponents.all;
xilinx_16x1d:
if memory_type = "XILINX_16X" generate
signal data_out1A, data_out1B : std_logic_vector(31 downto 0);
signal data_out2A, data_out2B : std_logic_vector(31 downto 0);
signal weA, weB : std_logic;
signal no_connect : std_logic_vector(127 downto 0);
begin
weA <= write_enable and not addr_write(4); --lower 16 registers
weB <= write_enable and addr_write(4); --upper 16 registers
reg_loop: for i in 0 to 31 generate
begin
--Read port 1 lower 16 registers
reg_bit1a : RAM16X1D
port map (
WCLK => clk, -- Port A write clock input
WE => weA, -- Port A write enable input
A0 => addr_write(0), -- Port A address[0] input bit
A1 => addr_write(1), -- Port A address[1] input bit
A2 => addr_write(2), -- Port A address[2] input bit
A3 => addr_write(3), -- Port A address[3] input bit
D => reg_dest_new(i), -- Port A 1-bit data input
DPRA0 => addr_read1(0), -- Port B address[0] input bit
DPRA1 => addr_read1(1), -- Port B address[1] input bit
DPRA2 => addr_read1(2), -- Port B address[2] input bit
DPRA3 => addr_read1(3), -- Port B address[3] input bit
DPO => data_out1A(i), -- Port B 1-bit data output
SPO => no_connect(i) -- Port A 1-bit data output
);
--Read port 1 upper 16 registers
reg_bit1b : RAM16X1D
port map (
WCLK => clk, -- Port A write clock input
WE => weB, -- Port A write enable input
A0 => addr_write(0), -- Port A address[0] input bit
A1 => addr_write(1), -- Port A address[1] input bit
A2 => addr_write(2), -- Port A address[2] input bit
A3 => addr_write(3), -- Port A address[3] input bit
D => reg_dest_new(i), -- Port A 1-bit data input
DPRA0 => addr_read1(0), -- Port B address[0] input bit
DPRA1 => addr_read1(1), -- Port B address[1] input bit
DPRA2 => addr_read1(2), -- Port B address[2] input bit
DPRA3 => addr_read1(3), -- Port B address[3] input bit
DPO => data_out1B(i), -- Port B 1-bit data output
SPO => no_connect(32+i) -- Port A 1-bit data output
);
--Read port 2 lower 16 registers
reg_bit2a : RAM16X1D
port map (
WCLK => clk, -- Port A write clock input
WE => weA, -- Port A write enable input
A0 => addr_write(0), -- Port A address[0] input bit
A1 => addr_write(1), -- Port A address[1] input bit
A2 => addr_write(2), -- Port A address[2] input bit
A3 => addr_write(3), -- Port A address[3] input bit
D => reg_dest_new(i), -- Port A 1-bit data input
DPRA0 => addr_read2(0), -- Port B address[0] input bit
DPRA1 => addr_read2(1), -- Port B address[1] input bit
DPRA2 => addr_read2(2), -- Port B address[2] input bit
DPRA3 => addr_read2(3), -- Port B address[3] input bit
DPO => data_out2A(i), -- Port B 1-bit data output
SPO => no_connect(64+i) -- Port A 1-bit data output
);
--Read port 2 upper 16 registers
reg_bit2b : RAM16X1D
port map (
WCLK => clk, -- Port A write clock input
WE => weB, -- Port A write enable input
A0 => addr_write(0), -- Port A address[0] input bit
A1 => addr_write(1), -- Port A address[1] input bit
A2 => addr_write(2), -- Port A address[2] input bit
A3 => addr_write(3), -- Port A address[3] input bit
D => reg_dest_new(i), -- Port A 1-bit data input
DPRA0 => addr_read2(0), -- Port B address[0] input bit
DPRA1 => addr_read2(1), -- Port B address[1] input bit
DPRA2 => addr_read2(2), -- Port B address[2] input bit
DPRA3 => addr_read2(3), -- Port B address[3] input bit
DPO => data_out2B(i), -- Port B 1-bit data output
SPO => no_connect(96+i) -- Port A 1-bit data output
);
end generate; --reg_loop
data_out1 <= data_out1A when addr_read1(4)='0' else data_out1B;
data_out2 <= data_out2A when addr_read2(4)='0' else data_out2B;
end generate; --xilinx_16x1d
-- Option #4
-- Altera LPM_RAM_DP
altera_mem:
if memory_type = "ALTERA_LPM" generate
signal clk_delayed : std_logic;
signal addr_reg : std_logic_vector(4 downto 0);
signal data_reg : std_logic_vector(31 downto 0);
signal q1 : std_logic_vector(31 downto 0);
signal q2 : std_logic_vector(31 downto 0);
begin
-- Altera dual port RAMs must have the addresses registered (sampled
-- at the rising edge). This is very unfortunate.
-- Therefore, the dual port RAM read clock must delayed so that
-- the read address signal can be sent from the mem_ctrl block.
-- This solution also delays the how fast the registers are read so the
-- maximum clock speed is cut in half (12.5 MHz instead of 25 MHz).
clk_delayed <= not clk; --Could be delayed by 1/4 clock cycle instead
dpram_bypass: process(clk, addr_write, reg_dest_new)
begin
if rising_edge(clk) and write_enable = '1' then
addr_reg <= addr_write;
data_reg <= reg_dest_new;
end if;
end process; --dpram_bypass
-- Bypass dpram if reading what was just written (Altera limitation)
data_out1 <= q1 when addr_read1 /= addr_reg else data_reg;
data_out2 <= q2 when addr_read2 /= addr_reg else data_reg;
lpm_ram_dp_component1 : lpm_ram_dp
generic map (
LPM_WIDTH => 32,
LPM_WIDTHAD => 5,
--LPM_NUMWORDS => 0,
LPM_INDATA => "REGISTERED",
LPM_OUTDATA => "UNREGISTERED",
LPM_RDADDRESS_CONTROL => "REGISTERED",
LPM_WRADDRESS_CONTROL => "REGISTERED",
LPM_FILE => "UNUSED",
LPM_TYPE => "LPM_RAM_DP",
USE_EAB => "ON",
INTENDED_DEVICE_FAMILY => "UNUSED",
RDEN_USED => "FALSE",
LPM_HINT => "UNUSED")
port map (
RDCLOCK => clk_delayed,
RDCLKEN => '1',
RDADDRESS => addr_read1,
RDEN => '1',
DATA => reg_dest_new,
WRADDRESS => addr_write,
WREN => write_enable,
WRCLOCK => clk,
WRCLKEN => '1',
Q => q1);
lpm_ram_dp_component2 : lpm_ram_dp
generic map (
LPM_WIDTH => 32,
LPM_WIDTHAD => 5,
--LPM_NUMWORDS => 0,
LPM_INDATA => "REGISTERED",
LPM_OUTDATA => "UNREGISTERED",
LPM_RDADDRESS_CONTROL => "REGISTERED",
LPM_WRADDRESS_CONTROL => "REGISTERED",
LPM_FILE => "UNUSED",
LPM_TYPE => "LPM_RAM_DP",
USE_EAB => "ON",
INTENDED_DEVICE_FAMILY => "UNUSED",
RDEN_USED => "FALSE",
LPM_HINT => "UNUSED")
port map (
RDCLOCK => clk_delayed,
RDCLKEN => '1',
RDADDRESS => addr_read2,
RDEN => '1',
DATA => reg_dest_new,
WRADDRESS => addr_write,
WREN => write_enable,
WRCLOCK => clk,
WRCLKEN => '1',
Q => q2);
end generate; --altera_mem
end; --architecture ram_block

65
plasma/logic/shifter.vhd Normal file
View File

@@ -0,0 +1,65 @@
---------------------------------------------------------------------
-- TITLE: Shifter Unit
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- Matthias Gruenewald
-- DATE CREATED: 2/2/01
-- FILENAME: shifter.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Implements the 32-bit shifter unit.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.mlite_pack.all;
entity shifter is
generic(shifter_type : string := "DEFAULT");
port(value : in std_logic_vector(31 downto 0);
shift_amount : in std_logic_vector(4 downto 0);
shift_func : in shift_function_type;
c_shift : out std_logic_vector(31 downto 0));
end; --entity shifter
architecture logic of shifter is
-- type shift_function_type is (
-- shift_nothing, shift_left_unsigned,
-- shift_right_signed, shift_right_unsigned);
signal shift1L, shift2L, shift4L, shift8L, shift16L : std_logic_vector(31 downto 0);
signal shift1R, shift2R, shift4R, shift8R, shift16R : std_logic_vector(31 downto 0);
signal fills : std_logic_vector(31 downto 16);
begin
fills <= "1111111111111111" when shift_func = SHIFT_RIGHT_SIGNED
and value(31) = '1'
else "0000000000000000";
shift1L <= value(30 downto 0) & '0' when shift_amount(0) = '1' else value;
shift2L <= shift1L(29 downto 0) & "00" when shift_amount(1) = '1' else shift1L;
shift4L <= shift2L(27 downto 0) & "0000" when shift_amount(2) = '1' else shift2L;
shift8L <= shift4L(23 downto 0) & "00000000" when shift_amount(3) = '1' else shift4L;
shift16L <= shift8L(15 downto 0) & ZERO(15 downto 0) when shift_amount(4) = '1' else shift8L;
shift1R <= fills(31) & value(31 downto 1) when shift_amount(0) = '1' else value;
shift2R <= fills(31 downto 30) & shift1R(31 downto 2) when shift_amount(1) = '1' else shift1R;
shift4R <= fills(31 downto 28) & shift2R(31 downto 4) when shift_amount(2) = '1' else shift2R;
shift8R <= fills(31 downto 24) & shift4R(31 downto 8) when shift_amount(3) = '1' else shift4R;
shift16R <= fills(31 downto 16) & shift8R(31 downto 16) when shift_amount(4) = '1' else shift8R;
GENERIC_SHIFTER: if shifter_type = "DEFAULT" generate
c_shift <= shift16L when shift_func = SHIFT_LEFT_UNSIGNED else
shift16R when shift_func = SHIFT_RIGHT_UNSIGNED or
shift_func = SHIFT_RIGHT_SIGNED else
ZERO;
end generate;
AREA_OPTIMIZED_SHIFTER: if shifter_type /= "DEFAULT" generate
c_shift <= shift16L when shift_func = SHIFT_LEFT_UNSIGNED else (others => 'Z');
c_shift <= shift16R when shift_func = SHIFT_RIGHT_UNSIGNED or
shift_func = SHIFT_RIGHT_SIGNED else (others => 'Z');
c_shift <= ZERO when shift_func = SHIFT_NOTHING else (others => 'Z');
end generate;
end; --architecture logic

View File

@@ -0,0 +1,29 @@
Greetings from the bootloader Apr 21 2010 19:05:48:
Waiting for binary image linked at 0x10000000
Other Menu Options:
1. Memory read word
2. Memory write word
3. Memory read byte
4. Memory write byte
5. Jump to address
6. Raw memory read
7. Raw memory write
8. Checksum
9. Dump
F. Copy 128KB from DDR to flash
>
Waiting for binary image linked at 0x10000000
Other Menu Options:
1. Memory read word
2. Memory write word
3. Memory read byte
4. Memory write byte
5. Jump to address
6. Raw memory read
7. Raw memory write
8. Checksum
9. Dump
F. Copy 128KB from DDR to flash
> 4

View File

@@ -0,0 +1,29 @@
vlib work
vmap work
vcom -93 -work work ../mlite_pack.vhd
vcom -93 -work work ../plasma.vhd
vcom -93 -work work ../alu.vhd
vcom -93 -work work ../control.vhd
vcom -93 -work work ../mem_ctrl.vhd
vcom -93 -work work ../mult.vhd
vcom -93 -work work ../shifter.vhd
vcom -93 -work work ../bus_mux.vhd
vcom -93 -work work ../ddr_ctrl.vhd
vcom -93 -work work ../mlite_cpu.vhd
vcom -93 -work work ../pc_next.vhd
vcom -93 -work work ../cache.vhd
vcom -93 -work work ../eth_dma.vhd
vcom -93 -work work ../pipeline.vhd
vcom -93 -work work ../reg_bank.vhd
vcom -93 -work work ../uart.vhd
vcom -93 -work work ../plasma_3e.vhd
vcom -93 -work work ../ram_image.vhd
vcom -93 -work work ../tbench.vhd
vsim -t 1ps tbench
view wave
add wave *
view structure
view signals
run 15ms

View File

@@ -0,0 +1,283 @@
# // ModelSim SE 6.0d Apr 25 2005 Linux 2.6.32-21-generic
# //
# // Copyright Mentor Graphics Corporation 2005
# // All Rights Reserved.
# //
# // THIS WORK CONTAINS TRADE SECRET AND
# // PROPRIETARY INFORMATION WHICH IS THE PROPERTY
# // OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS
# // AND IS SUBJECT TO LICENSE TERMS.
# //
# do plasma_3e_TB.do
# Reading /home/opt/cad/modeltech/linux/../modelsim.ini
# "work" maps to directory work. (Default mapping)
# Model Technology ModelSim SE vcom 6.0d Compiler 2005.04 Apr 25 2005
# -- Loading package standard
# -- Loading package std_logic_1164
# -- Compiling package mlite_pack
# -- Compiling package body mlite_pack
# -- Loading package mlite_pack
# Model Technology ModelSim SE vcom 6.0d Compiler 2005.04 Apr 25 2005
# -- Loading package standard
# -- Loading package std_logic_1164
# -- Loading package mlite_pack
# -- Compiling entity plasma
# -- Compiling architecture logic of plasma
# Model Technology ModelSim SE vcom 6.0d Compiler 2005.04 Apr 25 2005
# -- Loading package standard
# -- Loading package std_logic_1164
# -- Loading package mlite_pack
# -- Compiling entity alu
# -- Compiling architecture logic of alu
# Model Technology ModelSim SE vcom 6.0d Compiler 2005.04 Apr 25 2005
# -- Loading package standard
# -- Loading package std_logic_1164
# -- Loading package mlite_pack
# -- Compiling entity control
# -- Compiling architecture logic of control
# Model Technology ModelSim SE vcom 6.0d Compiler 2005.04 Apr 25 2005
# -- Loading package standard
# -- Loading package std_logic_1164
# -- Loading package mlite_pack
# -- Compiling entity mem_ctrl
# -- Compiling architecture logic of mem_ctrl
# Model Technology ModelSim SE vcom 6.0d Compiler 2005.04 Apr 25 2005
# -- Loading package standard
# -- Loading package std_logic_1164
# -- Loading package std_logic_arith
# -- Loading package std_logic_unsigned
# -- Loading package mlite_pack
# -- Compiling entity mult
# -- Compiling architecture logic of mult
# Model Technology ModelSim SE vcom 6.0d Compiler 2005.04 Apr 25 2005
# -- Loading package standard
# -- Loading package std_logic_1164
# -- Loading package mlite_pack
# -- Compiling entity shifter
# -- Compiling architecture logic of shifter
# Model Technology ModelSim SE vcom 6.0d Compiler 2005.04 Apr 25 2005
# -- Loading package standard
# -- Loading package std_logic_1164
# -- Loading package mlite_pack
# -- Compiling entity bus_mux
# -- Compiling architecture logic of bus_mux
# Model Technology ModelSim SE vcom 6.0d Compiler 2005.04 Apr 25 2005
# -- Loading package standard
# -- Loading package std_logic_1164
# -- Loading package std_logic_arith
# -- Loading package std_logic_unsigned
# -- Loading package mlite_pack
# -- Compiling entity ddr_ctrl
# -- Compiling architecture logic of ddr_ctrl
# Model Technology ModelSim SE vcom 6.0d Compiler 2005.04 Apr 25 2005
# -- Loading package standard
# -- Loading package std_logic_1164
# -- Loading package mlite_pack
# -- Loading package std_logic_arith
# -- Loading package std_logic_unsigned
# -- Compiling entity mlite_cpu
# -- Compiling architecture logic of mlite_cpu
# Model Technology ModelSim SE vcom 6.0d Compiler 2005.04 Apr 25 2005
# -- Loading package standard
# -- Loading package std_logic_1164
# -- Loading package mlite_pack
# -- Compiling entity pc_next
# -- Compiling architecture logic of pc_next
# Model Technology ModelSim SE vcom 6.0d Compiler 2005.04 Apr 25 2005
# -- Loading package standard
# -- Loading package std_logic_1164
# -- Loading package std_logic_arith
# -- Loading package std_logic_unsigned
# -- Loading package vcomponents
# -- Loading package mlite_pack
# -- Compiling entity cache
# -- Compiling architecture logic of cache
# Model Technology ModelSim SE vcom 6.0d Compiler 2005.04 Apr 25 2005
# -- Loading package standard
# -- Loading package std_logic_1164
# -- Loading package std_logic_arith
# -- Loading package std_logic_unsigned
# -- Loading package mlite_pack
# -- Compiling entity eth_dma
# -- Compiling architecture logic of eth_dma
# Model Technology ModelSim SE vcom 6.0d Compiler 2005.04 Apr 25 2005
# -- Loading package standard
# -- Loading package std_logic_1164
# -- Loading package mlite_pack
# -- Compiling entity pipeline
# -- Compiling architecture logic of pipeline
# Model Technology ModelSim SE vcom 6.0d Compiler 2005.04 Apr 25 2005
# -- Loading package standard
# -- Loading package std_logic_1164
# -- Loading package std_logic_arith
# -- Loading package std_logic_unsigned
# -- Loading package mlite_pack
# -- Compiling entity reg_bank
# -- Compiling architecture ram_block of reg_bank
# Model Technology ModelSim SE vcom 6.0d Compiler 2005.04 Apr 25 2005
# -- Loading package standard
# -- Loading package std_logic_1164
# -- Loading package attributes
# -- Loading package std_logic_misc
# -- Loading package std_logic_arith
# -- Loading package textio
# -- Loading package std_logic_textio
# -- Loading package std_logic_unsigned
# -- Loading package mlite_pack
# -- Compiling entity uart
# -- Compiling architecture logic of uart
# Model Technology ModelSim SE vcom 6.0d Compiler 2005.04 Apr 25 2005
# -- Loading package standard
# -- Loading package std_logic_1164
# -- Loading package std_logic_arith
# -- Loading package std_logic_unsigned
# -- Compiling entity plasma_3e
# -- Compiling architecture logic of plasma_3e
# Model Technology ModelSim SE vcom 6.0d Compiler 2005.04 Apr 25 2005
# -- Loading package standard
# -- Loading package std_logic_1164
# -- Loading package attributes
# -- Loading package std_logic_misc
# -- Loading package std_logic_arith
# -- Loading package std_logic_unsigned
# -- Loading package mlite_pack
# -- Loading package vcomponents
# -- Compiling entity ram
# -- Compiling architecture logic of ram
# Model Technology ModelSim SE vcom 6.0d Compiler 2005.04 Apr 25 2005
# -- Loading package standard
# -- Loading package std_logic_1164
# -- Loading package mlite_pack
# -- Loading package std_logic_arith
# -- Loading package std_logic_unsigned
# -- Compiling entity tbench
# -- Compiling architecture logic of tbench
# vsim -t 1ps tbench
# Loading /home/opt/cad/modeltech/linux/../std.standard
# Loading /home/opt/cad/modeltech/linux/../ieee.std_logic_1164(body)
# Loading work.mlite_pack(body)
# Loading /home/opt/cad/modeltech/linux/../ieee.std_logic_arith(body)
# Loading /home/opt/cad/modeltech/linux/../ieee.std_logic_unsigned(body)
# Loading work.tbench(logic)
# Loading work.plasma(logic)
# Loading work.mlite_cpu(logic)
# Loading work.pc_next(logic)
# Loading work.mem_ctrl(logic)
# Loading work.control(logic)
# Loading work.reg_bank(ram_block)
# Loading work.bus_mux(logic)
# Loading work.alu(logic)
# Loading work.shifter(logic)
# Loading work.mult(logic)
# Loading /opt/cad/modeltech/xilinx/vhdl/unisim.vcomponents
# Loading work.cache(logic)
# Loading /home/opt/cad/modeltech/linux/../synopsys.attributes
# Loading /home/opt/cad/modeltech/linux/../ieee.std_logic_misc(body)
# Loading work.ram(logic)
# Loading /home/opt/cad/modeltech/linux/../std.textio(body)
# Loading /home/opt/cad/modeltech/linux/../ieee.vital_timing(body)
# Loading /home/opt/cad/modeltech/linux/../ieee.vital_primitives(body)
# Loading /opt/cad/modeltech/xilinx/vhdl/unisim.vpkg(body)
# Loading /opt/cad/modeltech/xilinx/vhdl/unisim.ramb16_s9(ramb16_s9_v)
# Loading /home/opt/cad/modeltech/linux/../ieee.std_logic_textio(body)
# Loading work.uart(logic)
# Loading work.eth_dma(logic)
# .main_pane.mdi.interior.cs.vm.paneset.cli_0.wf.clip.cs
# .main_pane.workspace
# .main_pane.signals.interior.cs
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench
# ** Warning: CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, and it has been converted to 0.
# Time: 0 ps Iteration: 0 Instance: /tbench
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/dma_gen2/u4_eth
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/dma_gen2/u4_eth
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/u3_uart
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/opt_cache2/u_cache
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/opt_cache2/u_cache
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/opt_cache2/u_cache
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/u1_cpu/u8_mult
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/u1_cpu/u8_mult
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/u1_cpu/u8_mult
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/u1_cpu/u8_mult
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/u1_cpu/u8_mult
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/u1_cpu/u8_mult
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank/tri_port_mem
# ** Warning: CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, and it has been converted to 0.
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank/tri_port_mem
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank/tri_port_mem
# ** Warning: CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, and it has been converted to 0.
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank/tri_port_mem
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 0 Instance: /tbench/u1_plasma/u1_cpu
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 1 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank/tri_port_mem
# ** Warning: CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, and it has been converted to 0.
# Time: 0 ps Iteration: 1 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank/tri_port_mem
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 1 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank/tri_port_mem
# ** Warning: CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, and it has been converted to 0.
# Time: 0 ps Iteration: 1 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank/tri_port_mem
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 1 Instance: /tbench/u1_plasma/opt_cache2/u_cache
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 1 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 1 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 1 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 1 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 1 Instance: /tbench
# ** Warning: CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, and it has been converted to 0.
# Time: 0 ps Iteration: 1 Instance: /tbench
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 2 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 2 Instance: /tbench
# ** Warning: CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, and it has been converted to 0.
# Time: 0 ps Iteration: 2 Instance: /tbench
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 2 Instance: /tbench/u1_plasma/opt_cache2/u_cache
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 3 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank/tri_port_mem
# ** Warning: CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, and it has been converted to 0.
# Time: 0 ps Iteration: 3 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank/tri_port_mem
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 3 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank/tri_port_mem
# ** Warning: CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, and it has been converted to 0.
# Time: 0 ps Iteration: 3 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank/tri_port_mem
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 3 Instance: /tbench/u1_plasma/opt_cache2/u_cache
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 4 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank/tri_port_mem
# ** Warning: CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, and it has been converted to 0.
# Time: 0 ps Iteration: 4 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank/tri_port_mem
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 ps Iteration: 4 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank/tri_port_mem
# ** Warning: CONV_INTEGER: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, and it has been converted to 0.
# Time: 0 ps Iteration: 4 Instance: /tbench/u1_plasma/u1_cpu/u4_reg_bank/tri_port_mem
# Break key hit
# Simulation stop requested.

119
plasma/logic/tbench.vhd Normal file
View File

@@ -0,0 +1,119 @@
---------------------------------------------------------------------
-- TITLE: Test Bench
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 4/21/01
-- FILENAME: tbench.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- This entity provides a test bench for testing the Plasma CPU core.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.mlite_pack.all;
use ieee.std_logic_unsigned.all;
entity tbench is
end; --entity tbench
architecture logic of tbench is
constant memory_type : string :=
"TRI_PORT_X";
-- "DUAL_PORT_";
-- "ALTERA_LPM";
-- "XILINX_16X";
constant log_file : string :=
-- "UNUSED";
"output.txt";
signal clk : std_logic := '1';
signal reset : std_logic := '1';
signal interrupt : std_logic := '0';
signal mem_write : std_logic;
signal address : std_logic_vector(31 downto 2);
signal data_write : std_logic_vector(31 downto 0);
signal data_read : std_logic_vector(31 downto 0);
signal pause1 : std_logic := '0';
signal pause2 : std_logic := '0';
signal pause : std_logic;
signal no_ddr_start: std_logic;
signal no_ddr_stop : std_logic;
signal byte_we : std_logic_vector(3 downto 0);
signal uart_write : std_logic;
signal gpioA_in : std_logic_vector(31 downto 0) := (others => '0');
begin --architecture
--Uncomment the line below to test interrupts
interrupt <= '1' after 20 us when interrupt = '0' else '0' after 445 ns;
clk <= not clk after 50 ns;
reset <= '0' after 500 ns;
pause1 <= '1' after 700 ns when pause1 = '0' else '0' after 200 ns;
pause2 <= '1' after 300 ns when pause2 = '0' else '0' after 200 ns;
pause <= pause1 or pause2;
gpioA_in(20) <= not gpioA_in(20) after 200 ns; --E_RX_CLK
gpioA_in(19) <= not gpioA_in(19) after 20 us; --E_RX_DV
gpioA_in(18 downto 15) <= gpioA_in(18 downto 15) + 1 after 400 ns; --E_RX_RXD
gpioA_in(14) <= not gpioA_in(14) after 200 ns; --E_TX_CLK
u1_plasma: plasma
generic map (memory_type => memory_type,
ethernet => '1',
use_cache => '1',
log_file => log_file)
PORT MAP (
clk => clk,
reset => reset,
uart_read => uart_write,
uart_write => uart_write,
address => address,
byte_we => byte_we,
data_write => data_write,
data_read => data_read,
mem_pause_in => pause,
no_ddr_start => no_ddr_start,
no_ddr_stop => no_ddr_stop,
gpio0_out => open,
gpioA_in => gpioA_in);
dram_proc: process(clk, address, byte_we, data_write, pause)
constant ADDRESS_WIDTH : natural := 16;
type storage_array is
array(natural range 0 to (2 ** ADDRESS_WIDTH) / 4 - 1) of
std_logic_vector(31 downto 0);
variable storage : storage_array;
variable data : std_logic_vector(31 downto 0);
variable index : natural := 0;
begin
index := conv_integer(address(ADDRESS_WIDTH-1 downto 2));
data := storage(index);
if byte_we(0) = '1' then
data(7 downto 0) := data_write(7 downto 0);
end if;
if byte_we(1) = '1' then
data(15 downto 8) := data_write(15 downto 8);
end if;
if byte_we(2) = '1' then
data(23 downto 16) := data_write(23 downto 16);
end if;
if byte_we(3) = '1' then
data(31 downto 24) := data_write(31 downto 24);
end if;
if rising_edge(clk) then
if address(30 downto 28) = "001" and byte_we /= "0000" then
storage(index) := data;
end if;
end if;
if pause = '0' then
data_read <= data;
end if;
end process;
end; --architecture logic

181
plasma/logic/uart.vhd Normal file
View File

@@ -0,0 +1,181 @@
---------------------------------------------------------------------
-- TITLE: UART
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 5/29/02
-- FILENAME: uart.vhd
-- PROJECT: Plasma CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Implements the UART.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_misc.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_textio.all;
use ieee.std_logic_unsigned.all;
use std.textio.all;
use work.mlite_pack.all;
entity uart is
generic(log_file : string := "UNUSED");
port(clk : in std_logic;
reset : in std_logic;
enable_read : in std_logic;
enable_write : in std_logic;
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0);
uart_read : in std_logic;
uart_write : out std_logic;
busy_write : out std_logic;
data_avail : out std_logic);
end; --entity uart
architecture logic of uart is
signal delay_write_reg : std_logic_vector(9 downto 0);
signal bits_write_reg : std_logic_vector(3 downto 0);
signal data_write_reg : std_logic_vector(8 downto 0);
signal delay_read_reg : std_logic_vector(9 downto 0);
signal bits_read_reg : std_logic_vector(3 downto 0);
signal data_read_reg : std_logic_vector(7 downto 0);
signal data_save_reg : std_logic_vector(17 downto 0);
signal busy_write_sig : std_logic;
signal read_value_reg : std_logic_vector(6 downto 0);
signal uart_read2 : std_logic;
begin
uart_proc: process(clk, reset, enable_read, enable_write, data_in,
data_write_reg, bits_write_reg, delay_write_reg,
data_read_reg, bits_read_reg, delay_read_reg,
data_save_reg, read_value_reg, uart_read2,
busy_write_sig, uart_read)
constant COUNT_VALUE : std_logic_vector(9 downto 0) :=
-- "0100011110"; --33MHz/2/57600Hz = 0x11e
-- "1101100100"; --50MHz/57600Hz = 0x364
"0110110010"; --25MHz/57600Hz = 0x1b2 -- Plasma IF uses div2
-- "0011011001"; --12.5MHz/57600Hz = 0xd9
-- "0000000100"; --for debug (shorten read_value_reg)
begin
uart_read2 <= read_value_reg(read_value_reg'length - 1);
if reset = '1' then
data_write_reg <= ZERO(8 downto 1) & '1';
bits_write_reg <= "0000";
delay_write_reg <= ZERO(9 downto 0);
read_value_reg <= ONES(read_value_reg'length-1 downto 0);
data_read_reg <= ZERO(7 downto 0);
bits_read_reg <= "0000";
delay_read_reg <= ZERO(9 downto 0);
data_save_reg <= ZERO(17 downto 0);
elsif rising_edge(clk) then
--Write UART
if bits_write_reg = "0000" then --nothing left to write?
if enable_write = '1' then
delay_write_reg <= ZERO(9 downto 0); --delay before next bit
bits_write_reg <= "1010"; --number of bits to write
data_write_reg <= data_in & '0'; --remember data & start bit
end if;
else
if delay_write_reg /= COUNT_VALUE then
delay_write_reg <= delay_write_reg + 1; --delay before next bit
else
delay_write_reg <= ZERO(9 downto 0); --reset delay
bits_write_reg <= bits_write_reg - 1; --bits left to write
data_write_reg <= '1' & data_write_reg(8 downto 1);
end if;
end if;
--Average uart_read signal
if uart_read = '1' then
if read_value_reg /= ONES(read_value_reg'length - 1 downto 0) then
read_value_reg <= read_value_reg + 1;
end if;
else
if read_value_reg /= ZERO(read_value_reg'length - 1 downto 0) then
read_value_reg <= read_value_reg - 1;
end if;
end if;
--Read UART
if delay_read_reg = ZERO(9 downto 0) then --done delay for read?
if bits_read_reg = "0000" then --nothing left to read?
if uart_read2 = '0' then --wait for start bit
delay_read_reg <= '0' & COUNT_VALUE(9 downto 1); --half period
bits_read_reg <= "1001"; --bits left to read
end if;
else
delay_read_reg <= COUNT_VALUE; --initialize delay
bits_read_reg <= bits_read_reg - 1; --bits left to read
data_read_reg <= uart_read2 & data_read_reg(7 downto 1);
end if;
else
delay_read_reg <= delay_read_reg - 1; --delay
end if;
--Control character buffer
if bits_read_reg = "0000" and delay_read_reg = COUNT_VALUE then
if data_save_reg(8) = '0' or
(enable_read = '1' and data_save_reg(17) = '0') then
--Empty buffer
data_save_reg(8 downto 0) <= '1' & data_read_reg;
else
--Second character in buffer
data_save_reg(17 downto 9) <= '1' & data_read_reg;
if enable_read = '1' then
data_save_reg(8 downto 0) <= data_save_reg(17 downto 9);
end if;
end if;
elsif enable_read = '1' then
data_save_reg(17) <= '0'; --data_available
data_save_reg(8 downto 0) <= data_save_reg(17 downto 9);
end if;
end if; --rising_edge(clk)
uart_write <= data_write_reg(0);
if bits_write_reg /= "0000"
-- Comment out the following line for full UART simulation (much slower)
and log_file = "UNUSED"
then
busy_write_sig <= '1';
else
busy_write_sig <= '0';
end if;
busy_write <= busy_write_sig;
data_avail <= data_save_reg(8);
data_out <= data_save_reg(7 downto 0);
end process; --uart_proc
-- synthesis_off
uart_logger:
if log_file /= "UNUSED" generate
uart_proc: process(clk, enable_write, data_in)
file store_file : text open write_mode is log_file;
variable hex_file_line : line;
variable c : character;
variable index : natural;
variable line_length : natural := 0;
begin
if rising_edge(clk) and busy_write_sig = '0' then
if enable_write = '1' then
index := conv_integer(data_in(6 downto 0));
if index /= 10 then
c := character'val(index);
write(hex_file_line, c);
line_length := line_length + 1;
end if;
if index = 10 or line_length >= 72 then
--The following line may have to be commented out for synthesis
writeline(store_file, hex_file_line);
line_length := 0;
end if;
end if; --uart_sel
end if; --rising_edge(clk)
end process; --uart_proc
end generate; --uart_logger
-- synthesis_on
end; --architecture logic