You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

285 lines
12 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. use std.env.all;
  5. use work.risc_v_pkg.all;
  6. entity risc_v is
  7. port (
  8. reset_n_i : in std_logic;
  9. clk_i : in std_logic;
  10. -- test out
  11. reg_file_o : out t_reg_file;
  12. dmem_o : out t_dmem
  13. );
  14. end entity;
  15. architecture rtl of risc_v is
  16. signal s_reg_file : t_reg_file;
  17. signal s_dmem : t_dmem;
  18. signal s_instr : std_logic_vector(31 downto 0);
  19. signal s_imm : std_logic_vector(31 downto 0);
  20. signal s_dec_bits : std_logic_vector(10 downto 0);
  21. signal s_src1_value : std_logic_vector(31 downto 0);
  22. signal s_src2_value : std_logic_vector(31 downto 0);
  23. signal s_ld_data : std_logic_vector(31 downto 0);
  24. signal s_result : std_logic_vector(31 downto 0);
  25. signal s_sltu_rslt : std_logic_vector(31 downto 0);
  26. signal s_sltiu_rslt : std_logic_vector(31 downto 0);
  27. signal s_pc : unsigned(31 downto 0);
  28. signal s_next_pc : unsigned(31 downto 0);
  29. signal s_br_tgt_br : unsigned(31 downto 0);
  30. signal s_jalr_tgt_pc : unsigned(31 downto 0);
  31. signal s_taken_br : boolean;
  32. signal s_is_r_instr : boolean;
  33. signal s_is_i_instr : boolean;
  34. signal s_is_s_instr : boolean;
  35. signal s_is_b_instr : boolean;
  36. signal s_is_u_instr : boolean;
  37. signal s_is_j_instr : boolean;
  38. signal s_rd_valid : boolean;
  39. signal s_funct3_valid : boolean;
  40. signal s_rs1_valid : boolean;
  41. signal s_rs2_valid : boolean;
  42. signal s_funct7_valid : boolean;
  43. signal s_imm_valid : boolean;
  44. signal s_is_lui : boolean;
  45. signal s_is_auipc : boolean;
  46. signal s_is_jal : boolean;
  47. signal s_is_jalr : boolean;
  48. signal s_is_beq : boolean;
  49. signal s_is_bne : boolean;
  50. signal s_is_blt : boolean;
  51. signal s_is_bge : boolean;
  52. signal s_is_bltu : boolean;
  53. signal s_is_bgeu : boolean;
  54. signal s_is_addi : boolean;
  55. signal s_is_slti : boolean;
  56. signal s_is_sltiu : boolean;
  57. signal s_is_xori : boolean;
  58. signal s_is_ori : boolean;
  59. signal s_is_andi : boolean;
  60. signal s_is_slli : boolean;
  61. signal s_is_srli : boolean;
  62. signal s_is_srai : boolean;
  63. signal s_is_add : boolean;
  64. signal s_is_sub : boolean;
  65. signal s_is_sll : boolean;
  66. signal s_is_slt : boolean;
  67. signal s_is_sltu : boolean;
  68. signal s_is_xor : boolean;
  69. signal s_is_srl : boolean;
  70. signal s_is_sra : boolean;
  71. signal s_is_or : boolean;
  72. signal s_is_and : boolean;
  73. signal s_is_load : boolean;
  74. signal s_is_store : boolean;
  75. signal s_src_sgn_eq : boolean;
  76. signal s_imm_sgn_eq : boolean;
  77. alias a_opcode : std_logic_vector(6 downto 0) is s_instr(6 downto 0);
  78. alias a_rd : std_logic_vector(4 downto 0) is s_instr(11 downto 7);
  79. alias a_funct3 : std_logic_vector(2 downto 0) is s_instr(14 downto 12);
  80. alias a_rs1 : std_logic_vector(4 downto 0) is s_instr(19 downto 15);
  81. alias a_rs2 : std_logic_vector(4 downto 0) is s_instr(24 downto 20);
  82. alias a_funct7 : std_logic_vector(6 downto 0) is s_instr(31 downto 25);
  83. begin
  84. -- Test outs
  85. reg_file_o <= s_reg_file;
  86. dmem_o <= s_dmem;
  87. -- prog counter next state logic
  88. s_next_pc <= 32x"0" when not reset_n_i else
  89. s_br_tgt_br when s_taken_br or s_is_jal else
  90. s_jalr_tgt_pc when s_is_jalr else
  91. s_pc + 4;
  92. -- prog counter register
  93. process (clk_i) is
  94. begin
  95. if rising_edge(clk_i) then
  96. s_pc <= s_next_pc;
  97. end if;
  98. end process;
  99. -- Instruction memory
  100. s_instr <= c_imem(to_integer(s_pc(31 downto 2)));
  101. -- Decode
  102. -- Decode instruction type
  103. s_is_r_instr <= s_instr(6 downto 2) = "01011" or
  104. s_instr(6 downto 2) = "01100" or
  105. s_instr(6 downto 2) = "01110" or
  106. s_instr(6 downto 2) = "10100";
  107. s_is_i_instr <= std_match(s_instr(6 downto 2), "0000-") or
  108. std_match(s_instr(6 downto 2), "001-0") or
  109. s_instr(6 downto 2) = "11001";
  110. s_is_s_instr <= std_match(s_instr(6 downto 2), "0100-");
  111. s_is_b_instr <= s_instr(6 downto 2) = "11000";
  112. s_is_u_instr <= std_match(s_instr(6 downto 2), "0-101");
  113. s_is_j_instr <= s_instr(6 downto 2) = "11011";
  114. -- Extract instruction fields
  115. s_imm <= (31 downto 11 => s_instr(31),
  116. 10 downto 0 => s_instr(30 downto 20)) when s_is_i_instr else
  117. (31 downto 11 => s_instr(31),
  118. 10 downto 5 => s_instr(30 downto 25),
  119. 4 downto 0 => s_instr(11 downto 7)) when s_is_s_instr else
  120. (31 downto 12 => s_instr(31),
  121. 11 => s_instr(7),
  122. 10 downto 5 => s_instr(30 downto 25),
  123. 4 downto 1 => s_instr(11 downto 8),
  124. 0 => '0') when s_is_b_instr else
  125. ( 31 => s_instr(31),
  126. 30 downto 12 => s_instr(30 downto 12),
  127. 11 downto 0 => 12x"0") when s_is_u_instr else
  128. (31 downto 20 => s_instr(31),
  129. 19 downto 12 => s_instr(19 downto 12),
  130. 11 => s_instr(20),
  131. 10 downto 1 => s_instr(30 downto 21),
  132. 0 => '0') when s_is_j_instr else
  133. 32x"0";
  134. -- Calculate instruction fields valids
  135. s_rd_valid <= s_is_r_instr or s_is_i_instr or s_is_u_instr or s_is_j_instr;
  136. s_funct3_valid <= s_is_r_instr or s_is_i_instr or s_is_s_instr or s_is_b_instr;
  137. s_rs1_valid <= s_funct3_valid;
  138. s_rs2_valid <= s_is_r_instr or s_is_s_instr or s_is_b_instr;
  139. s_funct7_valid <= s_is_r_instr;
  140. s_imm_valid <= not s_is_r_instr;
  141. -- Instruction code decoding
  142. s_dec_bits <= (a_funct7(5), a_funct3, a_opcode);
  143. s_is_lui <= std_match(s_dec_bits, b"-_---_0110111");
  144. s_is_auipc <= std_match(s_dec_bits, b"-_---_0010111");
  145. s_is_jal <= std_match(s_dec_bits, b"-_---_1101111");
  146. s_is_jalr <= std_match(s_dec_bits, b"-_000_1100111");
  147. s_is_beq <= std_match(s_dec_bits, b"-_000_1100011");
  148. s_is_bne <= std_match(s_dec_bits, b"-_001_1100011");
  149. s_is_blt <= std_match(s_dec_bits, b"-_100_1100011");
  150. s_is_bge <= std_match(s_dec_bits, b"-_101_1100011");
  151. s_is_bltu <= std_match(s_dec_bits, b"-_110_1100011");
  152. s_is_bgeu <= std_match(s_dec_bits, b"-_111_1100011");
  153. s_is_addi <= std_match(s_dec_bits, b"-_000_0010011");
  154. s_is_slti <= std_match(s_dec_bits, b"-_010_0010011");
  155. s_is_sltiu <= std_match(s_dec_bits, b"-_011_0010011");
  156. s_is_xori <= std_match(s_dec_bits, b"-_100_0010011");
  157. s_is_ori <= std_match(s_dec_bits, b"-_110_0010011");
  158. s_is_andi <= std_match(s_dec_bits, b"-_111_0010011");
  159. s_is_slli <= s_dec_bits = b"0_001_0010011";
  160. s_is_srli <= s_dec_bits = b"0_101_0010011";
  161. s_is_srai <= s_dec_bits = b"1_101_0010011";
  162. s_is_add <= s_dec_bits = b"0_000_0110011";
  163. s_is_sub <= s_dec_bits = b"1_000_0110011";
  164. s_is_sll <= s_dec_bits = b"0_001_0110011";
  165. s_is_slt <= s_dec_bits = b"0_010_0110011";
  166. s_is_sltu <= s_dec_bits = b"0_011_0110011";
  167. s_is_xor <= s_dec_bits = b"0_100_0110011";
  168. s_is_srl <= s_dec_bits = b"0_101_0110011";
  169. s_is_sra <= s_dec_bits = b"1_101_0110011";
  170. s_is_or <= s_dec_bits = b"0_110_0110011";
  171. s_is_and <= s_dec_bits = b"0_111_0110011";
  172. -- LB, LH, LW, LBU, LHU
  173. s_is_load <= a_opcode = "0000011";
  174. -- SB, SH, SW
  175. s_is_store <= s_is_s_instr;
  176. -- Some subexpressions
  177. s_src_sgn_eq <= s_src1_value(31) = s_src2_value(31);
  178. s_imm_sgn_eq <= s_src1_value(31) = s_imm(31);
  179. -- SLTU & SLTI (set if less than, unsigned)
  180. s_sltu_rslt <= 31x"0" & to_std_logic(unsigned(s_src1_value) < unsigned(s_src2_value));
  181. s_sltiu_rslt <= 31x"0" & to_std_logic(unsigned(s_src1_value) < unsigned(s_imm));
  182. -- ALU
  183. s_result <=
  184. s_src1_value and s_imm when s_is_andi else
  185. s_src1_value or s_imm when s_is_ori else
  186. s_src1_value xor s_imm when s_is_xori else
  187. std_logic_vector(signed(s_src1_value) + signed(s_imm)) when s_is_addi or
  188. s_is_load or
  189. s_is_store else
  190. shift_left(s_src1_value, s_imm(5 downto 0)) when s_is_slli else
  191. shift_right(s_src1_value, s_imm(5 downto 0)) when s_is_srli else
  192. s_src1_value and s_src2_value when s_is_and else
  193. s_src1_value or s_src2_value when s_is_or else
  194. s_src1_value xor s_src2_value when s_is_xor else
  195. std_logic_vector(signed(s_src1_value) + signed(s_src2_value)) when s_is_add else
  196. std_logic_vector(signed(s_src1_value) - signed(s_src2_value)) when s_is_sub else
  197. shift_left(s_src1_value, s_src2_value(4 downto 0)) when s_is_sll else
  198. shift_right(s_src1_value, s_src2_value(4 downto 0)) when s_is_srl else
  199. s_sltu_rslt when s_is_sltu else
  200. s_sltiu_rslt when s_is_sltiu else
  201. s_imm(31 downto 12) & 12x"0" when s_is_lui else
  202. std_logic_vector(s_pc + unsigned(s_imm)) when s_is_auipc else
  203. std_logic_vector(s_pc + 4) when s_is_jal or
  204. s_is_jalr else
  205. s_sltu_rslt when s_is_slt and
  206. s_src_sgn_eq else
  207. 31x"0" & s_src1_value(31) when s_is_slt else
  208. s_sltiu_rslt when s_is_slti and
  209. s_imm_sgn_eq else
  210. 31x"0" & s_src1_value(31) when s_is_slti else
  211. shift_arith_right(s_src1_value, s_src2_value(4 downto 0)) when s_is_sra else
  212. shift_arith_right(s_src1_value, s_imm(4 downto 0)) when s_is_srai else
  213. 32x"0";
  214. -- Branch logic
  215. s_taken_br <= s_src1_value = s_src2_value when s_is_beq else
  216. s_src1_value /= s_src2_value when s_is_bne else
  217. signed(s_src1_value) < signed(s_src2_value) when s_is_blt else
  218. signed(s_src1_value) >= signed(s_src2_value) when s_is_bge else
  219. unsigned(s_src1_value) < unsigned(s_src2_value) when s_is_bltu else
  220. unsigned(s_src1_value) >= unsigned(s_src2_value) when s_is_bgeu else
  221. false;
  222. s_br_tgt_br <= s_pc + unsigned(s_imm);
  223. s_jalr_tgt_pc <= unsigned(s_src1_value) + unsigned(s_imm);
  224. -- Register file
  225. process (clk_i) is
  226. variable v_value : std_logic_vector(31 downto 0);
  227. begin
  228. if rising_edge(clk_i) then
  229. if reset_n_i = '0' then
  230. s_reg_file <= init_reg_file;
  231. elsif s_rd_valid and a_rd /= 5x"0" then
  232. v_value := std_logic_vector(s_ld_data) when s_is_load else s_result;
  233. s_reg_file(to_integer(unsigned(a_rd))) <= v_value;
  234. end if;
  235. end if;
  236. end process;
  237. s_src1_value <= s_reg_file(to_integer(unsigned(a_rs1))) when s_rs1_valid else
  238. (others => '0');
  239. s_src2_value <= s_reg_file(to_integer(unsigned(a_rs2))) when s_rs2_valid else
  240. (others => '0');
  241. -- Data memory
  242. process (clk_i) is
  243. begin
  244. if rising_edge(clk_i) then
  245. if reset_n_i = '0' then
  246. s_dmem <= init_dmem;
  247. elsif s_is_store then
  248. s_dmem(to_integer(unsigned(s_result(6 downto 2)))) <= std_logic_vector(s_src2_value);
  249. end if;
  250. end if;
  251. end process;
  252. s_ld_data <= s_dmem(to_integer(unsigned(s_result(6 downto 2)))) when s_is_load else
  253. (others => '0');
  254. end architecture rtl;