datapath.sv 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import risc_pkg::*;
  2. import alu_pkg::*;
  3. module datapath(clk, rst, rd, rs, imm, alu_op, alu_ex, reg_wr, pc_src,
  4. rimm, alu_src, mem_to_reg, pc, alu_out, mem_data, alu_zero,
  5. mem_wr_data, sp_wr, mem_sp);
  6. input logic clk, rst, reg_wr, pc_src, rimm, mem_to_reg, alu_src;
  7. input e_reg rd, rs;
  8. input e_alu_op alu_op;
  9. input e_alu_ext_op alu_ex;
  10. input word imm, mem_data;
  11. input logic sp_wr, mem_sp;
  12. output word pc, alu_out, mem_wr_data;
  13. output logic alu_zero;
  14. word sp, sp_next;
  15. // Reg File
  16. word reg_rd_d1, reg_rd_d2, reg_wr_d;
  17. e_reg reg_rd_a1, reg_rd_a2, reg_wr_a;
  18. assign reg_rd_a1 = rd;
  19. assign reg_rd_a2 = rs;
  20. assign reg_wr_a = rd;
  21. assign reg_wr_d = (mem_to_reg) ? mem_data : alu_out;
  22. reg_file RFILE(clk, rst, reg_rd_a1, reg_rd_a2, reg_rd_d1, reg_rd_d2, reg_wr_a, reg_wr_d, reg_wr);
  23. // Mem output data
  24. assign mem_wr_data = reg_rd_d1;
  25. // ALU
  26. word alu_srcA, alu_srcB;
  27. word alu_result;
  28. assign alu_srcA = reg_rd_d1;
  29. assign alu_srcB = alu_src ? imm : reg_rd_d2;
  30. word sp_sel;
  31. assign sp_sel = (mem_sp) ? sp_next : sp;
  32. assign alu_out = (sp_wr) ? sp_sel : alu_result;
  33. alu#(.WORD(8)) alu0(
  34. .a(alu_srcA),
  35. .b(alu_srcB),
  36. .op(alu_op),
  37. .r(alu_result),
  38. .zero(alu_zero)
  39. );
  40. //alu_op, alu_ex, alu_srcA, alu_srcB, alu_result, alu_zero);
  41. // Program counter
  42. word pcn; // PC next
  43. word pcj; // PC jump, +2 if imm used otherwise +1
  44. logic [0:1]pcadd;
  45. assign pcadd = (rimm) ? 2 : 1;
  46. assign pcj = pc + pcadd;
  47. //assign pcj = pc + 1;
  48. assign pcn = (pc_src) ? imm : pcj;
  49. always_ff@(posedge clk) begin
  50. if (rst) pc <= 0;
  51. else pc <= pcn;
  52. end
  53. always_ff@(posedge clk) begin
  54. if (rst) sp <= 8'hff;
  55. if (sp_wr) sp <= sp_next;
  56. end
  57. // Optimise this
  58. assign sp_next = (mem_sp) ? sp + 1 : sp - 1;
  59. endmodule
  60. module datapath_tb;
  61. logic clk, rst, reg_wr, pc_src, rimm, mem_to_reg, alu_zero;
  62. e_reg rs, rt;
  63. e_alu_op alu_op;
  64. word imm, mem_data, pc, alu_out;
  65. datapath DPATH(clk, rst, rs, rt, imm, alu_op, reg_wr, pc_src, rimm, mem_to_reg, pc, alu_out, mem_data, alu_zero);
  66. initial begin
  67. clk = 0;
  68. forever #5ns clk = ~clk;
  69. end
  70. initial begin
  71. rst = 1;
  72. reg_wr = 0;
  73. pc_src = 0;
  74. rimm = 0;
  75. mem_to_reg = 0;
  76. rs = ra;
  77. rt = ra;
  78. //alu_op = ALU_CPY;
  79. imm = 8'h00;
  80. mem_data = 8'h00;
  81. #10ns;
  82. rst = 0;
  83. reg_wr = 1;
  84. mem_to_reg = 1;
  85. mem_data = 8'h7A;
  86. #10ns;
  87. rs = rb;
  88. mem_data = 8'h8A;
  89. #10ns;
  90. rs = rc;
  91. mem_data = 8'h9A;
  92. #10ns;
  93. rs = re;
  94. mem_data = 8'hFD;
  95. #10ns;
  96. rs = ra;
  97. #10ns;
  98. $stop;
  99. end
  100. endmodule