OpenCores
URL https://opencores.org/ocsvn/plasma/plasma/trunk

Subversion Repositories plasma

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /plasma/tags/V3_0/vhdl
    from Rev 350 to Rev 352
    Reverse comparison

Rev 350 → Rev 352

/pc_next.vhd
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
/mem_ctrl.vhd
0,0 → 1,182
---------------------------------------------------------------------
-- 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;
mem_address : out std_logic_vector(31 downto 2);
mem_data_w : out std_logic_vector(31 downto 0);
mem_data_r : in std_logic_vector(31 downto 0);
mem_byte_we : out std_logic_vector(3 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 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,
mem_data_r, opcode_reg, next_opcode_reg, mem_state_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_sel_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_sel_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 := mem_data_r;
 
when MEM_READ16 | MEM_READ16S =>
if address_in(1) = ENDIAN_MODE(1) then
data_read_var(15 downto 0) := mem_data_r(31 downto 16);
else
data_read_var(15 downto 0) := mem_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) := mem_data_r(31 downto 24);
when "01" => data_read_var(7 downto 0) := mem_data_r(23 downto 16);
when "10" => data_read_var(7 downto 0) := mem_data_r(15 downto 8);
when others => data_read_var(7 downto 0) := mem_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_sel_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_sel_var := "1100";
else
byte_sel_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_sel_var := "1000";
when "01" =>
byte_sel_var := "0100";
when "10" =>
byte_sel_var := "0010";
when others =>
byte_sel_var := "0001";
end case;
 
when others =>
end case;
 
if mem_source = MEM_FETCH then --opcode fetch
address_var := address_pc;
opcode_next := mem_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_sel_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_sel_var := "0000";
else
address_var := address_in(31 downto 2);
byte_sel_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;
elsif rising_edge(clk) then
if pause_in = '0' then
mem_state_reg <= mem_state_next;
opcode_reg <= opcode_next;
if mem_state_reg = STATE_ADDR then
next_opcode_reg <= mem_data_r;
end if;
end if;
end if;
 
mem_address <= address_var;
opcode_out <= opcode_reg;
data_read <= data_read_var;
pause_out <= pause_var;
mem_data_w <= data_write_var;
mem_byte_we <= byte_sel_var;
 
end process; --data_proc
 
end; --architecture logic
/tbench.vhd
0,0 → 1,69
---------------------------------------------------------------------
-- 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;
 
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 mem_address : std_logic_vector(31 downto 2);
signal mem_data : std_logic_vector(31 downto 0);
signal mem_pause : std_logic := '0';
signal mem_byte_sel: std_logic_vector(3 downto 0);
--signal uart_read : std_logic;
signal uart_write : std_logic;
signal data_read : std_logic_vector(31 downto 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;
--mem_pause <= not mem_pause after 100 ns;
--uart_read <= '0';
data_read <= interrupt & ZERO(30 downto 0);
 
u1_plasma: plasma
generic map (memory_type => memory_type,
log_file => log_file)
PORT MAP (
clk => clk,
reset => reset,
uart_read => uart_write,
uart_write => uart_write,
address => mem_address,
data_write => mem_data,
data_read => data_read,
write_byte_enable => mem_byte_sel,
mem_pause_in => mem_pause,
gpio0_out => open,
gpioA_in => data_read);
 
end; --architecture logic
/shifter.vhd
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
 
/pipeline.vhd
0,0 → 1,129
---------------------------------------------------------------------
-- 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;
 
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
/code.txt
0,0 → 1,657
3c1c0000
379c8a30
3c040000
34840a40
3c050000
34a50a44
3c1d0000
37bd0c40
ac800000
0085182a
1460fffd
24840004
0c0001d4
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
3c052000
8ca40020
8ca60010
0c000209
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
24a5015c
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
24420a40
a0400008
24050007
00403825
3083000f
2862000a
10400003
00a73021
10000002
24620030
24620037
a0c20000
24a5ffff
04a1fff6
00042102
3c020000
03e00008
24420a40
3c020000
24420a50
a040000a
00803025
24050009
00404025
3c07cccc
34e7cccd
00c70019
00a82021
24a5ffff
00004810
000918c2
00031080
00431021
00021040
00c21023
24420030
a0820000
04a1fff4
00603025
3c020000
03e00008
24420a50
27bdffe0
afbf0018
afb10014
afb00010
0c00008f
00808825
0c0001ee
00402025
3c040000
0c0001ee
2484097c
3c023b9a
3442c9ff
0051102b
1040001e
3c030004
34634b83
00111242
00430019
3c030000
246309c8
00002810
000581c2
00101080
00431021
8c440000
0c0001ee
00000000
3c040000
0c0001ee
24840980
00101140
00501023
00021080
00501023
00021100
00501021
000210c0
00501023
00021940
00621823
00031880
00701821
00031a40
02238823
3c0205f5
3442e0ff
0051102b
10400023
3c0255e6
34423b89
02220019
3c030000
246309c8
00002810
00058642
00101080
00431021
8c440000
0c0001ee
00000000
3c040000
0c0001ee
2484098c
00101040
00501021
00021180
00501023
00021080
00501023
00021100
00501023
00021140
00501021
00021200
02228823
3c02000f
3442423f
0051102b
14400005
3c020131
3c040000
0c0001ee
24840998
3c020131
34422cff
0051102b
10400021
3c026b5f
3442ca6b
02220019
3c030000
246309c8
00002810
00058582
26020014
00021080
00431021
8c440000
0c0001ee
00000000
0c0001dd
24040020
00101940
00701823
00031180
00431023
000210c0
00501021
00021880
00431021
000211c0
02228823
3c02000f
3442423f
0051102b
14400009
3c02431b
3c040000
0c0001ee
24840998
3c02000f
3442423f
0051102b
10400017
3c02431b
3442de83
02220019
3c030000
246309c8
00002810
00058482
00101080
00431021
8c440000
0c0001ee
00000000
3c040000
0c0001ee
248409a4
00101940
00701823
00031180
00431023
000210c0
00501021
00021180
02228823
3c020001
3442869f
0051102b
10400020
3c030a7c
34635ac5
00111142
00430019
3c030000
246309c8
00002810
000581c2
00101080
00431021
8c440000
0c0001ee
00000000
3c040000
0c0001ee
2484098c
00101040
00501021
00021980
00431021
00021080
00501021
00021080
00501021
00021140
02228823
2e2203e8
10400005
2e224e20
3c040000
0c0001ee
248409b0
2e224e20
1440001f
2e2203e8
3c02d1b7
34421759
02220019
3c030000
246309c8
00002810
00058342
26020014
00021080
00431021
8c440000
0c0001ee
00000000
0c0001dd
24040020
00101080
00501021
000210c0
00501023
00021100
00501021
00021100
02228823
2e2203e8
10400008
3c021062
3c040000
0c0001ee
248409b0
2e2203e8
14400017
2e220064
3c021062
34424dd3
02220019
3c030000
246309c8
00002810
00058182
00101080
00431021
8c440000
0c0001ee
00000000
3c040000
0c0001ee
248409bc
00101140
00501023
00021080
00501021
000210c0
02228823
2e220064
14400017
2e220014
3c0251eb
3442851f
02220019
3c030000
246309c8
00002810
00058142
00101080
00431021
8c440000
0c0001ee
00000000
3c040000
0c0001ee
2484098c
00101040
00501021
000210c0
00501021
00021080
02228823
2e220014
14400014
3c030000
3c02cccc
3442cccd
02220019
246309c8
00002810
000580c2
26020014
00021080
00431021
8c440000
0c0001ee
00000000
0c0001dd
24040020
00101080
00501021
00021040
02228823
3c030000
246309c8
00111080
00431021
8c440000
0c0001ee
00000000
0c0001dd
2404000d
0c0001dd
2404000a
8fbf0018
8fb10014
8fb00010
03e00008
27bd0020
27bdffe8
afbf0014
afb00010
24100003
0c0000a7
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
0c0001dd
2404000d
92040000
0c0001dd
26100001
92020000
00000000
1440fff5
00000000
8fbf0018
8fb10014
8fb00010
00001025
03e00008
27bd0020
27bdffe8
afbf0010
0c0001dd
24040049
8fbf0010
00000000
03e00008
27bd0018
3c022000
34420020
8c420000
03e00008
30420001
27bdffe8
afbf0010
0c000211
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
00000978
00000974
00000970
00000968
00000960
00000958
00000954
0000094c
00000944
0000093c
00000938
00000930
00000928
0000091c
00000910
00000908
00000900
000008f4
000008e8
000008dc
00000978
00000938
000008d4
000008cc
000008c4
000008bc
000008b4
000008ac
000008a4
0000089c
00000000
/mlite_pack.vhd
0,0 → 1,487
---------------------------------------------------------------------
-- 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_add_sub
GENERIC (
lpm_width : NATURAL;
lpm_direction : STRING := "UNUSED";
lpm_type : STRING;
lpm_hint : STRING);
PORT (
dataa : IN STD_LOGIC_VECTOR (lpm_width-1 DOWNTO 0);
add_sub : IN STD_LOGIC ;
datab : IN STD_LOGIC_VECTOR (lpm_width-1 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR (lpm_width-1 DOWNTO 0));
END COMPONENT;
 
-- For Altera
COMPONENT lpm_ram_dp
GENERIC (
lpm_width : NATURAL;
lpm_widthad : NATURAL;
rden_used : STRING;
intended_device_family : STRING;
lpm_indata : STRING;
lpm_wraddress_control : STRING;
lpm_rdaddress_control : STRING;
lpm_outdata : STRING;
use_eab : STRING;
lpm_type : STRING);
PORT (
wren : IN STD_LOGIC ;
wrclock : IN STD_LOGIC ;
q : OUT STD_LOGIC_VECTOR (lpm_width-1 DOWNTO 0);
data : IN STD_LOGIC_VECTOR (lpm_width-1 DOWNTO 0);
rdaddress : IN STD_LOGIC_VECTOR (lpm_widthad-1 DOWNTO 0);
wraddress : IN STD_LOGIC_VECTOR (lpm_widthad-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 ramb4_s16_s16
port (
clka : in std_logic;
rsta : in std_logic;
addra : in std_logic_vector;
dia : in std_logic_vector;
ena : in std_logic;
wea : in std_logic;
doa : out std_logic_vector;
 
clkb : in std_logic;
rstb : in std_logic;
addrb : in std_logic_vector;
dib : in std_logic_vector;
enb : in std_logic;
web : in std_logic);
end component;
 
-- For Xilinx
component reg_file_dp_ram
port (
addra : IN std_logic_VECTOR(4 downto 0);
addrb : IN std_logic_VECTOR(4 downto 0);
clka : IN std_logic;
clkb : IN std_logic;
dinb : IN std_logic_VECTOR(31 downto 0);
douta : OUT std_logic_VECTOR(31 downto 0);
web : IN std_logic);
end component;
 
-- For Xilinx
component reg_file_dp_ram_xc4000xla
port (
A : IN std_logic_vector(4 DOWNTO 0);
DI : IN std_logic_vector(31 DOWNTO 0);
WR_EN : IN std_logic;
WR_CLK : IN std_logic;
DPRA : IN std_logic_vector(4 DOWNTO 0);
SPO : OUT std_logic_vector(31 DOWNTO 0);
DPO : OUT std_logic_vector(31 DOWNTO 0));
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;
mem_address : out std_logic_vector(31 downto 2);
mem_data_w : out std_logic_vector(31 downto 0);
mem_data_r : in std_logic_vector(31 downto 0);
mem_byte_we : out std_logic_vector(3 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);
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 := 3); --3 or 4
port(clk : in std_logic;
reset_in : in std_logic;
intr_in : in std_logic;
 
mem_address : out std_logic_vector(31 downto 0);
mem_data_w : out std_logic_vector(31 downto 0);
mem_data_r : in std_logic_vector(31 downto 0);
mem_byte_we : out std_logic_vector(3 downto 0);
mem_pause : in std_logic);
end component;
 
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 plasma
generic(memory_type : string := "XILINX_X16"; --"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);
data_write : out std_logic_vector(31 downto 0);
data_read : in std_logic_vector(31 downto 0);
write_byte_enable : out std_logic_vector(3 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
 
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
 
 
/reg_bank.vhd
0,0 → 1,450
---------------------------------------------------------------------
-- 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;
--Uncomment following two lines for Xilinx RAM16X1D
library UNISIM; --Xilinx
use UNISIM.vcomponents.all; --Xilinx
 
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;
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;
variable dual_port_ram2 : ram_type;
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
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;
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 => open -- 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 => open -- 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 => open -- 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 => open -- 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
-- Xilinx users may need to comment out this section!!!
altera_mem:
if memory_type = "ALTERA_LPM" generate
lpm_ram_dp_component1 : lpm_ram_dp
GENERIC MAP (
lpm_width => 32,
lpm_widthad => 5,
rden_used => "FALSE",
intended_device_family => "UNUSED",
lpm_indata => "REGISTERED",
lpm_wraddress_control => "REGISTERED",
lpm_rdaddress_control => "UNREGISTERED",
lpm_outdata => "UNREGISTERED",
use_eab => "ON",
lpm_type => "LPM_RAM_DP"
)
PORT MAP (
wren => write_enable,
wrclock => clk,
data => reg_dest_new,
rdaddress => addr_read1,
wraddress => addr_write,
q => data_out1
);
lpm_ram_dp_component2 : lpm_ram_dp
GENERIC MAP (
lpm_width => 32,
lpm_widthad => 5,
rden_used => "FALSE",
intended_device_family => "UNUSED",
lpm_indata => "REGISTERED",
lpm_wraddress_control => "REGISTERED",
lpm_rdaddress_control => "UNREGISTERED",
lpm_outdata => "UNREGISTERED",
use_eab => "ON",
lpm_type => "LPM_RAM_DP"
)
PORT MAP (
wren => write_enable,
wrclock => clk,
data => reg_dest_new,
rdaddress => addr_read2,
wraddress => addr_write,
q => data_out2
);
end generate; --altera_mem
 
 
-- Option #5
-- dual_port_mem_coregen:
-- if memory_type = "DUAL_PORT_XILINX" generate
-- reg_file_dp_ram_1: reg_file_dp_ram
-- port map (
-- addra => addr_read1,
-- addrb => addr_write,
-- clka => clk,
-- clkb => clk,
-- dinb => reg_dest_new,
-- douta => data_out1,
-- web => write_enable);
--
-- reg_file_dp_ram_2: reg_file_dp_ram
-- port map (
-- addra => addr_read2,
-- addrb => addr_write,
-- clka => clk,
-- clkb => clk,
-- dinb => reg_dest_new,
-- douta => data_out2,
-- web => write_enable);
-- end generate; --dual_port_mem
 
 
-- dual_port_mem_xc4000xla: if memory_type = "DUAL_PORT_XILINX_XC4000XLA" generate
-- reg_file_dp_ram_1: reg_file_dp_ram_xc4000xla
-- port map (
-- A => addr_write,
-- DI => reg_dest_new,
-- WR_EN => write_enable,
-- WR_CLK => clk,
-- DPRA => addr_read1,
-- SPO => open,
-- DPO => data_out1);
--
-- reg_file_dp_ram_2: reg_file_dp_ram_xc4000xla
-- port map (
-- A => addr_write,
-- DI => reg_dest_new,
-- WR_EN => write_enable,
-- WR_CLK => clk,
-- DPRA => addr_read2,
-- SPO => open,
-- DPO => data_out2);
-- end generate; --dual_port_mem
 
 
-- Option #6
-- Generic Two-Port Synchronous RAM
-- generic_tpram can be obtained from:
-- http://www.opencores.org/cvsweb.shtml/generic_memories/
-- Supports ASICs (Artisan, Avant, and Virage) and Xilinx FPGA
-- generic_mem:
-- if memory_type = "OPENCORES_MEM" generate
-- bank1 : generic_tpram port map (
-- clk_a => clk,
-- rst_a => '0',
-- ce_a => '1',
-- we_a => '0',
-- oe_a => '1',
-- addr_a => addr_read1,
-- di_a => ZERO,
-- do_a => data_out1,
--
-- clk_b => clk,
-- rst_b => '0',
-- ce_b => '1',
-- we_b => write_enable,
-- oe_b => '0',
-- addr_b => addr_write,
-- di_a => reg_dest_new);
--
-- bank2 : generic_tpram port map (
-- clk_a => clk,
-- rst_a => '0',
-- ce_a => '1',
-- we_a => '0',
-- oe_a => '1',
-- addr_a => addr_read2,
-- di_a => ZERO,
-- do_a => data_out2,
--
-- clk_b => clk,
-- rst_b => '0',
-- ce_b => '1',
-- we_b => write_enable,
-- oe_b => '0',
-- addr_b => addr_write,
-- di_a => reg_dest_new);
-- end generate; --generic_mem
 
 
-- Option #7
-- Xilinx mode using four 16x16 banks
-- xilinx_mem:
-- if memory_type = "XILINX" generate
-- bank1_high: ramb4_s16_s16 port map (
-- clka => clk,
-- rsta => sig_false,
-- addra => addr_read1,
-- dia => zero_sig,
-- ena => sig_true,
-- wea => sig_false,
-- doa => data_out1(31 downto 16),
--
-- clkb => clk,
-- rstb => sig_false,
-- addrb => addr_write,
-- dib => reg_dest_new(31 downto 16),
-- enb => sig_true,
-- web => write_enable);
--
-- bank1_low: ramb4_s16_s16 port map (
-- clka => clk,
-- rsta => sig_false,
-- addra => addr_read1,
-- dia => zero_sig,
-- ena => sig_true,
-- wea => sig_false,
-- doa => data_out1(15 downto 0),
--
-- clkb => clk,
-- rstb => sig_false,
-- addrb => addr_write,
-- dib => reg_dest_new(15 downto 0),
-- enb => sig_true,
-- web => write_enable);
--
-- bank2_high: ramb4_s16_s16 port map (
-- clka => clk,
-- rsta => sig_false,
-- addra => addr_read2,
-- dia => zero_sig,
-- ena => sig_true,
-- wea => sig_false,
-- doa => data_out2(31 downto 16),
--
-- clkb => clk,
-- rstb => sig_false,
-- addrb => addr_write,
-- dib => reg_dest_new(31 downto 16),
-- enb => sig_true,
-- web => write_enable);
--
-- bank2_low: ramb4_s16_s16 port map (
-- clka => clk,
-- rsta => sig_false,
-- addra => addr_read2,
-- dia => zero_sig,
-- ena => sig_true,
-- wea => sig_false,
-- doa => data_out2(15 downto 0),
--
-- clkb => clk,
-- rstb => sig_false,
-- addrb => addr_write,
-- dib => reg_dest_new(15 downto 0),
-- enb => sig_true,
-- web => write_enable);
-- end generate; --xilinx_mem
 
end; --architecture ram_block
/ram_xilinx.vhd
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 "text.exe".
-- Run convert.exe to change "text.exe" to "code.txt" which
-- will contain the hex values of the opcodes.
-- Next run "run_image ram_xilinx.vhd code.txt ram_image.vhd",
-- to create the "ram_image.vhd" file that will have the opcodes
-- corectly 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
/uart.vhd
0,0 → 1,162
---------------------------------------------------------------------
-- 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(8 downto 0);
signal busy_write_sig : std_logic;
signal read_value_reg : std_logic_vector(7 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)
constant COUNT_VALUE : std_logic_vector(9 downto 0) :=
-- "0100011110"; --33MHz/2/57600Hz = 0x11e
-- "1101100100"; --50MHz/57600Hz = 0x364
"0110110010"; --25MHz/57600Hz = 0x1b2
-- "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(7 downto 0);
data_read_reg <= ZERO(7 downto 0);
bits_read_reg <= "0000";
delay_read_reg <= ZERO(9 downto 0);
data_save_reg <= ZERO(8 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;
 
if bits_read_reg = "0000" and delay_read_reg = COUNT_VALUE then
data_save_reg <= '1' & data_read_reg;
elsif enable_read = '1' then
data_save_reg(8) <= '0'; --data_available
end if;
end if; --rising_edge(clk)
 
uart_write <= data_write_reg(0);
if bits_write_reg /= "0000" 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
 
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 had 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
 
end; --architecture logic
/plasma.vhd
0,0 → 1,196
---------------------------------------------------------------------
-- 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 (16KB)
-- 0x10000000 - 0x000fffff 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
-- 0x20000050 GPIOA In
-- 0x20000060 Counter
-- IRQ bits:
-- 7 GPIO31
-- 6 GPIO30
-- 5 ^GPIO31
-- 4 ^GPIO30
-- 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_X16"; --"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);
data_write : out std_logic_vector(31 downto 0);
data_read : in std_logic_vector(31 downto 0);
write_byte_enable : out std_logic_vector(3 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; --entity plasma
 
architecture logic of plasma is
signal address_reg : std_logic_vector(31 downto 2);
signal data_write_reg : std_logic_vector(31 downto 0);
signal write_byte_enable_reg : std_logic_vector(3 downto 0);
 
signal mem_address : std_logic_vector(31 downto 0);
signal mem_data_read : std_logic_vector(31 downto 0);
signal mem_data_write : std_logic_vector(31 downto 0);
signal mem_write_byte_enable : std_logic_vector(3 downto 0);
signal data_read_ram : std_logic_vector(31 downto 0);
signal data_read_uart : std_logic_vector(7 downto 0);
signal write_enable : std_logic;
signal mem_pause : std_logic;
 
signal enable_internal_ram : 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 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 counter_reg : std_logic_vector(31 downto 0);
 
begin --architecture
write_byte_enable <= write_byte_enable_reg;
data_write <= data_write_reg;
address <= address_reg;
 
write_enable <= '1' when write_byte_enable_reg /= "0000" else '0';
mem_pause <= mem_pause_in or (uart_write_busy and enable_uart and write_enable);
irq_status <= gpioA_in(31 downto 30) & (gpioA_in(31 downto 30) xor "11") &
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 <= gpio0_reg;
 
enable_internal_ram <= '1' when mem_address(30 downto 28) = "000" else '0';
enable_misc <= '1' when address_reg(30 downto 28) = "010" else '0';
enable_uart <= '1' when enable_misc = '1' and address_reg(7 downto 4) = "0000" else '0';
enable_uart_read <= enable_uart and not write_enable;
enable_uart_write <= enable_uart and write_enable;
 
u1_cpu: mlite_cpu
generic map (memory_type => memory_type)
PORT MAP (
clk => clk,
reset_in => reset,
intr_in => irq,
mem_address => mem_address,
mem_data_w => mem_data_write,
mem_data_r => mem_data_read,
mem_byte_we => mem_write_byte_enable,
mem_pause => mem_pause);
 
misc_proc: process(clk, reset, mem_address, address_reg, enable_misc,
data_read_ram, data_read, data_read_uart, mem_pause,
irq_mask_reg, irq_status, gpio0_reg, write_enable,
gpioA_in, counter_reg, mem_data_write, data_write_reg)
begin
case address_reg(30 downto 28) is
when "000" => --internal RAM
mem_data_read <= data_read_ram;
when "001" => --external RAM
mem_data_read <= data_read;
when "010" => --misc
case address_reg(6 downto 4) is
when "000" => --uart
mem_data_read <= ZERO(31 downto 8) & data_read_uart;
when "001" => --irq_mask
mem_data_read <= ZERO(31 downto 8) & irq_mask_reg;
when "010" => --irq_status
mem_data_read <= ZERO(31 downto 8) & irq_status;
when "011" => --gpio0
mem_data_read <= gpio0_reg;
when "101" => --gpioA
mem_data_read <= gpioA_in;
when "110" => --counter
mem_data_read <= counter_reg;
when others =>
mem_data_read <= gpioA_in;
end case;
when others =>
mem_data_read <= ZERO;
end case;
 
if reset = '1' then
address_reg <= ZERO(31 downto 2);
data_write_reg <= ZERO;
write_byte_enable_reg <= ZERO(3 downto 0);
irq_mask_reg <= ZERO(7 downto 0);
gpio0_reg <= ZERO;
counter_reg <= ZERO;
elsif rising_edge(clk) then
if mem_pause = '0' then
address_reg <= mem_address(31 downto 2);
data_write_reg <= mem_data_write;
write_byte_enable_reg <= mem_write_byte_enable;
if enable_misc = '1' and write_enable = '1' then
if address_reg(6 downto 4) = "001" then
irq_mask_reg <= data_write_reg(7 downto 0);
elsif address_reg(6 downto 4) = "011" then
gpio0_reg <= data_write_reg;
end if;
end if;
end if;
counter_reg <= bv_inc(counter_reg);
end if;
end process;
 
u2_ram: ram
generic map (memory_type => memory_type)
port map (
clk => clk,
enable => enable_internal_ram,
write_byte_enable => mem_write_byte_enable,
address => mem_address(31 downto 2),
data_write => mem_data_write,
data_read => data_read_ram);
 
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 => data_write_reg(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);
 
end; --architecture logic
/ram.vhd
0,0 → 1,175
---------------------------------------------------------------------
-- 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;
--Uncomment following two lines for Xilinx RAM16X1D
library UNISIM; --Xilinx
use UNISIM.vcomponents.all; --Xilinx
 
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
--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
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 => write_byte_enable(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 => write_byte_enable(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 => write_byte_enable(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 => write_byte_enable(0),
q => data_read(7 downto 0));
 
end generate; --altera_ram
 
 
--For XILINX see ram_xilinx.vhd
 
end; --architecture logic
/control.vhd
0,0 → 1,510
---------------------------------------------------------------------
-- 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+5+2+3+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);
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;
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);
 
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*/
-- c_source := C_FROM_REG_SOURCE_EQZ;
 
when "001011" => --MOVN if(r[rt]) r[rd]=r[rs]; /*IV*/
-- c_source := FROM_REG_SOURCE_NEZ;
 
when "001100" => --SYSCALL
-- if(r[4]==0) printf("0x%8.8lx ",r[5]);
 
when "001101" => --BREAK s->wakeup=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;
c_source := C_FROM_PC_PLUS4;
pc_source := FROM_LBRANCH;
branch_function := BRANCH_LTZ;
 
when "00010" => --BLTZL lbranch=r[rs]<0;
pc_source := FROM_LBRANCH;
branch_function := BRANCH_LTZ;
 
when "10011" => --BGEZALL r[31]=s->pc_next; lbranch=r[rs]>=0;
c_source := C_FROM_PC_PLUS4;
pc_source := FROM_LBRANCH;
branch_function := BRANCH_GEZ;
 
when "00011" => --BGEZL lbranch=r[rs]>=0;
pc_source := FROM_LBRANCH;
branch_function := BRANCH_GEZ;
 
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_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];
a_source := A_FROM_PC;
b_source := B_FROM_IMMX4;
alu_function := ALU_ADD;
pc_source := FROM_LBRANCH;
branch_function := BRANCH_EQ;
 
when "010101" => --BNEL lbranch=r[rs]!=r[rt];
a_source := A_FROM_PC;
b_source := B_FROM_IMMX4;
alu_function := ALU_ADD;
pc_source := FROM_LBRANCH;
branch_function := BRANCH_NE;
 
when "010110" => --BLEZL lbranch=r[rs]<=0;
a_source := A_FROM_PC;
b_source := B_FROM_IMMX4;
alu_function := ALU_ADD;
pc_source := FROM_LBRANCH;
branch_function := BRANCH_LEZ;
 
when "010111" => --BGTZL lbranch=r[rs]>0;
a_source := A_FROM_PC;
b_source := B_FROM_IMMX4;
alu_function := ALU_ADD;
pc_source := FROM_LBRANCH;
branch_function := BRANCH_GTZ;
 
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' 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;
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
/mlite_cpu.vhd
0,0 → 1,336
---------------------------------------------------------------------
-- 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 three or four stage pipeline.
-- An add instruction would take the following steps (see cpu.gif):
-- Stage #1:
-- 1. The "pc_next" entity passes the program counter (PC) to the
-- "mem_ctrl" entity which fetches the opcode from memory.
-- Stage #2:
-- 2. The memory returns the opcode.
-- Stage #3:
-- 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 #4 (part of stage #3 if using three 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 #4b:
-- 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 three 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 mem_byte_we Stages
-- ns mem_address mem_data_w mem_data_r 40 44 48 4c 50
-- 3500 0 0 00000040 00000000 00000000 0 0 1
-- 3600 0 0 00000044 00000000 34040041 0 0 2 1
-- 3700 0 0 00000048 00000000 3405FFFF 0 0 3 2 1
-- 3800 0 0 0000004C 00000000 A0A40000 0 0 3 2 1
-- 3900 0 0 0000FFFC 41414141 00000000 1 0 3 2
-- 4000 0 0 00000050 41414141 XXXXXX41 0 0 4b 3 1
-- 4100 0 0 00000054 00000000 00000000 0 0 2
---------------------------------------------------------------------
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 := 3); --3 or 4
port(clk : in std_logic;
reset_in : in std_logic;
intr_in : in std_logic;
 
mem_address : out std_logic_vector(31 downto 0);
mem_data_w : out std_logic_vector(31 downto 0);
mem_data_r : in std_logic_vector(31 downto 0);
mem_byte_we : out std_logic_vector(3 downto 0);
mem_pause : in std_logic);
end; --entity mlite_cpu
 
architecture logic of mlite_cpu is
--When using a three stage pipeline "sigD <= sig".
--When using a four 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 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'
else '0';
c_bus <= c_alu or c_shift or c_mult;
reset <= '1' when reset_in = '1' or reset_reg /= "1111" else '0';
mem_address(1 downto 0) <= "00";
 
--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,
mem_address => mem_address(31 downto 2),
mem_data_w => mem_data_w,
mem_data_r => mem_data_r,
mem_byte_we => mem_byte_we);
 
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);
 
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);
 
pipeline3: if pipeline_stages <= 3 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
 
pipeline4: if pipeline_stages > 3 generate
--When operating in four 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; --pipeline4
 
end; --architecture logic
/mult.vhd
0,0 → 1,204
---------------------------------------------------------------------
-- 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.
--
-- 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
/alu.vhd
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
 
/bus_mux.vhd
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
/plasma_if.vhd
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_X16"; --"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);
data_write : out std_logic_vector(31 downto 0);
data_read : in std_logic_vector(31 downto 0);
write_byte_enable : out std_logic_vector(3 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 write_byte_enable : 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, write_byte_enable, data_write)
begin
if mem_address(30 downto 28) = "001" then --RAM
ram_ce1_n <= '0';
ram_ce2_n <= '0';
if write_byte_enable = "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 write_byte_enable(3);
ram_lb1_n <= not write_byte_enable(2);
ram_ub2_n <= not write_byte_enable(1);
ram_lb2_n <= not write_byte_enable(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,
data_write => data_write,
data_read => data_reg,
write_byte_enable => write_byte_enable,
mem_pause_in => mem_pause_in,
gpio0_out => gpio0_out,
gpioA_in => gpioA_in);
end; --architecture logic
 
/makefile
0,0 → 1,119
#Makefile for Plasma
 
#for ModelSim
#WORK_DIR = work
#DEP_FILE = _primary.dat
#COMPILE = vcom -check_synthesis
 
#for FREE VHDL simulator http://www.symphonyeda.com
#WARNING: vhdle now deletes the output.txt if terminated by a ^C
WORK_DIR = work.sym
DEP_FILE = prim.dep
COMPILE = vhdlp -s
 
all: $(WORK_DIR)/tbench/$(DEP_FILE)
 
run: all
-@del output.txt
vhdle -t 30us tbench
type output.txt|more
 
run2: all
-@del output.txt
vhdle -t 50us tbench
type output.txt|more
 
run3: all
-@del output.txt
vhdle -t 100us tbench
type output.txt|more
 
opcodes: all
make -C ..\tools opcodes
vhdle -t 200us tbench
@type output.txt|more
 
simulate: all
vhdle -s -t 10us tbench -do simili.cmd -list trace.txt
-@..\tools\tracehex.exe
-@start ed trace2.txt
 
simulate2: all
vhdle -s -t 4us tbench -do simili.cmd -list trace.txt
-@..\tools\tracehex.exe
-@ed trace2.txt
 
$(WORK_DIR)/lpm_pack/$(DEP_FILE): lpm_pack.vhd
$(COMPILE) lpm_pack.vhd
 
$(WORK_DIR)/lpm_model/$(DEP_FILE): lpm_model.vhd
$(COMPILE) -87 lpm_model.vhd
 
$(WORK_DIR)/mlite_pack/$(DEP_FILE): mlite_pack.vhd
$(COMPILE) mlite_pack.vhd
 
$(WORK_DIR)/alu/$(DEP_FILE): mlite_pack.vhd alu.vhd
$(COMPILE) alu.vhd
 
$(WORK_DIR)/bus_mux/$(DEP_FILE): mlite_pack.vhd bus_mux.vhd
$(COMPILE) bus_mux.vhd
 
$(WORK_DIR)/control/$(DEP_FILE): mlite_pack.vhd control.vhd
$(COMPILE) control.vhd
 
$(WORK_DIR)/mem_ctrl/$(DEP_FILE): mlite_pack.vhd mem_ctrl.vhd
$(COMPILE) mem_ctrl.vhd
 
$(WORK_DIR)/mult/$(DEP_FILE): mlite_pack.vhd mult.vhd
$(COMPILE) mult.vhd
 
$(WORK_DIR)/pc_next/$(DEP_FILE): mlite_pack.vhd pc_next.vhd
$(COMPILE) pc_next.vhd
 
$(WORK_DIR)/reg_bank/$(DEP_FILE): mlite_pack.vhd reg_bank.vhd
$(COMPILE) reg_bank.vhd
 
$(WORK_DIR)/shifter/$(DEP_FILE): mlite_pack.vhd shifter.vhd
$(COMPILE) shifter.vhd
 
$(WORK_DIR)/pipeline/$(DEP_FILE): mlite_pack.vhd pipeline.vhd
$(COMPILE) pipeline.vhd
 
$(WORK_DIR)/mlite_cpu/$(DEP_FILE): mlite_cpu.vhd \
$(WORK_DIR)/mlite_pack/$(DEP_FILE) \
$(WORK_DIR)/alu/$(DEP_FILE) \
$(WORK_DIR)/bus_mux/$(DEP_FILE) \
$(WORK_DIR)/control/$(DEP_FILE) \
$(WORK_DIR)/mem_ctrl/$(DEP_FILE) \
$(WORK_DIR)/mult/$(DEP_FILE) \
$(WORK_DIR)/pc_next/$(DEP_FILE) \
$(WORK_DIR)/reg_bank/$(DEP_FILE) \
$(WORK_DIR)/shifter/$(DEP_FILE) \
$(WORK_DIR)/pipeline/$(DEP_FILE)
$(COMPILE) mlite_cpu.vhd
 
$(WORK_DIR)/ram/$(DEP_FILE): mlite_pack.vhd ram.vhd
$(COMPILE) -87 ram.vhd
 
$(WORK_DIR)/uart/$(DEP_FILE): mlite_pack.vhd uart.vhd
$(COMPILE) -87 uart.vhd
 
$(WORK_DIR)/plasma/$(DEP_FILE): mlite_pack.vhd plasma.vhd \
$(WORK_DIR)/mlite_cpu/$(DEP_FILE) \
$(WORK_DIR)/ram/$(DEP_FILE) \
$(WORK_DIR)/uart/$(DEP_FILE)
$(COMPILE) plasma.vhd
 
$(WORK_DIR)/plasma_if/$(DEP_FILE): mlite_pack.vhd plasma_if.vhd \
$(WORK_DIR)/plasma/$(DEP_FILE)
$(COMPILE) plasma_if.vhd
 
$(WORK_DIR)/tbench/$(DEP_FILE): mlite_pack.vhd tbench.vhd \
$(WORK_DIR)/plasma/$(DEP_FILE) \
$(WORK_DIR)/plasma_if/$(DEP_FILE)
$(COMPILE) tbench.vhd
 
altera: $(WORK_DIR)/lpm_pack/$(DEP_FILE) \
$(WORK_DIR)/lpm_model/$(DEP_FILE)
echo UNUSED > UNUSED
 
/simili.cmd
0,0 → 1,8
add list /u1/*
#add list /u1/u1_cpu/*
#add list /u1/u1_cpu/u8_mult/*
#add list /u1/u1_cpu/pc /u1/u1_cpu/opcode /u1/*
#add list /u1/u1_cpu/u3_control/*
#add list /u1/u1_cpu/u8_mult/*
SetListStyle nodelta collapse
SetListInterval 0us 1ms
simili.cmd Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.