fetch1.vhdl 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. library work;
  5. use work.common.all;
  6. entity fetch1 is
  7. generic(
  8. RESET_ADDRESS : std_logic_vector(63 downto 0) := (others => '0');
  9. ALT_RESET_ADDRESS : std_logic_vector(63 downto 0) := (others => '0');
  10. HAS_BTC : boolean := true
  11. );
  12. port(
  13. clk : in std_ulogic;
  14. rst : in std_ulogic;
  15. -- Control inputs:
  16. stall_in : in std_ulogic;
  17. flush_in : in std_ulogic;
  18. inval_btc : in std_ulogic;
  19. stop_in : in std_ulogic;
  20. alt_reset_in : in std_ulogic;
  21. -- redirect from writeback unit
  22. w_in : in WritebackToFetch1Type;
  23. -- redirect from decode1
  24. d_in : in Decode1ToFetch1Type;
  25. -- Request to icache
  26. i_out : out Fetch1ToIcacheType;
  27. -- outputs to logger
  28. log_out : out std_ulogic_vector(42 downto 0)
  29. );
  30. end entity fetch1;
  31. architecture behaviour of fetch1 is
  32. type reg_internal_t is record
  33. mode_32bit: std_ulogic;
  34. rd_is_niap4: std_ulogic;
  35. predicted: std_ulogic;
  36. predicted_nia: std_ulogic_vector(63 downto 0);
  37. end record;
  38. signal r, r_next : Fetch1ToIcacheType;
  39. signal r_int, r_next_int : reg_internal_t;
  40. signal advance_nia : std_ulogic;
  41. signal log_nia : std_ulogic_vector(42 downto 0);
  42. constant BTC_ADDR_BITS : integer := 10;
  43. constant BTC_TAG_BITS : integer := 62 - BTC_ADDR_BITS;
  44. constant BTC_TARGET_BITS : integer := 62;
  45. constant BTC_SIZE : integer := 2 ** BTC_ADDR_BITS;
  46. constant BTC_WIDTH : integer := BTC_TAG_BITS + BTC_TARGET_BITS;
  47. type btc_mem_type is array (0 to BTC_SIZE - 1) of std_ulogic_vector(BTC_WIDTH - 1 downto 0);
  48. signal btc_rd_data : std_ulogic_vector(BTC_WIDTH - 1 downto 0) := (others => '0');
  49. signal btc_rd_valid : std_ulogic := '0';
  50. begin
  51. regs : process(clk)
  52. begin
  53. if rising_edge(clk) then
  54. log_nia <= r.nia(63) & r.nia(43 downto 2);
  55. if r /= r_next then
  56. report "fetch1 rst:" & std_ulogic'image(rst) &
  57. " IR:" & std_ulogic'image(r_next.virt_mode) &
  58. " P:" & std_ulogic'image(r_next.priv_mode) &
  59. " E:" & std_ulogic'image(r_next.big_endian) &
  60. " 32:" & std_ulogic'image(r_next_int.mode_32bit) &
  61. " R:" & std_ulogic'image(w_in.redirect) & std_ulogic'image(d_in.redirect) &
  62. " S:" & std_ulogic'image(stall_in) &
  63. " T:" & std_ulogic'image(stop_in) &
  64. " nia:" & to_hstring(r_next.nia);
  65. end if;
  66. if rst = '1' or w_in.redirect = '1' or d_in.redirect = '1' or stall_in = '0' then
  67. r.virt_mode <= r_next.virt_mode;
  68. r.priv_mode <= r_next.priv_mode;
  69. r.big_endian <= r_next.big_endian;
  70. r_int.mode_32bit <= r_next_int.mode_32bit;
  71. end if;
  72. if advance_nia = '1' then
  73. r.predicted <= r_next.predicted;
  74. r.nia <= r_next.nia;
  75. r_int.predicted <= r_next_int.predicted;
  76. r_int.predicted_nia <= r_next_int.predicted_nia;
  77. r_int.rd_is_niap4 <= r_next.sequential;
  78. end if;
  79. r.sequential <= r_next.sequential and advance_nia;
  80. -- always send the up-to-date stop mark and req
  81. r.stop_mark <= stop_in;
  82. r.req <= not rst;
  83. end if;
  84. end process;
  85. log_out <= log_nia;
  86. btc : if HAS_BTC generate
  87. signal btc_memory : btc_mem_type;
  88. attribute ram_style : string;
  89. attribute ram_style of btc_memory : signal is "block";
  90. signal btc_valids : std_ulogic_vector(BTC_SIZE - 1 downto 0);
  91. attribute ram_style of btc_valids : signal is "distributed";
  92. signal btc_wr : std_ulogic;
  93. signal btc_wr_data : std_ulogic_vector(BTC_WIDTH - 1 downto 0);
  94. signal btc_wr_addr : std_ulogic_vector(BTC_ADDR_BITS - 1 downto 0);
  95. signal btc_wr_v : std_ulogic;
  96. begin
  97. btc_wr_data <= w_in.br_nia(63 downto BTC_ADDR_BITS + 2) &
  98. w_in.redirect_nia(63 downto 2);
  99. btc_wr_addr <= w_in.br_nia(BTC_ADDR_BITS + 1 downto 2);
  100. btc_wr <= w_in.br_last;
  101. btc_wr_v <= w_in.br_taken;
  102. btc_ram : process(clk)
  103. variable raddr : unsigned(BTC_ADDR_BITS - 1 downto 0);
  104. begin
  105. if rising_edge(clk) then
  106. raddr := unsigned(r.nia(BTC_ADDR_BITS + 1 downto 2)) +
  107. to_unsigned(2, BTC_ADDR_BITS);
  108. if advance_nia = '1' then
  109. btc_rd_data <= btc_memory(to_integer(raddr));
  110. btc_rd_valid <= btc_valids(to_integer(raddr));
  111. end if;
  112. if btc_wr = '1' then
  113. btc_memory(to_integer(unsigned(btc_wr_addr))) <= btc_wr_data;
  114. end if;
  115. if inval_btc = '1' or rst = '1' then
  116. btc_valids <= (others => '0');
  117. elsif btc_wr = '1' then
  118. btc_valids(to_integer(unsigned(btc_wr_addr))) <= btc_wr_v;
  119. end if;
  120. end if;
  121. end process;
  122. end generate;
  123. comb : process(all)
  124. variable v : Fetch1ToIcacheType;
  125. variable v_int : reg_internal_t;
  126. begin
  127. v := r;
  128. v_int := r_int;
  129. v.sequential := '0';
  130. v.predicted := '0';
  131. v_int.predicted := '0';
  132. if rst = '1' then
  133. if alt_reset_in = '1' then
  134. v.nia := ALT_RESET_ADDRESS;
  135. else
  136. v.nia := RESET_ADDRESS;
  137. end if;
  138. v.virt_mode := '0';
  139. v.priv_mode := '1';
  140. v.big_endian := '0';
  141. v_int.mode_32bit := '0';
  142. v_int.predicted_nia := (others => '0');
  143. elsif w_in.redirect = '1' then
  144. v.nia := w_in.redirect_nia(63 downto 2) & "00";
  145. if w_in.mode_32bit = '1' then
  146. v.nia(63 downto 32) := (others => '0');
  147. end if;
  148. v.virt_mode := w_in.virt_mode;
  149. v.priv_mode := w_in.priv_mode;
  150. v.big_endian := w_in.big_endian;
  151. v_int.mode_32bit := w_in.mode_32bit;
  152. elsif d_in.redirect = '1' then
  153. v.nia := d_in.redirect_nia(63 downto 2) & "00";
  154. if r_int.mode_32bit = '1' then
  155. v.nia(63 downto 32) := (others => '0');
  156. end if;
  157. elsif r_int.predicted = '1' then
  158. v.nia := r_int.predicted_nia;
  159. v.predicted := '1';
  160. else
  161. v.sequential := '1';
  162. v.nia := std_ulogic_vector(unsigned(r.nia) + 4);
  163. if r_int.mode_32bit = '1' then
  164. v.nia(63 downto 32) := x"00000000";
  165. end if;
  166. if btc_rd_valid = '1' and r_int.rd_is_niap4 = '1' and
  167. btc_rd_data(BTC_WIDTH - 1 downto BTC_TARGET_BITS)
  168. = v.nia(BTC_TAG_BITS + BTC_ADDR_BITS + 1 downto BTC_ADDR_BITS + 2) then
  169. v_int.predicted := '1';
  170. end if;
  171. end if;
  172. v_int.predicted_nia := btc_rd_data(BTC_TARGET_BITS - 1 downto 0) & "00";
  173. -- If the last NIA value went down with a stop mark, it didn't get
  174. -- executed, and hence we shouldn't increment NIA.
  175. advance_nia <= rst or w_in.redirect or d_in.redirect or (not r.stop_mark and not stall_in);
  176. r_next <= v;
  177. r_next_int <= v_int;
  178. -- Update outputs to the icache
  179. i_out <= r;
  180. end process;
  181. end architecture behaviour;