当前位置:   article > 正文

CPU设计实战:Loongarch版 lab6--20条指令单周期CPU_cpu设计实战loongarch版

cpu设计实战loongarch版

        本文章是为了记录学习Loongarch参加龙芯杯,所有实验均来自LoongarchCPU设计实验

        debug到一半才想起来写个博客,就不写过程了,下个lab再写过程。

        这个debug卡我时间最长的就是通用寄存器的写使能信号,当时一直没找到,甚至把golden—trace生成了一遍又一遍,对照test,检查了各种,卡了很长时间,我都以为是我之前哪一步搞错了,或者环境什么的,但是一步步做下来并没有,并且“机器永远是对的”让我终于查到了错。

        其他的bug就还好,如果认真跟着实验手册走,按逻辑检查并且查龙芯架构参考手册就能马上找出来,,上面的每一句话都很重要。

        下面是两个模块的代码,运行已通过仿真验证。

        mycpu_top 

  1. module mycpu_top(
  2. input wire clk,
  3. input wire resetn,
  4. // inst sram interface
  5. output wire inst_sram_we,
  6. output wire [31:0] inst_sram_addr,
  7. output wire [31:0] inst_sram_wdata,
  8. input wire [31:0] inst_sram_rdata,
  9. // data sram interface
  10. output wire data_sram_we,
  11. output wire [31:0] data_sram_addr,
  12. output wire [31:0] data_sram_wdata,
  13. input wire [31:0] data_sram_rdata,
  14. // trace debug interface
  15. output wire [31:0] debug_wb_pc,
  16. output wire [ 3:0] debug_wb_rf_we,
  17. output wire [ 4:0] debug_wb_rf_wnum,
  18. output wire [31:0] debug_wb_rf_wdata
  19. );
  20. reg reset;
  21. always @(posedge clk) reset <= ~resetn;
  22. reg valid;
  23. always @(posedge clk) begin
  24. if (reset) begin
  25. valid <= 1'b0;
  26. end
  27. else begin
  28. valid <= 1'b1;
  29. end
  30. end
  31. wire [31:0] seq_pc;
  32. wire [31:0] nextpc;
  33. wire br_taken;
  34. wire [31:0] br_target;
  35. wire [31:0] inst;
  36. reg [31:0] pc;
  37. wire [11:0] alu_op;
  38. wire load_op;
  39. wire src1_is_pc;
  40. wire src2_is_imm;
  41. wire res_from_mem;
  42. wire dst_is_r1;
  43. wire gr_we;
  44. wire mem_we;
  45. wire src_reg_is_rd;
  46. wire [4: 0] dest;
  47. wire [31:0] rj_value;
  48. wire [31:0] rkd_value;
  49. wire [31:0] imm;
  50. wire [31:0] br_offs;
  51. wire [31:0] jirl_offs;
  52. wire [ 5:0] op_31_26;
  53. wire [ 3:0] op_25_22;
  54. wire [ 1:0] op_21_20;
  55. wire [ 4:0] op_19_15;
  56. wire [ 4:0] rd;
  57. wire [ 4:0] rj;
  58. wire [ 4:0] rk;
  59. wire [11:0] i12;
  60. wire [19:0] i20;
  61. wire [15:0] i16;
  62. wire [25:0] i26;
  63. wire [63:0] op_31_26_d;
  64. wire [15:0] op_25_22_d;
  65. wire [ 3:0] op_21_20_d;
  66. wire [31:0] op_19_15_d;
  67. wire inst_add_w;
  68. wire inst_sub_w;
  69. wire inst_slt;
  70. wire inst_sltu;
  71. wire inst_nor;
  72. wire inst_and;
  73. wire inst_or;
  74. wire inst_xor;
  75. wire inst_slli_w;
  76. wire inst_srli_w;
  77. wire inst_srai_w;
  78. wire inst_addi_w;
  79. wire inst_ld_w;
  80. wire inst_st_w;
  81. wire inst_jirl;
  82. wire inst_b;
  83. wire inst_bl;
  84. wire inst_beq;
  85. wire inst_bne;
  86. wire inst_lu12i_w;
  87. wire need_ui5;
  88. wire need_si12;
  89. wire need_si16;
  90. wire need_si20;
  91. wire need_si26;
  92. wire src2_is_4;
  93. wire [ 4:0] rf_raddr1;
  94. wire [31:0] rf_rdata1;
  95. wire [ 4:0] rf_raddr2;
  96. wire [31:0] rf_rdata2;
  97. wire rf_we ;
  98. wire [ 4:0] rf_waddr;
  99. wire [31:0] rf_wdata;
  100. wire [31:0] alu_src1 ;
  101. wire [31:0] alu_src2 ;
  102. wire [31:0] alu_result ;
  103. wire [31:0] mem_result;
  104. wire [31:0] final_result;
  105. assign seq_pc = pc + 3'h4;
  106. assign nextpc = br_taken ? br_target : seq_pc;
  107. always @(posedge clk) begin
  108. if (reset) begin
  109. pc <= 32'h1bfffffc; //trick: to make nextpc be 0x1c000000 during reset
  110. end
  111. else begin
  112. pc <= nextpc;
  113. end
  114. end
  115. assign inst_sram_we = 1'b0;
  116. assign inst_sram_addr = pc;
  117. assign inst_sram_wdata = 32'b0;
  118. assign inst = inst_sram_rdata;
  119. assign op_31_26 = inst[31:26];
  120. assign op_25_22 = inst[25:22];
  121. assign op_21_20 = inst[21:20];
  122. assign op_19_15 = inst[19:15];
  123. assign rd = inst[ 4: 0];
  124. assign rj = inst[ 9: 5];
  125. assign rk = inst[14:10];
  126. assign i12 = inst[21:10];
  127. assign i20 = inst[24: 5];
  128. assign i16 = inst[25:10];
  129. assign i26 = {inst[ 9: 0], inst[25:10]};
  130. decoder_6_64 u_dec0(.in(op_31_26 ), .out(op_31_26_d ));
  131. decoder_4_16 u_dec1(.in(op_25_22 ), .out(op_25_22_d ));
  132. decoder_2_4 u_dec2(.in(op_21_20 ), .out(op_21_20_d ));
  133. decoder_5_32 u_dec3(.in(op_19_15 ), .out(op_19_15_d ));
  134. assign inst_add_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h00];
  135. assign inst_sub_w = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h02];
  136. assign inst_slt = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h04];
  137. assign inst_sltu = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h05];
  138. assign inst_nor = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h08];
  139. assign inst_and = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h09];
  140. assign inst_or = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0a];
  141. assign inst_xor = op_31_26_d[6'h00] & op_25_22_d[4'h0] & op_21_20_d[2'h1] & op_19_15_d[5'h0b];
  142. assign inst_slli_w = op_31_26_d[6'h00] & op_25_22_d[4'h1] & op_21_20_d[2'h0] & op_19_15_d[5'h01];
  143. assign inst_srli_w = op_31_26_d[6'h00] & op_25_22_d[4'h1] & op_21_20_d[2'h0] & op_19_15_d[5'h09];
  144. assign inst_srai_w = op_31_26_d[6'h00] & op_25_22_d[4'h1] & op_21_20_d[2'h0] & op_19_15_d[5'h11];
  145. assign inst_addi_w = op_31_26_d[6'h00] & op_25_22_d[4'ha];
  146. assign inst_ld_w = op_31_26_d[6'h0a] & op_25_22_d[4'h2];
  147. assign inst_st_w = op_31_26_d[6'h0a] & op_25_22_d[4'h6];
  148. assign inst_jirl = op_31_26_d[6'h13];
  149. assign inst_b = op_31_26_d[6'h14];
  150. assign inst_bl = op_31_26_d[6'h15];
  151. assign inst_beq = op_31_26_d[6'h16];
  152. assign inst_bne = op_31_26_d[6'h17];
  153. assign inst_lu12i_w= op_31_26_d[6'h05] & ~inst[25];
  154. assign alu_op[ 0] = inst_add_w | inst_addi_w | inst_ld_w | inst_st_w
  155. | inst_jirl | inst_bl;
  156. assign alu_op[ 1] = inst_sub_w;
  157. assign alu_op[ 2] = inst_slt;
  158. assign alu_op[ 3] = inst_sltu;
  159. assign alu_op[ 4] = inst_and;
  160. assign alu_op[ 5] = inst_nor;
  161. assign alu_op[ 6] = inst_or;
  162. assign alu_op[ 7] = inst_xor;
  163. assign alu_op[ 8] = inst_slli_w;
  164. assign alu_op[ 9] = inst_srli_w;
  165. assign alu_op[10] = inst_srai_w;
  166. assign alu_op[11] = inst_lu12i_w;
  167. assign need_ui5 = inst_slli_w | inst_srli_w | inst_srai_w;
  168. assign need_si12 = inst_addi_w | inst_ld_w | inst_st_w;
  169. assign need_si16 = inst_jirl | inst_beq | inst_bne;
  170. assign need_si20 = inst_lu12i_w;
  171. assign need_si26 = inst_b | inst_bl;
  172. assign src2_is_4 = inst_jirl | inst_bl;
  173. assign imm = src2_is_4 ? 32'h4 :
  174. need_si20 ? {i20[19:0], 12'b0} :
  175. /*need_ui5 || need_si12*/{{20{i12[11]}}, i12[11:0]} ;
  176. assign br_offs = need_si26 ? {{ 4{i26[25]}}, i26[25:0], 2'b0} :
  177. {{14{i16[15]}}, i16[15:0], 2'b0} ;
  178. assign jirl_offs = {{14{i16[15]}}, i16[15:0], 2'b0};
  179. assign src_reg_is_rd = inst_beq | inst_bne | inst_st_w;
  180. assign src1_is_pc = inst_jirl | inst_bl;
  181. assign src2_is_imm = inst_slli_w |
  182. inst_srli_w |
  183. inst_srai_w |
  184. inst_addi_w |
  185. inst_ld_w |
  186. inst_st_w |
  187. inst_lu12i_w|
  188. inst_jirl |
  189. inst_bl ;
  190. assign res_from_mem = inst_ld_w;
  191. assign dst_is_r1 = inst_bl;
  192. assign gr_we = ~inst_st_w & ~inst_beq & ~inst_bne & ~inst_b;
  193. assign mem_we = inst_st_w;
  194. assign dest = dst_is_r1 ? 5'd1 : rd;
  195. assign rf_raddr1 = rj;
  196. assign rf_raddr2 = src_reg_is_rd ? rd :rk;
  197. regfile u_regfile(
  198. .clk (clk ),
  199. .raddr1 (rf_raddr1),
  200. .rdata1 (rf_rdata1),
  201. .raddr2 (rf_raddr2),
  202. .rdata2 (rf_rdata2),
  203. .we (rf_we ),
  204. .waddr (rf_waddr ),
  205. .wdata (rf_wdata )
  206. );
  207. assign rj_value = rf_rdata1;
  208. assign rkd_value = rf_rdata2;
  209. assign rj_eq_rd = (rj_value == rkd_value);
  210. assign br_taken = ( inst_beq && rj_eq_rd
  211. || inst_bne && !rj_eq_rd
  212. || inst_jirl
  213. || inst_bl
  214. || inst_b
  215. ) && valid;
  216. assign br_target = (inst_beq || inst_bne || inst_bl || inst_b) ? (pc + br_offs) :
  217. /*inst_jirl*/ (rj_value + jirl_offs);
  218. assign alu_src1 = src1_is_pc ? pc[31:0] : rj_value;
  219. assign alu_src2 = src2_is_imm ? imm : (inst_bl ? 32'd4 : rkd_value);
  220. alu u_alu(
  221. .alu_op (alu_op ),
  222. .alu_src1 (alu_src1 ),
  223. .alu_src2 (alu_src2 ),
  224. .alu_result (alu_result)
  225. );
  226. assign data_sram_we = mem_we && valid;
  227. assign data_sram_addr = alu_result;
  228. assign data_sram_wdata = rkd_value;
  229. assign mem_result = data_sram_rdata;
  230. assign final_result = res_from_mem ? mem_result : alu_result;
  231. assign rf_we = gr_we && valid;
  232. assign rf_waddr = dest;
  233. assign rf_wdata = final_result;
  234. // debug info generate
  235. assign debug_wb_pc = rf_we ? pc : debug_wb_pc;
  236. assign debug_wb_rf_we = {4{rf_we}};
  237. assign debug_wb_rf_wnum = rf_we ? dest : debug_wb_rf_wnum;
  238. assign debug_wb_rf_wdata = rf_we ? final_result : debug_wb_rf_wdata;
  239. endmodule

        alu

  1. module alu(
  2. input wire [11:0] alu_op,
  3. input wire [31:0] alu_src1,
  4. input wire [31:0] alu_src2,
  5. output wire [31:0] alu_result
  6. );
  7. wire op_add; //add operation
  8. wire op_sub; //sub operation
  9. wire op_slt; //signed compared and set less than
  10. wire op_sltu; //unsigned compared and set less than
  11. wire op_and; //bitwise and
  12. wire op_nor; //bitwise nor
  13. wire op_or; //bitwise or
  14. wire op_xor; //bitwise xor
  15. wire op_sll; //logic left shift
  16. wire op_srl; //logic right shift
  17. wire op_sra; //arithmetic right shift
  18. wire op_lui; //Load Upper Immediate
  19. // control code decomposition
  20. assign op_add = alu_op[ 0];
  21. assign op_sub = alu_op[ 1];
  22. assign op_slt = alu_op[ 2];
  23. assign op_sltu = alu_op[ 3];
  24. assign op_and = alu_op[ 4];
  25. assign op_nor = alu_op[ 5];
  26. assign op_or = alu_op[ 6];
  27. assign op_xor = alu_op[ 7];
  28. assign op_sll = alu_op[ 8];
  29. assign op_srl = alu_op[ 9];
  30. assign op_sra = alu_op[10];
  31. assign op_lui = alu_op[11];
  32. wire [31:0] add_sub_result;
  33. wire [31:0] slt_result;
  34. wire [31:0] sltu_result;
  35. wire [31:0] and_result;
  36. wire [31:0] nor_result;
  37. wire [31:0] or_result;
  38. wire [31:0] xor_result;
  39. wire [31:0] lui_result;
  40. wire [31:0] sll_result;
  41. wire [63:0] sr64_result;
  42. wire [31:0] sr_result;
  43. // 32-bit adder
  44. wire [31:0] adder_a;
  45. wire [31:0] adder_b;
  46. wire adder_cin;
  47. wire [31:0] adder_result;
  48. wire adder_cout;
  49. assign adder_a = alu_src1;
  50. assign adder_b = (op_sub | op_slt | op_sltu) ? ~alu_src2 : alu_src2; //src1 - src2 rj-rk
  51. assign adder_cin = (op_sub | op_slt | op_sltu) ? 1'b1 : 1'b0;
  52. assign {adder_cout, adder_result} = adder_a + adder_b + adder_cin;
  53. // ADD, SUB result
  54. assign add_sub_result = adder_result;
  55. // SLT result
  56. assign slt_result[31:1] = 31'b0; //rj < rk 1
  57. assign slt_result[0] = (alu_src1[31] & ~alu_src2[31])
  58. | ((alu_src1[31] ~^ alu_src2[31]) & adder_result[31]);
  59. // SLTU result
  60. assign sltu_result[31:1] = 31'b0;
  61. assign sltu_result[0] = ~adder_cout;
  62. // bitwise operation
  63. assign and_result = alu_src1 & alu_src2;
  64. assign or_result = alu_src1 | alu_src2;
  65. assign nor_result = ~or_result;
  66. assign xor_result = alu_src1 ^ alu_src2;
  67. assign lui_result = alu_src2;
  68. // SLL result
  69. assign sll_result = alu_src1 << alu_src2[4:0]; //rj << i5
  70. // SRL, SRA result
  71. assign sr64_result = {{32{op_sra & alu_src1[31]}}, alu_src1[31:0]} >> alu_src2[4:0]; //rj >> i5
  72. assign sr_result = sr64_result[31:0];
  73. // final result mux
  74. assign alu_result = ({32{op_add|op_sub}} & add_sub_result)
  75. | ({32{op_slt }} & slt_result)
  76. | ({32{op_sltu }} & sltu_result)
  77. | ({32{op_and }} & and_result)
  78. | ({32{op_nor }} & nor_result)
  79. | ({32{op_or }} & or_result)
  80. | ({32{op_xor }} & xor_result)
  81. | ({32{op_lui }} & lui_result)
  82. | ({32{op_sll }} & sll_result)
  83. | ({32{op_srl|op_sra}} & sr_result);
  84. endmodule

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/941982
推荐阅读
相关标签
  

闽ICP备14008679号