1
0
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:
J
2019-03-03 23:16:35 -05:00
parent a0acbcafdc
commit 4a6746a0b1
5 changed files with 149 additions and 1 deletions

View File

@@ -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
View 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
View 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

BIN
ram.img

Binary file not shown.

74
simple_ram.vhd Normal file
View 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;