exec.vhd 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. use work.core_pkg.all;
  5. use work.op_pkg.all;
  6. entity exec is
  7. port (
  8. clk : in std_logic;
  9. res_n : in std_logic;
  10. stall : in std_logic;
  11. flush : in std_logic;
  12. -- from DEC
  13. op : in exec_op_type;
  14. pc_in : in pc_type;
  15. -- to MEM
  16. pc_old_out : out pc_type;
  17. pc_new_out : out pc_type;
  18. aluresult : out data_type;
  19. wrdata : out data_type;
  20. zero : out std_logic;
  21. memop_in : in mem_op_type;
  22. memop_out : out mem_op_type;
  23. wbop_in : in wb_op_type;
  24. wbop_out : out wb_op_type;
  25. -- FWD
  26. exec_op : out exec_op_type;
  27. reg_write_mem : in reg_write_type;
  28. reg_write_wr : in reg_write_type
  29. );
  30. end entity;
  31. architecture rtl of exec is
  32. type alu_t is record
  33. op : alu_op_type;
  34. A : data_type;
  35. B : data_type;
  36. end record;
  37. constant INITIAL_ALU : alu_t := (
  38. op => ALU_NOP,
  39. A => (others => '0'),
  40. B => (others => '0')
  41. );
  42. type internal_t is record
  43. op : exec_op_type;
  44. pc : pc_type;
  45. memop : mem_op_type;
  46. wbop : wb_op_type;
  47. end record;
  48. constant INITIAL_INTERNAL : internal_t := (
  49. pc => (others => '0'),
  50. op => EXEC_NOP,
  51. memop => MEM_NOP,
  52. wbop => WB_NOP
  53. );
  54. signal internal : internal_t;
  55. signal int_alu : alu_t;
  56. signal pc_a, pc_b : pc_type;
  57. signal do_fwd_A, do_fwd_B : std_logic;
  58. signal fwd_val_A, fwd_val_B : data_type;
  59. signal rs1_data, rs2_data : data_type;
  60. begin
  61. -- structural
  62. alu_inst : entity work.alu
  63. port map (
  64. op => int_alu.op,
  65. A => int_alu.A,
  66. B => int_alu.B,
  67. R => aluresult,
  68. Z => zero
  69. );
  70. -- sequential
  71. sync : process(clk, res_n, flush, stall)
  72. begin
  73. if res_n = '0' then
  74. internal <= INITIAL_INTERNAL;
  75. elsif stall = '0' and rising_edge(clk) then
  76. internal.pc <= pc_in;
  77. internal.op <= op;
  78. internal.memop <= memop_in;
  79. internal.wbop <= wbop_in;
  80. end if;
  81. end process;
  82. -- FWD
  83. fwd_A_inst : entity work.fwd
  84. port map (
  85. reg_write_mem => reg_write_mem,
  86. reg_write_wb => reg_write_wr,
  87. reg => internal.op.rs1,
  88. val => fwd_val_A,
  89. do_fwd => do_fwd_A
  90. );
  91. fwd_B_inst : entity work.fwd
  92. port map (
  93. reg_write_mem => reg_write_mem,
  94. reg_write_wb => reg_write_wr,
  95. reg => internal.op.rs2,
  96. val => fwd_val_B,
  97. do_fwd => do_fwd_B
  98. );
  99. -- concurrent
  100. rs1_data <= fwd_val_A when do_fwd_A = '1' else internal.op.readdata1;
  101. rs2_data <= fwd_val_B when do_fwd_B = '1' else internal.op.readdata2;
  102. int_alu.op <= internal.op.aluop;
  103. int_alu.A <= x"0000" & internal.pc when internal.op.alusrc1 /= '0' else rs1_data;
  104. int_alu.B <= internal.op.imm when internal.op.alusrc2 /= '0' else rs2_data;
  105. pc_old_out <= internal.pc;
  106. pc_a <= internal.op.readdata1(15 downto 0) when (internal.op.alusrc1 and internal.op.alusrc2 and internal.op.alusrc3) = '1' else internal.pc; --case for JALR
  107. pc_b <= internal.op.imm(pc_type'RANGE) when internal.op.alusrc3 = '1' else (others => '0');
  108. pc_new_out <= std_logic_vector(signed(pc_a) + signed(pc_b));
  109. wrdata <= rs2_data;
  110. memop_out <= internal.memop when flush = '0' else MEM_NOP;
  111. wbop_out <= internal.wbop when flush = '0' else WB_NOP;
  112. exec_op <= internal.op;
  113. end architecture;