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.

src/bram.vhd CHANGED
@@ -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
- -- 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,17 +48,17 @@ begin
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;
 
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.

src/bram.vhd CHANGED
@@ -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
- -- shared variable RAM: ram_type := (others => (others => '0'));
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) <= dia((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.

src/mem_subsys.vhd CHANGED
@@ -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(clka => clk, ena => req.active, wea => req.write_enable, addra => req.address(11 downto 2), dia => req.value, doa => res);
 
 
 
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.

src/constants.vhd CHANGED
@@ -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;
src/mem_subsys.vhd CHANGED
@@ -9,8 +9,10 @@ use work.constants.all;
9
  entity mem_subsys is
10
  port (
11
  clk: in std_logic;
12
- req: in mem_req_t;
13
- res: out std_logic_vector(31 downto 0)
 
 
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 => 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;
 
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;
src/top_level.vhd CHANGED
@@ -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 mem_req: mem_req_t;
18
- signal mem_res: std_logic_vector(31 downto 0);
 
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
- req: in mem_req_t;
33
- res: out std_logic_vector(31 downto 0)
 
 
34
  );
35
  end component;
36
 
37
  begin
38
 
39
- core_inst: core port map(clk => clk, mem_req => mem_req, mem_res => mem_res, led => led);
40
 
41
- mem_subsys_inst: mem_subsys port map(clk => clk, req => mem_req, res => mem_res);
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;
src/types.vhd CHANGED
@@ -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.

src/core.vhd CHANGED
@@ -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
- mem_req: out mem_req_t;
15
- mem_res: in std_logic_vector(31 downto 0);
 
 
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 => mem_res, pipeline_ready => pipeline_ready);
75
 
76
- execute_inst: execute port map(clk => clk, input => decode_output, output => execute_output, mem_req => mem_req, jump => jump, jump_address => jump_address, led => led);
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
 
src/mem_subsys.vhd CHANGED
@@ -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;
src/top_level.vhd CHANGED
@@ -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 := 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 (
24
  clk: in std_logic;
25
- mem_req: out mem_req_t;
26
- mem_res: in std_logic_vector(31 downto 0);
 
 
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, 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;
 
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.

src/core.vhd CHANGED
@@ -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 := 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)
@@ -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
 
src/core/fetch.vhd CHANGED
@@ -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.

src/core/fetch.vhd CHANGED
@@ -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.

src/bram.vhd CHANGED
@@ -24,8 +24,136 @@ entity bram is
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
 
 
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.

src/bram.vhd CHANGED
@@ -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(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
  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 NB_COL - 1 loop
166
  if wea(i) = '1' then
167
- RAM(conv_integer(addra))((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH) := dia((i + 1) * COL_WIDTH - 1 downto i * COL_WIDTH);
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));
src/mem_subsys.vhd CHANGED
@@ -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(NB_COL - 1 downto 0);
32
- addra: in std_logic_vector(ADDR_WIDTH - 1 downto 0);
33
- dia: in std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
34
- doa: out std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0);
35
  clkb: in std_logic;
36
  enb: in std_logic;
37
- addrb: in std_logic_vector(ADDR_WIDTH - 1 downto 0);
38
- dob: out std_logic_vector(NB_COL * COL_WIDTH - 1 downto 0)
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.

src/core.vhd CHANGED
@@ -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
 
src/core/fetch.vhd CHANGED
@@ -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).

src/core/constants.vhd CHANGED
@@ -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 => '0'),
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!