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:
78
plasma/logic/Makefile
Normal file
78
plasma/logic/Makefile
Normal 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
15
plasma/logic/_impact.cmd
Normal 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
61
plasma/logic/alu.vhd
Normal 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
136
plasma/logic/bus_mux.vhd
Normal 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
175
plasma/logic/cache.vhd
Normal 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
658
plasma/logic/code.txt
Normal 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
481
plasma/logic/control.vhd
Normal 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
354
plasma/logic/ddr_ctrl.vhd
Normal 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
BIN
plasma/logic/default.ipf
Normal file
Binary file not shown.
BIN
plasma/logic/default.ipf_ISE_Backup
Normal file
BIN
plasma/logic/default.ipf_ISE_Backup
Normal file
Binary file not shown.
183
plasma/logic/eth_dma.vhd
Normal file
183
plasma/logic/eth_dma.vhd
Normal 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
196
plasma/logic/mem_ctrl.vhd
Normal 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
342
plasma/logic/mlite_cpu.vhd
Normal 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
542
plasma/logic/mlite_pack.vhd
Normal 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
208
plasma/logic/mult.vhd
Normal 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
71
plasma/logic/pc_next.vhd
Normal 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
139
plasma/logic/pipeline.vhd
Normal 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
301
plasma/logic/plasma.vhd
Normal 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
279
plasma/logic/plasma_3e.ucf
Normal 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
277
plasma/logic/plasma_3e.vhd
Normal 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
111
plasma/logic/plasma_if.ucf
Normal 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
152
plasma/logic/plasma_if.vhd
Normal 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
6
plasma/logic/prog.cmd
Normal 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
176
plasma/logic/ram.vhd
Normal 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
350
plasma/logic/ram_image.vhd
Normal 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
350
plasma/logic/ram_xilinx.vhd
Normal 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
323
plasma/logic/reg_bank.vhd
Normal 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
65
plasma/logic/shifter.vhd
Normal 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
|
||||
|
||||
29
plasma/logic/simulation/output.txt
Normal file
29
plasma/logic/simulation/output.txt
Normal 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
|
||||
29
plasma/logic/simulation/plasma_3e_TB.do
Normal file
29
plasma/logic/simulation/plasma_3e_TB.do
Normal 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
|
||||
283
plasma/logic/simulation/transcript
Normal file
283
plasma/logic/simulation/transcript
Normal 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
119
plasma/logic/tbench.vhd
Normal 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
181
plasma/logic/uart.vhd
Normal 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
|
||||
Reference in New Issue
Block a user