mirror of
https://github.com/j-core/j-core-ice40.git
synced 2026-04-20 09:27:27 +00:00
With single port RAM
This commit is contained in:
@@ -10,6 +10,18 @@ entity cpu_pure_tb is
|
||||
end;
|
||||
|
||||
architecture behaviour of cpu_pure_tb is
|
||||
function to_hex_string(s: in std_logic_vector) return string is
|
||||
constant hex : string (1 to 16) := "0123456789ABCDEF";
|
||||
variable ss : std_logic_vector(31 downto 0) := (others => '0');
|
||||
variable ret : string (1 to ss'left/4+1);
|
||||
begin
|
||||
ss(s'range) := s;
|
||||
for i in 0 to ss'left/4 loop
|
||||
ret(i+1) := hex(to_integer(unsigned(ss(ss'left - i*4 downto ss'left - i*4 -3)))+1);
|
||||
end loop;
|
||||
return ret;
|
||||
end to_hex_string;
|
||||
|
||||
type instrd_bus_i_t is array(instr_bus_device_t'left to instr_bus_device_t'right) of cpu_data_i_t;
|
||||
type instrd_bus_o_t is array(instr_bus_device_t'left to instr_bus_device_t'right) of cpu_data_o_t;
|
||||
|
||||
@@ -150,7 +162,7 @@ begin
|
||||
wait until clk'event and clk = '1';
|
||||
if pio_data_o.wr = '1' and pio_data_o.a = x"ABCD0000" then
|
||||
write(l, string'("LED: Write "));
|
||||
-- hwrite(l, pio_data_o.d);
|
||||
write(l, to_hex_string(pio_data_o.d));
|
||||
write(l, " at " & time'image(now));
|
||||
writeline(output, l);
|
||||
end if;
|
||||
|
||||
55
cpu_simple_sram.vhd
Normal file
55
cpu_simple_sram.vhd
Normal file
@@ -0,0 +1,55 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use work.cpu2j0_pack.all;
|
||||
|
||||
entity cpu_sram is
|
||||
port (
|
||||
clk : in std_logic;
|
||||
ibus_i : in cpu_instruction_o_t;
|
||||
ibus_o : out cpu_instruction_i_t;
|
||||
db_i : in cpu_data_o_t;
|
||||
db_o : out cpu_data_i_t
|
||||
);
|
||||
end;
|
||||
|
||||
architecture struc of cpu_sram is
|
||||
signal db_we : std_logic_vector(3 downto 0);
|
||||
signal rd : std_logic_vector(31 downto 0);
|
||||
signal ra : std_logic_vector(12 downto 2);
|
||||
signal en : std_logic;
|
||||
signal iclk : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
db_we <= (db_i.wr and db_i.we(3)) &
|
||||
(db_i.wr and db_i.we(2)) &
|
||||
(db_i.wr and db_i.we(1)) &
|
||||
(db_i.wr and db_i.we(0));
|
||||
|
||||
ra <= db_i.a(12 downto 2) when db_i.en = '1' else ibus_i.a(12 downto 2);
|
||||
|
||||
-- clk memory on negative edge to avoid wait states
|
||||
iclk <= not clk;
|
||||
en <= db_i.en or ibus_i.en;
|
||||
|
||||
r : entity work.simple_ram
|
||||
generic map (ADDR_WIDTH => 13)
|
||||
port map(clk => iclk,
|
||||
en => en,
|
||||
we => db_we,
|
||||
waddr => db_i.a(12 downto 2),
|
||||
di => db_i.d,
|
||||
|
||||
raddr => ra,
|
||||
do => rd);
|
||||
|
||||
-- (too) simple output mux
|
||||
db_o.d <= rd;
|
||||
ibus_o.d <= rd(31 downto 16) when ibus_i.a(1) = '0' else rd(15 downto 0);
|
||||
|
||||
-- simply ack immediately. Should this simulate different delays?
|
||||
db_o.ack <= db_i.en;
|
||||
ibus_o.ack <= ibus_i.en when db_i.en = '0' else '0';
|
||||
|
||||
end architecture struc;
|
||||
7
nvc_simple.sh
Normal file
7
nvc_simple.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
nvc -a cpu2j0_pkg.vhd components_pkg.vhd mult_pkg.vhd decode_pkg.vhd decode_body.vhd datapath_pkg.vhd cpu.vhd decode.vhd decode_core.vhd decode_table.vhd decode_table_reverse.vhd datapath.vhd register_file.vhd mult.vhd
|
||||
|
||||
nvc -a data_bus_pkg.vhd monitor_pkg.vhd simple_ram.vhd bus_monitor.vhd timeout_cnt.vhd cpu_simple_sram.vhd cpu_pure_tb.vhh
|
||||
|
||||
nvc -e -V cpu_pure_tb
|
||||
74
simple_ram.vhd
Normal file
74
simple_ram.vhd
Normal file
@@ -0,0 +1,74 @@
|
||||
-- A simple pre-initalized RAM, which reads from a binary file at synthesis time
|
||||
-- single 32 bit read/write port.
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity simple_ram is
|
||||
generic (
|
||||
-- 32-bit read/write port. ADDR_WIDTH is in bytes, not words.
|
||||
ADDR_WIDTH : integer := 15 -- default 32k
|
||||
);
|
||||
port (
|
||||
clk : in std_logic;
|
||||
|
||||
en : in std_logic;
|
||||
raddr : in std_logic_vector(ADDR_WIDTH - 3 downto 0);
|
||||
do : out std_logic_vector(31 downto 0);
|
||||
|
||||
we : in std_logic_vector(3 downto 0);
|
||||
waddr : in std_logic_vector(ADDR_WIDTH - 3 downto 0);
|
||||
di : in std_logic_vector(31 downto 0)
|
||||
);
|
||||
end simple_ram;
|
||||
|
||||
architecture behavioral of simple_ram is
|
||||
constant NUM_WORDS : integer := 2**(ADDR_WIDTH - 2);
|
||||
type ram_type is array (0 to NUM_WORDS-1) of std_logic_vector(31 downto 0);
|
||||
|
||||
impure function load_binary(filename : string) return ram_type is
|
||||
type binary_file is file of character;
|
||||
file f : binary_file;
|
||||
variable c : character;
|
||||
variable mem : ram_type;
|
||||
begin
|
||||
file_open(f, filename, read_mode);
|
||||
for i in ram_type'range loop
|
||||
mem(i) := (others => '0');
|
||||
-- read 4 bytes and store in big endian order
|
||||
for bi in 3 downto 0 loop
|
||||
if not endfile(f) then
|
||||
read(f, c);
|
||||
mem(i)((bi+1)*8 - 1 downto bi*8) :=
|
||||
std_logic_vector(to_unsigned(character'pos(c), 8));
|
||||
end if;
|
||||
end loop;
|
||||
end loop;
|
||||
file_close(f);
|
||||
return mem;
|
||||
end;
|
||||
|
||||
signal ram : ram_type := load_binary("ram.img");
|
||||
begin
|
||||
|
||||
process (clk)
|
||||
variable read : std_logic_vector(31 downto 0);
|
||||
begin
|
||||
if clk'event and clk = '1' and en = '1' then
|
||||
if we(3) = '1' then
|
||||
ram(to_integer(unsigned(waddr)))(31 downto 24) <= di(31 downto 24);
|
||||
end if;
|
||||
if we(2) = '1' then
|
||||
ram(to_integer(unsigned(waddr)))(23 downto 16) <= di(23 downto 16);
|
||||
end if;
|
||||
if we(1) = '1' then
|
||||
ram(to_integer(unsigned(waddr)))(15 downto 8 ) <= di(15 downto 8 );
|
||||
end if;
|
||||
if we(0) = '1' then
|
||||
ram(to_integer(unsigned(waddr)))(7 downto 0 ) <= di(7 downto 0 );
|
||||
end if;
|
||||
read := ram(to_integer(unsigned(raddr)));
|
||||
do <= read;
|
||||
end if;
|
||||
end process;
|
||||
end behavioral;
|
||||
Reference in New Issue
Block a user