This lesson starts at commit c2c6ad9e07ff149a1de3863f1d10db636e966997.
9. Reading instructions from main memory
In the last lesson we made sure we can write to and read from the main memory. However, the instructions are still fetched from a hardcoded array of instructions. We'll change that in this lesson, so that instructions are fetched from the "real" memory.
For this, we'll need to enable the second port on the block RAM, which I commented out before.
|
@@ -16,12 +16,12 @@ entity bram is
|
|
| 16 |
addra: in std_logic_vector(ADDR_WIDTH - 1 downto 0);
|
| 17 |
dia: in std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
|
| 18 |
doa: out std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0)
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
);
|
| 26 |
end bram;
|
| 27 |
|
|
@@ -48,17 +48,17 @@ begin
|
|
| 48 |
end process;
|
| 49 |
|
| 50 |
-- port B
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
end rtl;
|
|
|
|
| 16 |
addra: in std_logic_vector(ADDR_WIDTH - 1 downto 0);
|
| 17 |
dia: in std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
|
| 18 |
doa: out std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0)
|
| 19 |
+
clkb: in std_logic;
|
| 20 |
+
enb: in std_logic;
|
| 21 |
+
web: in std_logic_vector(NB_COL - 1 downto 0);
|
| 22 |
+
addrb: in std_logic_vector(ADDR_WIDTH - 1 downto 0);
|
| 23 |
+
dib: in std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
|
| 24 |
+
dob: out std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0)
|
| 25 |
);
|
| 26 |
end bram;
|
| 27 |
|
|
|
|
| 48 |
end process;
|
| 49 |
|
| 50 |
-- port B
|
| 51 |
+
process(clkb)
|
| 52 |
+
begin
|
| 53 |
+
if rising_edge(clkb) then
|
| 54 |
+
if enb = '1' then
|
| 55 |
+
for i in 0 to NB_COL - 1 loop
|
| 56 |
+
if web(i) = '1' then
|
| 57 |
+
RAM(conv_integer(addrb))((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH) := dib((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH);
|
| 58 |
+
end if;
|
| 59 |
+
end loop;
|
| 60 |
+
dob <= RAM(conv_integer(addrb));
|
| 61 |
+
end if;
|
| 62 |
+
end if;
|
| 63 |
+
end process;
|
| 64 |
end rtl;
|
We'll need to make the variable for the RAM shared again. The instruction fetch will only need to read (not write), so we can remove some logic.
|
@@ -15,20 +15,17 @@ entity bram is
|
|
| 15 |
wea: in std_logic_vector(NB_COL - 1 downto 0);
|
| 16 |
addra: in std_logic_vector(ADDR_WIDTH - 1 downto 0);
|
| 17 |
dia: in std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
|
| 18 |
-
doa: out std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0)
|
| 19 |
clkb: in std_logic;
|
| 20 |
enb: in std_logic;
|
| 21 |
-
web: in std_logic_vector(NB_COL - 1 downto 0);
|
| 22 |
addrb: in std_logic_vector(ADDR_WIDTH - 1 downto 0);
|
| 23 |
-
dib: in std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
|
| 24 |
dob: out std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0)
|
| 25 |
);
|
| 26 |
end bram;
|
| 27 |
|
| 28 |
architecture rtl of bram is
|
| 29 |
type ram_type is array (0 to SIZE - 1) of std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
|
| 30 |
-
|
| 31 |
-
signal RAM: ram_type := (others => (others => '0'));
|
| 32 |
|
| 33 |
begin
|
| 34 |
|
|
@@ -39,7 +36,7 @@ begin
|
|
| 39 |
if ena = '1' then
|
| 40 |
for i in 0 to NB_COL - 1 loop
|
| 41 |
if wea(i) = '1' then
|
| 42 |
-
RAM(conv_integer(addra))((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH)
|
| 43 |
end if;
|
| 44 |
end loop;
|
| 45 |
doa <= RAM(conv_integer(addra));
|
|
@@ -52,11 +49,6 @@ begin
|
|
| 52 |
begin
|
| 53 |
if rising_edge(clkb) then
|
| 54 |
if enb = '1' then
|
| 55 |
-
for i in 0 to NB_COL - 1 loop
|
| 56 |
-
if web(i) = '1' then
|
| 57 |
-
RAM(conv_integer(addrb))((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH) := dib((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH);
|
| 58 |
-
end if;
|
| 59 |
-
end loop;
|
| 60 |
dob <= RAM(conv_integer(addrb));
|
| 61 |
end if;
|
| 62 |
end if;
|
|
|
|
| 15 |
wea: in std_logic_vector(NB_COL - 1 downto 0);
|
| 16 |
addra: in std_logic_vector(ADDR_WIDTH - 1 downto 0);
|
| 17 |
dia: in std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
|
| 18 |
+
doa: out std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
|
| 19 |
clkb: in std_logic;
|
| 20 |
enb: in std_logic;
|
|
|
|
| 21 |
addrb: in std_logic_vector(ADDR_WIDTH - 1 downto 0);
|
|
|
|
| 22 |
dob: out std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0)
|
| 23 |
);
|
| 24 |
end bram;
|
| 25 |
|
| 26 |
architecture rtl of bram is
|
| 27 |
type ram_type is array (0 to SIZE - 1) of std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
|
| 28 |
+
shared variable RAM: ram_type := (others => (others => '0'));
|
|
|
|
| 29 |
|
| 30 |
begin
|
| 31 |
|
|
|
|
| 36 |
if ena = '1' then
|
| 37 |
for i in 0 to NB_COL - 1 loop
|
| 38 |
if wea(i) = '1' then
|
| 39 |
+
RAM(conv_integer(addra))((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH) := dia((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH);
|
| 40 |
end if;
|
| 41 |
end loop;
|
| 42 |
doa <= RAM(conv_integer(addra));
|
|
|
|
| 49 |
begin
|
| 50 |
if rising_edge(clkb) then
|
| 51 |
if enb = '1' then
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
dob <= RAM(conv_integer(addrb));
|
| 53 |
end if;
|
| 54 |
end if;
|
Now, we'll need update the component definition in mem_subsys.vhd, and hook up the new inputs and output.
|
@@ -29,11 +29,18 @@ architecture rtl of mem_subsys is
|
|
| 29 |
wea: in std_logic_vector(NB_COL - 1 downto 0);
|
| 30 |
addra: in std_logic_vector(ADDR_WIDTH - 1 downto 0);
|
| 31 |
dia: in std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
|
| 32 |
-
doa: out std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
);
|
| 34 |
end component;
|
| 35 |
|
| 36 |
begin
|
| 37 |
-
bram_inst: bram port map(
|
|
|
|
|
|
|
|
|
|
| 38 |
|
| 39 |
end rtl;
|
|
|
|
| 29 |
wea: in std_logic_vector(NB_COL - 1 downto 0);
|
| 30 |
addra: in std_logic_vector(ADDR_WIDTH - 1 downto 0);
|
| 31 |
dia: in std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
|
| 32 |
+
doa: out std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
|
| 33 |
+
clkb: in std_logic;
|
| 34 |
+
enb: in std_logic;
|
| 35 |
+
addrb: in std_logic_vector(ADDR_WIDTH - 1 downto 0);
|
| 36 |
+
dob: out std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0)
|
| 37 |
);
|
| 38 |
end component;
|
| 39 |
|
| 40 |
begin
|
| 41 |
+
bram_inst: bram port map(
|
| 42 |
+
clka => clk, ena => req.active, wea => req.write_enable, addra => req.address(11 downto 2), dia => req.value, doa => res,
|
| 43 |
+
clkb => clk, enb => '0', addrb => (others => '0')
|
| 44 |
+
);
|
| 45 |
|
| 46 |
end rtl;
|
Now we want to add another port to the memory subsystem that the instruction fetch can use.
|
@@ -11,4 +11,9 @@ package constants is
|
|
| 11 |
address => (others => '0'),
|
| 12 |
value => (others => '0')
|
| 13 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
end package constants;
|
|
|
|
| 11 |
address => (others => '0'),
|
| 12 |
value => (others => '0')
|
| 13 |
);
|
| 14 |
+
|
| 15 |
+
constant DEFAULT_MEM_READ_REQ: mem_read_req_t := (
|
| 16 |
+
active => '0',
|
| 17 |
+
address => (others => '0')
|
| 18 |
+
);
|
| 19 |
end package constants;
|
|
@@ -9,8 +9,10 @@ use work.constants.all;
|
|
| 9 |
entity mem_subsys is
|
| 10 |
port (
|
| 11 |
clk: in std_logic;
|
| 12 |
-
|
| 13 |
-
|
|
|
|
|
|
|
| 14 |
);
|
| 15 |
end mem_subsys;
|
| 16 |
|
|
@@ -39,8 +41,8 @@ architecture rtl of mem_subsys is
|
|
| 39 |
|
| 40 |
begin
|
| 41 |
bram_inst: bram port map(
|
| 42 |
-
clka => clk, ena =>
|
| 43 |
-
clkb => clk, enb =>
|
| 44 |
);
|
| 45 |
|
| 46 |
end rtl;
|
|
|
|
| 9 |
entity mem_subsys is
|
| 10 |
port (
|
| 11 |
clk: in std_logic;
|
| 12 |
+
req_1: in mem_req_t;
|
| 13 |
+
req_2: in mem_read_req_t;
|
| 14 |
+
res_1: out std_logic_vector(31 downto 0);
|
| 15 |
+
res_2: out std_logic_vector(31 downto 0)
|
| 16 |
);
|
| 17 |
end mem_subsys;
|
| 18 |
|
|
|
|
| 41 |
|
| 42 |
begin
|
| 43 |
bram_inst: bram port map(
|
| 44 |
+
clka => clk, ena => req_1.active, wea => req_1.write_enable, addra => req_1.address(11 downto 2), dia => req_1.value, doa => res_1,
|
| 45 |
+
clkb => clk, enb => req_2.active, addrb => req_2.address(11 downto 2)
|
| 46 |
);
|
| 47 |
|
| 48 |
end rtl;
|
|
@@ -3,6 +3,7 @@ use ieee.std_logic_1164.all;
|
|
| 3 |
use ieee.numeric_std.all;
|
| 4 |
|
| 5 |
use work.types.all;
|
|
|
|
| 6 |
|
| 7 |
|
| 8 |
entity top_level is
|
|
@@ -14,8 +15,9 @@ end top_level;
|
|
| 14 |
|
| 15 |
|
| 16 |
architecture rtl of top_level is
|
| 17 |
-
signal
|
| 18 |
-
signal
|
|
|
|
| 19 |
|
| 20 |
component core is
|
| 21 |
port (
|
|
@@ -29,15 +31,17 @@ architecture rtl of top_level is
|
|
| 29 |
component mem_subsys is
|
| 30 |
port (
|
| 31 |
clk: in std_logic;
|
| 32 |
-
|
| 33 |
-
|
|
|
|
|
|
|
| 34 |
);
|
| 35 |
end component;
|
| 36 |
|
| 37 |
begin
|
| 38 |
|
| 39 |
-
core_inst: core port map(clk => clk, mem_req =>
|
| 40 |
|
| 41 |
-
mem_subsys_inst: mem_subsys port map(clk => clk,
|
| 42 |
|
| 43 |
end rtl;
|
|
|
|
| 3 |
use ieee.numeric_std.all;
|
| 4 |
|
| 5 |
use work.types.all;
|
| 6 |
+
use work.constants.all;
|
| 7 |
|
| 8 |
|
| 9 |
entity top_level is
|
|
|
|
| 15 |
|
| 16 |
|
| 17 |
architecture rtl of top_level is
|
| 18 |
+
signal mem_req_1: mem_req_t;
|
| 19 |
+
signal mem_req_2: mem_read_req_t := DEFAULT_MEM_READ_REQ;
|
| 20 |
+
signal mem_res_1, mem_res_2: std_logic_vector(31 downto 0);
|
| 21 |
|
| 22 |
component core is
|
| 23 |
port (
|
|
|
|
| 31 |
component mem_subsys is
|
| 32 |
port (
|
| 33 |
clk: in std_logic;
|
| 34 |
+
req_1: in mem_req_t;
|
| 35 |
+
req_2: in mem_read_req_t;
|
| 36 |
+
res_1: out std_logic_vector(31 downto 0);
|
| 37 |
+
res_2: out std_logic_vector(31 downto 0)
|
| 38 |
);
|
| 39 |
end component;
|
| 40 |
|
| 41 |
begin
|
| 42 |
|
| 43 |
+
core_inst: core port map(clk => clk, mem_req => mem_req_1, mem_res => mem_res_1, led => led);
|
| 44 |
|
| 45 |
+
mem_subsys_inst: mem_subsys port map(clk => clk, req_1 => mem_req_1, res_1 => mem_res_1, req_2 => mem_req_2, res_2 => open);
|
| 46 |
|
| 47 |
end rtl;
|
|
@@ -11,4 +11,9 @@ package types is
|
|
| 11 |
address: std_logic_vector(31 downto 0);
|
| 12 |
value: std_logic_vector(31 downto 0);
|
| 13 |
end record mem_req_t;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
end package types;
|
|
|
|
| 11 |
address: std_logic_vector(31 downto 0);
|
| 12 |
value: std_logic_vector(31 downto 0);
|
| 13 |
end record mem_req_t;
|
| 14 |
+
|
| 15 |
+
type mem_read_req_t is record
|
| 16 |
+
active: std_logic;
|
| 17 |
+
address: std_logic_vector(31 downto 0);
|
| 18 |
+
end record mem_read_req_t;
|
| 19 |
end package types;
|
Now we also need to add that read port to the core, so that the instruction fetch can access it. We're almost done with the plumbing for this one, I promise.
|
@@ -3,6 +3,7 @@ use ieee.std_logic_1164.all;
|
|
| 3 |
use ieee.numeric_std.all;
|
| 4 |
|
| 5 |
use work.types.all;
|
|
|
|
| 6 |
|
| 7 |
use work.core_types.all;
|
| 8 |
use work.core_constants.all;
|
|
@@ -11,8 +12,10 @@ use work.core_constants.all;
|
|
| 11 |
entity core is
|
| 12 |
port (
|
| 13 |
clk: in std_logic;
|
| 14 |
-
|
| 15 |
-
|
|
|
|
|
|
|
| 16 |
led: out std_logic_vector(7 downto 0)
|
| 17 |
);
|
| 18 |
end core;
|
|
@@ -71,9 +74,9 @@ architecture rtl of core is
|
|
| 71 |
begin
|
| 72 |
fetch_inst: fetch port map(clk => clk, pipeline_ready => pipeline_ready, jump => jump, jump_address => jump_address, output => fetch_output);
|
| 73 |
|
| 74 |
-
decode_write_inst: decode_write port map(clk => clk, decode_input => fetch_output, decode_output => decode_output, write_input => memory_output, mem_res =>
|
| 75 |
|
| 76 |
-
execute_inst: execute port map(clk => clk, input => decode_output, output => execute_output, mem_req =>
|
| 77 |
|
| 78 |
memory_inst: memory port map(clk => clk, input => execute_output, output => memory_output);
|
| 79 |
|
|
|
|
| 3 |
use ieee.numeric_std.all;
|
| 4 |
|
| 5 |
use work.types.all;
|
| 6 |
+
use work.constants.all;
|
| 7 |
|
| 8 |
use work.core_types.all;
|
| 9 |
use work.core_constants.all;
|
|
|
|
| 12 |
entity core is
|
| 13 |
port (
|
| 14 |
clk: in std_logic;
|
| 15 |
+
mem_req_1: out mem_req_t;
|
| 16 |
+
mem_req_2: out mem_read_req_t := DEFAULT_MEM_READ_REQ;
|
| 17 |
+
mem_res_1: in std_logic_vector(31 downto 0);
|
| 18 |
+
mem_res_2: in std_logic_vector(31 downto 0);
|
| 19 |
led: out std_logic_vector(7 downto 0)
|
| 20 |
);
|
| 21 |
end core;
|
|
|
|
| 74 |
begin
|
| 75 |
fetch_inst: fetch port map(clk => clk, pipeline_ready => pipeline_ready, jump => jump, jump_address => jump_address, output => fetch_output);
|
| 76 |
|
| 77 |
+
decode_write_inst: decode_write port map(clk => clk, decode_input => fetch_output, decode_output => decode_output, write_input => memory_output, mem_res => mem_res_1, pipeline_ready => pipeline_ready);
|
| 78 |
|
| 79 |
+
execute_inst: execute port map(clk => clk, input => decode_output, output => execute_output, mem_req => mem_req_1, jump => jump, jump_address => jump_address, led => led);
|
| 80 |
|
| 81 |
memory_inst: memory port map(clk => clk, input => execute_output, output => memory_output);
|
| 82 |
|
|
@@ -42,7 +42,7 @@ architecture rtl of mem_subsys is
|
|
| 42 |
begin
|
| 43 |
bram_inst: bram port map(
|
| 44 |
clka => clk, ena => req_1.active, wea => req_1.write_enable, addra => req_1.address(11 downto 2), dia => req_1.value, doa => res_1,
|
| 45 |
-
clkb => clk, enb => req_2.active, addrb => req_2.address(11 downto 2)
|
| 46 |
);
|
| 47 |
|
| 48 |
end rtl;
|
|
|
|
| 42 |
begin
|
| 43 |
bram_inst: bram port map(
|
| 44 |
clka => clk, ena => req_1.active, wea => req_1.write_enable, addra => req_1.address(11 downto 2), dia => req_1.value, doa => res_1,
|
| 45 |
+
clkb => clk, enb => req_2.active, addrb => req_2.address(11 downto 2), dob => res_2
|
| 46 |
);
|
| 47 |
|
| 48 |
end rtl;
|
|
@@ -16,14 +16,16 @@ end top_level;
|
|
| 16 |
|
| 17 |
architecture rtl of top_level is
|
| 18 |
signal mem_req_1: mem_req_t;
|
| 19 |
-
signal mem_req_2: mem_read_req_t
|
| 20 |
signal mem_res_1, mem_res_2: std_logic_vector(31 downto 0);
|
| 21 |
|
| 22 |
component core is
|
| 23 |
port (
|
| 24 |
clk: in std_logic;
|
| 25 |
-
|
| 26 |
-
|
|
|
|
|
|
|
| 27 |
led: out std_logic_vector(7 downto 0)
|
| 28 |
);
|
| 29 |
end component;
|
|
@@ -40,8 +42,8 @@ architecture rtl of top_level is
|
|
| 40 |
|
| 41 |
begin
|
| 42 |
|
| 43 |
-
core_inst: core port map(clk => clk,
|
| 44 |
|
| 45 |
-
mem_subsys_inst: mem_subsys port map(clk => clk, req_1 => mem_req_1, res_1 => mem_res_1, req_2 => mem_req_2, res_2 =>
|
| 46 |
|
| 47 |
end rtl;
|
|
|
|
| 16 |
|
| 17 |
architecture rtl of top_level is
|
| 18 |
signal mem_req_1: mem_req_t;
|
| 19 |
+
signal mem_req_2: mem_read_req_t;
|
| 20 |
signal mem_res_1, mem_res_2: std_logic_vector(31 downto 0);
|
| 21 |
|
| 22 |
component core is
|
| 23 |
port (
|
| 24 |
clk: in std_logic;
|
| 25 |
+
mem_req_1: out mem_req_t;
|
| 26 |
+
mem_req_2: out mem_read_req_t;
|
| 27 |
+
mem_res_1: in std_logic_vector(31 downto 0);
|
| 28 |
+
mem_res_2: in std_logic_vector(31 downto 0);
|
| 29 |
led: out std_logic_vector(7 downto 0)
|
| 30 |
);
|
| 31 |
end component;
|
|
|
|
| 42 |
|
| 43 |
begin
|
| 44 |
|
| 45 |
+
core_inst: core port map(clk => clk, mem_req_1 => mem_req_1, mem_res_1 => mem_res_1, mem_req_2 => mem_req_2, mem_res_2 => mem_res_2, led => led);
|
| 46 |
|
| 47 |
+
mem_subsys_inst: mem_subsys port map(clk => clk, req_1 => mem_req_1, res_1 => mem_res_1, req_2 => mem_req_2, res_2 => mem_res_2);
|
| 48 |
|
| 49 |
end rtl;
|
Now we add a read port to the fetch stage and hook it up to the read port of the core.
|
@@ -13,7 +13,7 @@ entity core is
|
|
| 13 |
port (
|
| 14 |
clk: in std_logic;
|
| 15 |
mem_req_1: out mem_req_t;
|
| 16 |
-
mem_req_2: out mem_read_req_t
|
| 17 |
mem_res_1: in std_logic_vector(31 downto 0);
|
| 18 |
mem_res_2: in std_logic_vector(31 downto 0);
|
| 19 |
led: out std_logic_vector(7 downto 0)
|
|
@@ -36,6 +36,7 @@ architecture rtl of core is
|
|
| 36 |
pipeline_ready: in std_logic;
|
| 37 |
jump: in std_logic;
|
| 38 |
jump_address: in std_logic_vector(31 downto 0);
|
|
|
|
| 39 |
output: out fetch_output_t
|
| 40 |
);
|
| 41 |
end component;
|
|
@@ -72,7 +73,7 @@ architecture rtl of core is
|
|
| 72 |
end component;
|
| 73 |
|
| 74 |
begin
|
| 75 |
-
fetch_inst: fetch port map(clk => clk, pipeline_ready => pipeline_ready, jump => jump, jump_address => jump_address, output => fetch_output);
|
| 76 |
|
| 77 |
decode_write_inst: decode_write port map(clk => clk, decode_input => fetch_output, decode_output => decode_output, write_input => memory_output, mem_res => mem_res_1, pipeline_ready => pipeline_ready);
|
| 78 |
|
|
|
|
| 13 |
port (
|
| 14 |
clk: in std_logic;
|
| 15 |
mem_req_1: out mem_req_t;
|
| 16 |
+
mem_req_2: out mem_read_req_t;
|
| 17 |
mem_res_1: in std_logic_vector(31 downto 0);
|
| 18 |
mem_res_2: in std_logic_vector(31 downto 0);
|
| 19 |
led: out std_logic_vector(7 downto 0)
|
|
|
|
| 36 |
pipeline_ready: in std_logic;
|
| 37 |
jump: in std_logic;
|
| 38 |
jump_address: in std_logic_vector(31 downto 0);
|
| 39 |
+
mem_req: out mem_read_req_t;
|
| 40 |
output: out fetch_output_t
|
| 41 |
);
|
| 42 |
end component;
|
|
|
|
| 73 |
end component;
|
| 74 |
|
| 75 |
begin
|
| 76 |
+
fetch_inst: fetch port map(clk => clk, pipeline_ready => pipeline_ready, jump => jump, jump_address => jump_address, mem_req => mem_req_2, output => fetch_output);
|
| 77 |
|
| 78 |
decode_write_inst: decode_write port map(clk => clk, decode_input => fetch_output, decode_output => decode_output, write_input => memory_output, mem_res => mem_res_1, pipeline_ready => pipeline_ready);
|
| 79 |
|
|
@@ -2,6 +2,9 @@ library ieee;
|
|
| 2 |
use ieee.std_logic_1164.all;
|
| 3 |
use ieee.numeric_std.all;
|
| 4 |
|
|
|
|
|
|
|
|
|
|
| 5 |
use work.core_types.all;
|
| 6 |
use work.core_constants.all;
|
| 7 |
|
|
@@ -12,6 +15,7 @@ entity fetch is
|
|
| 12 |
pipeline_ready: in std_logic;
|
| 13 |
jump: in std_logic;
|
| 14 |
jump_address: in std_logic_vector(31 downto 0);
|
|
|
|
| 15 |
output: out fetch_output_t := DEFAULT_FETCH_OUTPUT
|
| 16 |
);
|
| 17 |
end fetch;
|
|
|
|
| 2 |
use ieee.std_logic_1164.all;
|
| 3 |
use ieee.numeric_std.all;
|
| 4 |
|
| 5 |
+
use work.types.all;
|
| 6 |
+
use work.constants.all;
|
| 7 |
+
|
| 8 |
use work.core_types.all;
|
| 9 |
use work.core_constants.all;
|
| 10 |
|
|
|
|
| 15 |
pipeline_ready: in std_logic;
|
| 16 |
jump: in std_logic;
|
| 17 |
jump_address: in std_logic_vector(31 downto 0);
|
| 18 |
+
mem_req: out mem_read_req_t := DEFAULT_MEM_READ_REQ;
|
| 19 |
output: out fetch_output_t := DEFAULT_FETCH_OUTPUT
|
| 20 |
);
|
| 21 |
end fetch;
|
Now we actually want to use the memory port.
|
@@ -33,6 +33,8 @@ architecture rtl of fetch is
|
|
| 33 |
signal pc: unsigned(31 downto 0) := (others => '0');
|
| 34 |
|
| 35 |
begin
|
|
|
|
|
|
|
| 36 |
|
| 37 |
process (clk)
|
| 38 |
begin
|
|
|
|
| 33 |
signal pc: unsigned(31 downto 0) := (others => '0');
|
| 34 |
|
| 35 |
begin
|
| 36 |
+
mem_req.active <= pipeline_ready;
|
| 37 |
+
mem_req.address <= std_logic_vector(pc);
|
| 38 |
|
| 39 |
process (clk)
|
| 40 |
begin
|
If we simulate now, we just get zeros from the memory. Which makes sense, because we initialized it like that. So, erm, let's initialize it the same way as we did for the hardcoded array that we used for instruction memory until now.
|
@@ -24,8 +24,136 @@ entity bram is
|
|
| 24 |
end bram;
|
| 25 |
|
| 26 |
architecture rtl of bram is
|
| 27 |
-
|
| 28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
|
| 30 |
begin
|
| 31 |
|
|
|
|
| 24 |
end bram;
|
| 25 |
|
| 26 |
architecture rtl of bram is
|
| 27 |
+
shared variable RAM: ram_type := (
|
| 28 |
+
X"deadc0b7", X"eef08093", X"00102023", X"00101223", X"00101523", X"00100623", X"001008a3", X"00100b23",
|
| 29 |
+
X"00100da3", X"00002103", X"00405183", X"00a05203", X"00c04283", X"01104303", X"01604383", X"01b04403",
|
| 30 |
+
X"00401483", X"00a01503", X"00c00583", X"01100603", X"01600683", X"01b00703", X"0000006f", X"00000000",
|
| 31 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 32 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 33 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 34 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 35 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 36 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 37 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 38 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 39 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 40 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 41 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 42 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 43 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 44 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 45 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 46 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 47 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 48 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 49 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 50 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 51 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 52 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 53 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 54 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 55 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 56 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 57 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 58 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 59 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 60 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 61 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 62 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 63 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 64 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 65 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 66 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 67 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 68 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 69 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 70 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 71 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 72 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 73 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 74 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 75 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 76 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 77 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 78 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 79 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 80 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 81 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 82 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 83 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 84 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 85 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 86 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 87 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 88 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 89 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 90 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 91 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 92 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 93 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 94 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 95 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 96 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 97 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 98 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 99 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 100 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 101 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 102 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 103 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 104 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 105 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 106 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 107 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 108 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 109 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 110 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 111 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 112 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 113 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 114 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 115 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 116 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 117 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 118 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 119 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 120 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 121 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 122 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 123 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 124 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 125 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 126 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 127 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 128 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 129 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 130 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 131 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 132 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 133 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 134 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 135 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 136 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 137 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 138 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 139 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 140 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 141 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 142 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 143 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 144 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 145 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 146 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 147 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 148 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 149 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 150 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 151 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 152 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 153 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 154 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000",
|
| 155 |
+
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000"
|
| 156 |
+
);
|
| 157 |
|
| 158 |
begin
|
| 159 |
|
Let's remove those generics from the block RAM module while we're at it, we won't be using them.
|
@@ -3,27 +3,22 @@ use ieee.std_logic_1164.all;
|
|
| 3 |
use ieee.std_logic_unsigned.all;
|
| 4 |
|
| 5 |
entity bram is
|
| 6 |
-
generic(
|
| 7 |
-
SIZE: integer := 1024;
|
| 8 |
-
ADDR_WIDTH: integer := 10;
|
| 9 |
-
COL_WIDTH: integer := 8;
|
| 10 |
-
NB_COL: integer := 4
|
| 11 |
-
);
|
| 12 |
port(
|
| 13 |
clka: in std_logic;
|
| 14 |
ena: in std_logic;
|
| 15 |
-
wea: in std_logic_vector(
|
| 16 |
-
addra: in std_logic_vector(
|
| 17 |
-
dia: in std_logic_vector(
|
| 18 |
-
doa: out std_logic_vector(
|
| 19 |
clkb: in std_logic;
|
| 20 |
enb: in std_logic;
|
| 21 |
-
addrb: in std_logic_vector(
|
| 22 |
-
dob: out std_logic_vector(
|
| 23 |
);
|
| 24 |
end bram;
|
| 25 |
|
| 26 |
architecture rtl of bram is
|
|
|
|
| 27 |
shared variable RAM: ram_type := (
|
| 28 |
X"deadc0b7", X"eef08093", X"00102023", X"00101223", X"00101523", X"00100623", X"001008a3", X"00100b23",
|
| 29 |
X"00100da3", X"00002103", X"00405183", X"00a05203", X"00c04283", X"01104303", X"01604383", X"01b04403",
|
|
@@ -162,9 +157,9 @@ begin
|
|
| 162 |
begin
|
| 163 |
if rising_edge(clka) then
|
| 164 |
if ena = '1' then
|
| 165 |
-
for i in 0 to
|
| 166 |
if wea(i) = '1' then
|
| 167 |
-
RAM(conv_integer(addra))((i + 1) *
|
| 168 |
end if;
|
| 169 |
end loop;
|
| 170 |
doa <= RAM(conv_integer(addra));
|
|
|
|
| 3 |
use ieee.std_logic_unsigned.all;
|
| 4 |
|
| 5 |
entity bram is
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
port(
|
| 7 |
clka: in std_logic;
|
| 8 |
ena: in std_logic;
|
| 9 |
+
wea: in std_logic_vector(3 downto 0);
|
| 10 |
+
addra: in std_logic_vector(9 downto 0);
|
| 11 |
+
dia: in std_logic_vector(31 downto 0);
|
| 12 |
+
doa: out std_logic_vector(31 downto 0);
|
| 13 |
clkb: in std_logic;
|
| 14 |
enb: in std_logic;
|
| 15 |
+
addrb: in std_logic_vector(9 downto 0);
|
| 16 |
+
dob: out std_logic_vector(31 downto 0)
|
| 17 |
);
|
| 18 |
end bram;
|
| 19 |
|
| 20 |
architecture rtl of bram is
|
| 21 |
+
type ram_type is array (0 to 1023) of std_logic_vector(31 downto 0);
|
| 22 |
shared variable RAM: ram_type := (
|
| 23 |
X"deadc0b7", X"eef08093", X"00102023", X"00101223", X"00101523", X"00100623", X"001008a3", X"00100b23",
|
| 24 |
X"00100da3", X"00002103", X"00405183", X"00a05203", X"00c04283", X"01104303", X"01604383", X"01b04403",
|
|
|
|
| 157 |
begin
|
| 158 |
if rising_edge(clka) then
|
| 159 |
if ena = '1' then
|
| 160 |
+
for i in 0 to 3 loop
|
| 161 |
if wea(i) = '1' then
|
| 162 |
+
RAM(conv_integer(addra))((i + 1) * 8 - 1 downto i * 8) := dia((i + 1) * 8 - 1 downto i * 8);
|
| 163 |
end if;
|
| 164 |
end loop;
|
| 165 |
doa <= RAM(conv_integer(addra));
|
|
@@ -19,23 +19,17 @@ end mem_subsys;
|
|
| 19 |
|
| 20 |
architecture rtl of mem_subsys is
|
| 21 |
component bram is
|
| 22 |
-
generic(
|
| 23 |
-
SIZE: integer := 1024;
|
| 24 |
-
ADDR_WIDTH: integer := 10;
|
| 25 |
-
COL_WIDTH: integer := 8;
|
| 26 |
-
NB_COL: integer := 4
|
| 27 |
-
);
|
| 28 |
port(
|
| 29 |
clka: in std_logic;
|
| 30 |
ena: in std_logic;
|
| 31 |
-
wea: in std_logic_vector(
|
| 32 |
-
addra: in std_logic_vector(
|
| 33 |
-
dia: in std_logic_vector(
|
| 34 |
-
doa: out std_logic_vector(
|
| 35 |
clkb: in std_logic;
|
| 36 |
enb: in std_logic;
|
| 37 |
-
addrb: in std_logic_vector(
|
| 38 |
-
dob: out std_logic_vector(
|
| 39 |
);
|
| 40 |
end component;
|
| 41 |
|
|
|
|
| 19 |
|
| 20 |
architecture rtl of mem_subsys is
|
| 21 |
component bram is
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
port(
|
| 23 |
clka: in std_logic;
|
| 24 |
ena: in std_logic;
|
| 25 |
+
wea: in std_logic_vector(3 downto 0);
|
| 26 |
+
addra: in std_logic_vector(9 downto 0);
|
| 27 |
+
dia: in std_logic_vector(31 downto 0);
|
| 28 |
+
doa: out std_logic_vector(31 downto 0);
|
| 29 |
clkb: in std_logic;
|
| 30 |
enb: in std_logic;
|
| 31 |
+
addrb: in std_logic_vector(9 downto 0);
|
| 32 |
+
dob: out std_logic_vector(31 downto 0)
|
| 33 |
);
|
| 34 |
end component;
|
| 35 |
|
In simulation, we see now that when the active flag in the fetch output is set, the instruction matches what the memory returns. So we can just replace the instruction in the fetch output by the memory contents.
|
@@ -37,6 +37,7 @@ architecture rtl of core is
|
|
| 37 |
jump: in std_logic;
|
| 38 |
jump_address: in std_logic_vector(31 downto 0);
|
| 39 |
mem_req: out mem_read_req_t;
|
|
|
|
| 40 |
output: out fetch_output_t
|
| 41 |
);
|
| 42 |
end component;
|
|
@@ -73,7 +74,7 @@ architecture rtl of core is
|
|
| 73 |
end component;
|
| 74 |
|
| 75 |
begin
|
| 76 |
-
fetch_inst: fetch port map(clk => clk, pipeline_ready => pipeline_ready, jump => jump, jump_address => jump_address, mem_req => mem_req_2, output => fetch_output);
|
| 77 |
|
| 78 |
decode_write_inst: decode_write port map(clk => clk, decode_input => fetch_output, decode_output => decode_output, write_input => memory_output, mem_res => mem_res_1, pipeline_ready => pipeline_ready);
|
| 79 |
|
|
|
|
| 37 |
jump: in std_logic;
|
| 38 |
jump_address: in std_logic_vector(31 downto 0);
|
| 39 |
mem_req: out mem_read_req_t;
|
| 40 |
+
mem_res: in std_logic_vector(31 downto 0);
|
| 41 |
output: out fetch_output_t
|
| 42 |
);
|
| 43 |
end component;
|
|
|
|
| 74 |
end component;
|
| 75 |
|
| 76 |
begin
|
| 77 |
+
fetch_inst: fetch port map(clk => clk, pipeline_ready => pipeline_ready, jump => jump, jump_address => jump_address, mem_req => mem_req_2, mem_res => mem_res_2, output => fetch_output);
|
| 78 |
|
| 79 |
decode_write_inst: decode_write port map(clk => clk, decode_input => fetch_output, decode_output => decode_output, write_input => memory_output, mem_res => mem_res_1, pipeline_ready => pipeline_ready);
|
| 80 |
|
|
@@ -16,25 +16,19 @@ entity fetch is
|
|
| 16 |
jump: in std_logic;
|
| 17 |
jump_address: in std_logic_vector(31 downto 0);
|
| 18 |
mem_req: out mem_read_req_t := DEFAULT_MEM_READ_REQ;
|
|
|
|
| 19 |
output: out fetch_output_t := DEFAULT_FETCH_OUTPUT
|
| 20 |
);
|
| 21 |
end fetch;
|
| 22 |
|
| 23 |
|
| 24 |
architecture rtl of fetch is
|
| 25 |
-
type instruction_memory_t is array(0 to 31) of std_logic_vector(31 downto 0);
|
| 26 |
-
signal imem: instruction_memory_t := (
|
| 27 |
-
X"deadc0b7", X"eef08093", X"00102023", X"00101223", X"00101523", X"00100623", X"001008a3", X"00100b23",
|
| 28 |
-
X"00100da3", X"00002103", X"00405183", X"00a05203", X"00c04283", X"01104303", X"01604383", X"01b04403",
|
| 29 |
-
X"00401483", X"00a01503", X"00c00583", X"01100603", X"01600683", X"01b00703", X"0000006f", X"00000000",
|
| 30 |
-
X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000", X"00000000"
|
| 31 |
-
);
|
| 32 |
-
|
| 33 |
signal pc: unsigned(31 downto 0) := (others => '0');
|
| 34 |
|
| 35 |
begin
|
| 36 |
mem_req.active <= pipeline_ready;
|
| 37 |
mem_req.address <= std_logic_vector(pc);
|
|
|
|
| 38 |
|
| 39 |
process (clk)
|
| 40 |
begin
|
|
@@ -43,7 +37,6 @@ begin
|
|
| 43 |
pc <= pc + 4;
|
| 44 |
|
| 45 |
output.is_active <= '1';
|
| 46 |
-
output.instr <= imem(to_integer(pc(6 downto 2)));
|
| 47 |
output.pc <= std_logic_vector(pc);
|
| 48 |
|
| 49 |
assert jump = '0' report "Fetching and jumping at the same cycle is not supported";
|
|
|
|
| 16 |
jump: in std_logic;
|
| 17 |
jump_address: in std_logic_vector(31 downto 0);
|
| 18 |
mem_req: out mem_read_req_t := DEFAULT_MEM_READ_REQ;
|
| 19 |
+
mem_res: in std_logic_vector(31 downto 0);
|
| 20 |
output: out fetch_output_t := DEFAULT_FETCH_OUTPUT
|
| 21 |
);
|
| 22 |
end fetch;
|
| 23 |
|
| 24 |
|
| 25 |
architecture rtl of fetch is
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
signal pc: unsigned(31 downto 0) := (others => '0');
|
| 27 |
|
| 28 |
begin
|
| 29 |
mem_req.active <= pipeline_ready;
|
| 30 |
mem_req.address <= std_logic_vector(pc);
|
| 31 |
+
output.instr <= mem_res;
|
| 32 |
|
| 33 |
process (clk)
|
| 34 |
begin
|
|
|
|
| 37 |
pc <= pc + 4;
|
| 38 |
|
| 39 |
output.is_active <= '1';
|
|
|
|
| 40 |
output.pc <= std_logic_vector(pc);
|
| 41 |
|
| 42 |
assert jump = '0' report "Fetching and jumping at the same cycle is not supported";
|
If we simulate this, we see it has some problems with setting the instr field in the fetch output. This is due to the default value, and easily fixed by setting the default value of the instr field to 'Z' (high impedence).
|
@@ -7,7 +7,7 @@ use work.core_types.all;
|
|
| 7 |
package core_constants is
|
| 8 |
constant DEFAULT_FETCH_OUTPUT: fetch_output_t := (
|
| 9 |
is_active => '0',
|
| 10 |
-
instr => (others => '
|
| 11 |
pc => (others => '0')
|
| 12 |
);
|
| 13 |
|
|
|
|
| 7 |
package core_constants is
|
| 8 |
constant DEFAULT_FETCH_OUTPUT: fetch_output_t := (
|
| 9 |
is_active => '0',
|
| 10 |
+
instr => (others => 'Z'),
|
| 11 |
pc => (others => '0')
|
| 12 |
);
|
| 13 |
|
Now, our CPU fetches instructions from the main memory, yay!