발표시간 10~15분, 기본은 10분 systemverilog verification하면 20분

개인으로 발표

ppt 20장 내외

예시

image.png

image.png

image.png

I type 마저 완성하기

image.png

Byte ram 기반 코드

module data_mem (
    input  logic         clk,
    input  logic         d_wr_en,
    input  logic [31:0]  dAddr,    // 바이트 주소 (0~63)
    input  logic [31:0]  dWdata,
    input  logic [2:0]   funct3,
    output logic [31:0]  dRdata
);
    // 64개의 바이트로 구성된 메모리 (16워드 * 4바이트/워드)
    logic [7:0] data_memory[0:63];

    // --- 메모리 초기화 ---
    initial begin
        for(int i = 0; i < 16; i++) begin
            data_memory[i*4 + 0] = (i + 32'h8765_4321)[7:0];
            data_memory[i*4 + 1] = (i + 32'h8765_4321)[15:8];
            data_memory[i*4 + 2] = (i + 32'h8765_4321)[23:16];
            data_memory[i*4 + 3] = (i + 32'h8765_4321)[31:24];
        end
    end

    // --- 읽기 로직 (Load) ---
    always_comb begin
        dRdata = 32'bx; // 래치 방지를 위한 기본값
        case (funct3)
            // lb: 해당 주소의 1바이트를 읽어 부호 확장
            3'b000: dRdata = { {24{data_memory[dAddr][7]}}, data_memory[dAddr] };
            
            // lh: 해당 주소부터 2바이트를 읽어 부호 확장
            3'b001: dRdata = { {16{data_memory[dAddr+1][7]}}, data_memory[dAddr+1], data_memory[dAddr] };

            // lw: 해당 주소부터 4바이트를 읽어 워드로 조합
            3'b010: dRdata = { data_memory[dAddr+3], data_memory[dAddr+2], data_memory[dAddr+1], data_memory[dAddr] };

            // lbu: 해당 주소의 1바이트를 읽어 0으로 확장
            3'b100: dRdata = { 24'b0, data_memory[dAddr] };

            // lhu: 해당 주소부터 2바이트를 읽어 0으로 확장
            3'b101: dRdata = { 16'b0, data_memory[dAddr+1], data_memory[dAddr] };
            
            default: dRdata = 32'bx;
        endcase
    end

    // --- 쓰기 로직 (Store) ---
    always_ff @(posedge clk) begin
        if (d_wr_en) begin
            case (funct3)
                // sb: dWdata의 최하위 1바이트를 해당 주소에 씀
                3'b000: data_memory[dAddr] <= dWdata[7:0];
                
                // sh: dWdata의 하위 2바이트를 해당 주소부터 차례로 씀
                3'b001: begin
                    data_memory[dAddr]   <= dWdata[7:0];
                    data_memory[dAddr+1] <= dWdata[15:8];
                end
                
                // sw: dWdata의 4바이트를 해당 주소부터 차례로 씀
                3'b010: begin
                    data_memory[dAddr]   <= dWdata[7:0];
                    data_memory[dAddr+1] <= dWdata[15:8];
                    data_memory[dAddr+2] <= dWdata[23:16];
                    data_memory[dAddr+3] <= dWdata[31:24];
                end
            endcase
        end
    end

endmodule

Control Unit code

`timescale 1ns / 1ps
`include "./define.sv"

module control_unit (
    input  logic [31:0] instr_code,
    output logic        reg_wr_en,
    output logic        aluSrcMuxSel,
    output logic        RegWdataSel,
    output logic [ 3:0] alu_controls,
    output logic        d_wr_en
);

    logic [6:0] funct7; 
    logic [2:0] funct3; 
    logic [6:0] opcode; 

    assign funct7 = instr_code[31:25];
    assign funct3 = instr_code[14:12];
    assign opcode = instr_code[6:0];

    logic [3:0] controls;
    assign {RegWdataSel,aluSrcMuxSel, reg_wr_en, d_wr_en} = controls;

    always_comb begin
        case(opcode)
            `OP_R_TYPE: begin // R-type
                controls = 4'b0010;
            end
            `OP_S_TYPE: begin
                controls = 4'b0101;
            end
            `OP_IL_TYPE: controls = 4'b1110;
            `OP_I_TYPE: controls = 4'b0110;
            default : controls = 4'b0000;
        endcase
    end

    always_comb begin
        case (opcode)
            `OP_R_TYPE:  alu_controls = {funct7[5], funct3};
            `OP_S_TYPE:  alu_controls = `ADD;
            `OP_IL_TYPE: alu_controls = `ADD;
            `OP_I_TYPE: begin
                // Shift 명령어(slli, srli, srai)는 funct7 추가 정보 필요
                if (funct3 == 3'b001 || funct3 == 3'b101) begin
                    alu_controls = {funct7[5], funct3};
                end else begin
                    alu_controls = {1'b0, funct3}; // 나머지 I-type 연산
                end
            end
            default: alu_controls = 4'bx;
        endcase
    end

endmodule

RV32I - B type

define.sv

`define ADD 4'b0000
`define SUB 4'b1000
`define SLL 4'b0001
`define SRL 4'b0101
`define SRA 4'b1101
`define SLT 4'b0010
`define SLTU 4'b0011
`define XOR 4'b0100
`define OR 4'b0110
`define AND 4'b0111

`define BEQ 3'b000
`define BNE 3'b001
`define BLT 3'b100
`define BGE 3'b101
`define BLTU 3'b110
`define BGEU 3'b111

// Opcode
`define OP_R_TYPE   7'b0110011 // R-type (add, sub, ...)
`define OP_S_TYPE 7'b0100011
`define OP_I_TYPE 7'b0010011
`define OP_IL_TYPE 7'b0000011
`define OP_B_TYPE   7'b1100011 // B-type (beq, bne, ...)

extend module

module extend (
    input  logic [31:0] instr_code,
    output logic [31:0] imm_Ext
);

    wire [6:0] opcode = instr_code[6:0];
    wire [2:0] funct3 = instr_code[14:12];

    always_comb begin
        case (opcode)
            `OP_R_TYPE: imm_Ext = 32'bx;
            `OP_S_TYPE:
            imm_Ext = {
                {20{instr_code[31]}}, instr_code[31:25], instr_code[11:7]};
            `OP_IL_TYPE: begin
                imm_Ext = {{20{instr_code[31]}}, instr_code[31:20]};
            end
            `OP_I_TYPE: begin
                imm_Ext = {{20{instr_code[31]}},instr_code[31:20]};
            end
            `OP_B_TYPE: 
            imm_Ext = { {19{instr_code[31]}}, instr_code[31], instr_code[7], instr_code[30:25], instr_code[11:8], 1'b0 };
            default: imm_Ext = 32'bx;
        endcase
    end
endmodule