当前位置:   article > 正文

单周期CPU(三)译码模块(minisys)(verilog)(vivado)

单周期CPU(三)译码模块(minisys)(verilog)(vivado)
  1. `timescale 1ns / 1ps
  2. //
  3. module Idecode32 (
  4. input reset,
  5. input clock,
  6. output [31:0] read_data_1, // 输出的第一操作数
  7. output [31:0] read_data_2, // 输出的第二操作数
  8. input [31:0] Instruction, // 取指单元来的指令
  9. input [31:0] read_data, //DATA RAM or I/O port取出的数据
  10. input [31:0] ALU_result, // 从执行单元来的运算的结果,需要扩展立即数到32
  11. input Jal, // 来自控制单元,说明是JAL指令
  12. input RegWrite, // 来自控制单元
  13. input MemtoReg, // 来自控制单元
  14. input RegDst, // 来自控制单元
  15. output [31:0] Sign_extend, // 译码单元输出的扩展后的32位立即数
  16. input [31:0] opcplus4 // 来自取指单元,JAL中用
  17. );
  18. reg[31:0] register[0:31]; // 寄存器组共3232位寄存器
  19. reg[4:0] write_register_address; // 要写的寄存器的号
  20. reg[31:0] write_data; // 要写寄存器的数据放这里
  21. wire[4:0] read_register_1_address; // 要读的第一个寄存器的号(rs)
  22. wire[4:0] read_register_2_address; // 要读的第二个寄存器的号(rt)
  23. wire[4:0] write_register_address_1; // r-form指令要写的寄存器的号(rd
  24. wire[4:0] write_register_address_0; // i-form指令要写的寄存器的号(rt)
  25. wire[15:0] Instruction_immediate_value; // 指令中的立即数
  26. wire[5:0] opcode; // 指令码
  27. assign opcode = Instruction[31:26]; // OP
  28. assign read_register_1_address = Instruction[25:21]; // rs
  29. assign read_register_2_address = Instruction[20:16]; // rt
  30. assign write_register_address_1 = Instruction[15:11]; // rd (r-form)
  31. assign write_register_address_0 = Instruction[20:16]; // rt (i-form)
  32. assign Instruction_immediate_value = Instruction[15:0]; // data, rladr (i-form)
  33. wire sign; // 取符号位的值
  34. assign sign = Instruction[15]; // 取指令的第15位作为符号位
  35. assign Sign_extend[31:16] = (sign) ? {16{1'b1}} : {16{1'b0}}; // 符号扩展,根据符号位填充高位
  36. assign Sign_extend[15:0] = Instruction[15:0]; // 将原始的16位立即数填充到低位
  37. assign read_data_1 = register[read_register_1_address]; // 从寄存器组中读取第一个源寄存器的数据
  38. assign read_data_2 = register[read_register_2_address]; // 从寄存器组中读取第二个源寄存器的数据
  39. always @* begin
  40. if (Jal) begin
  41. write_register_address = 5'b11111; // JAL指令的目标寄存器是31号寄存器
  42. end else begin
  43. if (RegDst) begin
  44. write_register_address = write_register_address_1; // r-form指令的目标寄存器地址
  45. end else begin
  46. write_register_address = write_register_address_0; // i-form指令的目标寄存器地址
  47. end
  48. end
  49. end
  50. always @* begin
  51. if (MemtoReg) begin
  52. write_data = read_data; // 数据来自数据RAM的输出
  53. end else begin
  54. write_data = ALU_result; // 运算指令的数据来自ALU_result
  55. end
  56. end
  57. integer i;
  58. always @(posedge clock) begin
  59. if (reset == 1) begin
  60. for (i = 0; i < 32; i = i + 1)
  61. register[i] <= 0; // 初始化寄存器组,将所有寄存器清零
  62. end else if (RegWrite == 1) begin
  63. if (write_register_address != 5'b00000) begin
  64. register[write_register_address] <= write_data; // 写入数据到目标寄存器,除了0号寄存器
  65. end
  66. end
  67. end
  68. endmodule

仿真代码如下

  1. `timescale 1ns / 1ps
  2. //
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date:
  7. // Design Name:
  8. // Module Name: idcode32_sim
  9. // Project Name:
  10. // Target Devices:
  11. // Tool Versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //
  21. module idcode32_sim ();
  22. // input
  23. reg[31:0] Instruction = 32'b000000_00010_00011_00111_00000_100000; //add $7,$2,$3
  24. reg[31:0] read_data = 32'h00000000; //DATA RAM or I/O port取出的数据
  25. reg[31:0] ALU_result = 32'h00000005; // 需要扩展立即数到32位
  26. reg Jal = 1'b0;
  27. reg RegWrite = 1'b1;
  28. reg MemtoReg = 1'b0;
  29. reg RegDst = 1'b1;
  30. reg clock = 1'b0 ,reset = 1'b1;
  31. reg[31:0] opcplus4 = 32'h00000004; // 来自取指单元,JAL中用
  32. // output
  33. wire[31:0] read_data_1;
  34. wire[31:0] read_data_2;
  35. wire[31:0] Sign_extend;
  36. Idecode32 Uid (
  37. .reset (reset), // 复位(高电平有效)
  38. .clock (clock), // CPU时钟
  39. .read_data_1 (read_data_1), // 输出的第一操作数
  40. .read_data_2 (read_data_2), // 输出的第二操作数
  41. .Instruction (Instruction), // 取指单元来的指令
  42. .read_data (read_data), //DATA RAM or I/O port取出的数据
  43. .ALU_result (ALU_result), // 从执行单元来的运算的结果,需要扩展立即数到32
  44. .Jal (Jal), // 来自控制单元,说明是JAL指令
  45. .RegWrite (RegWrite), // 来自控制单元
  46. .MemtoReg (MemtoReg), // 来自控制单元
  47. .RegDst (RegDst), // 来自控制单元
  48. .Sign_extend (Sign_extend), // 扩展后的32位立即数
  49. .opcplus4 (opcplus4) // 来自取指单元,JAL中用
  50. );
  51. initial begin
  52. #200 reset = 1'b0;
  53. #200 begin Instruction = 32'b001000_00111_00011_1000000000110111; //addi $3,$7,0X8037
  54. read_data = 32'h00000000;
  55. ALU_result = 32'hFFFF803C;
  56. Jal = 1'b0;
  57. RegWrite = 1'b1;
  58. MemtoReg = 1'b0;
  59. RegDst = 1'b0;
  60. opcplus4 = 32'h00000008;
  61. end
  62. #200 begin Instruction = 32'b001100_00010_00100_1000000010010111; //andi $4,$2,0X8097
  63. read_data = 32'h00000000;
  64. ALU_result = 32'h00000002;
  65. Jal = 1'b0;
  66. RegWrite = 1'b1;
  67. MemtoReg = 1'b0;
  68. RegDst = 1'b0;
  69. opcplus4 = 32'h0000000c;
  70. end
  71. #200 begin Instruction = 32'b000000_00000_00001_00101_00010_000000; //sll $5,$1,2
  72. read_data = 32'h00000000;
  73. ALU_result = 32'h00000004;
  74. Jal = 1'b0;
  75. RegWrite = 1'b1;
  76. MemtoReg = 1'b0;
  77. RegDst = 1'b1;
  78. opcplus4 = 32'h00000010;
  79. end
  80. #200 begin Instruction = 32'b100011_00000_00110_0000000100000000; //LW $6,0(0X100)
  81. read_data = 32'h0000007B;
  82. ALU_result = 32'h00000054;
  83. Jal = 1'b0;
  84. RegWrite = 1'b1;
  85. MemtoReg = 1'b1;
  86. RegDst = 1'b0;
  87. opcplus4 = 32'h00000014;
  88. end
  89. #200 begin Instruction = 32'b000011_00000000000000000000000000; //JAL 0000
  90. read_data = 32'h00000000;
  91. ALU_result = 32'h00000004;
  92. Jal = 1'b1;
  93. RegWrite = 1'b1;
  94. MemtoReg = 1'b0;
  95. RegDst = 1'b0;
  96. opcplus4 = 32'h00000018;
  97. end
  98. end
  99. always #50 clock = ~clock;
  100. endmodule

仿真波形图如下图

 

 

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号