~ruther/verilog-riscv-semestral-project

ref: 8f631f51a777c2aa139b677706608f2189c091a3 verilog-riscv-semestral-project/src/cpu.sv -rwxr-xr-x 3.0 KiB
8f631f51 — Rutherther refactor: move memory out of cpu 1 year, 5 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import cpu_types::*;

module cpu(
  input             clk,
  input             rst_n,

  // program memory
  input [31:0]      instruction,
  output reg [31:0] pc,

  // ram
  input [31:0]      memory_address,
  input [31:0]      memory_out,
  output reg [31:0] memory_write,
  output reg        memory_we
);
  parameter WIDTH = 32;

  wire [31:0] instruction;

  reg [31:0]  pc_next;
  wire [31:0] pc;
  wire        pc_src;

  reg [31:0]  alu_1, alu_2;
  wire        alu_1_src, alu_2_src;

  wire [2:0]  alu_op;
  wire        alu_add_one, alu_negate, alu_signed;
  wire        alu_zero;
  wire [31:0] alu_out;

  wire [4:0]  reg_a_1, reg_a_2, reg_a_w;
  wire [31:0] reg_rd1, reg_rd2;
  reg [31:0]  reg_write;
  wire [1:0]  reg_write_src;
  wire        reg_we;

  wire [31:0] immediate;

  wire        jump_instruction, jump_negate_zero;
  wire        jump_taken;

  assign memory_write = reg_rd2;
  assign memory_address = alu_out;

  // alu source 1
  always_comb begin
    case (alu_1_src)
      REG_FILE_RS1 : alu_1 = reg_rd1;
      PC : alu_1 = pc;
    endcase
  end

  // alu source 2
  always_comb begin
    case (alu_2_src)
      REG_FILE_RS2 : alu_2 = reg_rd2;
      IMMEDIATE : alu_2 = immediate;
    endcase
  end

  // pc source
  assign jump_taken = jump_instruction && (alu_out[0] ^ jump_negate_zero);
  always_comb begin
    case (pc_src)
      PC_PLUS : begin
        if (jump_taken)
          pc_next = pc + immediate;
        else
          pc_next = pc + 4;
      end
      PC_ALU : pc_next = alu_out;
    endcase
  end

  // register file write source
  always_comb begin
    case (reg_write_src)
      RD_ALU : reg_write = alu_out;
      RD_PC_PLUS : reg_write = pc + 4;
      RD_MEMORY : reg_write = memory_out;
      default : ;
    endcase
  end

  control_unit control_unit_inst(
    .instruction(instruction),

    .immediate(immediate),

    .alu_op(alu_op),
    .alu_add_one(alu_add_one),
    .alu_negate(alu_negate),
    .alu_signed(alu_signed),

    .memory_we(memory_we),

    .jump_instruction(jump_instruction),
    .jump_negate_zero(jump_negate_zero),

    .pc_src(pc_src),
    .alu_src_1(alu_1_src),
    .alu_src_2(alu_2_src),
    .reg_rd_src(reg_write_src),

    .reg_rs1(reg_a_1),
    .reg_rs2(reg_a_2),
    .reg_rd(reg_a_w),
    .reg_we(reg_we)
  );

  alu #(.WIDTH(WIDTH)) alu_inst(
    .a(alu_1),
    .b(alu_2),

    .out(alu_out),

    .op(alu_op),
    .b_add_one(alu_add_one),
    .b_negate(alu_negate),
    .sign(alu_signed),
    .zero_flag(alu_zero)
  );

  register_file #(.WIDTH(WIDTH), .ADDRESS_LENGTH(5)) register_file_inst(
    .clk(clk),
    .a1(reg_a_1),
    .a2(reg_a_2),
    .a3(reg_a_w),
    .we3(reg_we),
    .wd3(reg_write),
    .rd1(reg_rd1),
    .rd2(reg_rd2)
  );

  program_counter program_counter_inst(
    .clk(clk),
    .rst_n(rst_n),
    .pc(pc[11:0]),
    .pc_next(pc_next[11:0])
  );

  // program_memory program_memory_inst(
  //   .addr(pc[11:0]),
  //   .instruction(instruction)
  // );

  // ram memory_inst(
  //   .clk(clk),
  //   .a(memory_address),
  //   .we(memory_we),
  //   .wd(memory_write),
  //   .rd(memory_out)
  // );
endmodule
Do not follow this link