[하만]세미콘 아카데미/verilog

0530~0531 RISCV_Type

내머리속은이런걸로 2024. 7. 9. 17:47

RISC-V Register File, Instruction

RISC-V Register File 32bit x 32


RISC-V CPU 기본 모듈

  • ALU : 연산 기능을 수행한다.
  • Register File : 고속으로 데이터를 임시 저장하고 접근하는 작은 메모리 블록이다.
  • PC Register : Instruction이 실행할 위치를 가지고 있는 Register이다. → Program Counter
  • Instruction Memory : 프로그램 명령어를 저장하고 CPU가 실행할 명령어를 읽어오는 메모리이다.
  • Data Memory : 실행 중인 프로그램이 사용하는 데이터를 저장하고 읽기/쓰기를 수행하는 메모리이다.

RISC-V Instruction Type

schematic

 

R - type

R-Type Instruction
R-Type schematic

I-Type

I-Type Instruction
I-Type Schematic

IL - Type

IL-Type Instruction
IL-Type Schematic



S-Type

S-Type Instruction
S-Type Schematic

B-Type

B-Type instruction
B-Type Schematic

 

U-Type

U-Type Instruction
U-Type schematic

 

UA-Type

UA-Type Instruction
UA-Type schematic

 

J-Type

J-Type Instruction
J-Type Instruction

 

JA-Type

JA-Type Instruction
JA-Type schematic


Single Cycle vs Multi Cycle vs Pipeline

Single Cycle

: 모든 명령어가 하나의 클럭 사이클 내에서 완료되는 프로세서이다.

  • 모든 명령어가 동일한 사이클 시간 내에 실행 : 가장 복잡한 명령어를 기준으로 사이클 시간이 결정된다. Propagation delay가 발생할 수 있다.
  • 단순한 설계 : 설계가 상대적으로 단순하고 이해하기 쉽다.
  • 낮은 효율성 : 간단한 명령어들도 불필요하게 긴 시간을 소모할 수 있다.

전파 지연 [ Propagation Delay ]

: 신호가 회로의 한 부분에서 다른 부분으로 전달되는 데 걸리는 시간이다. 모든 명령어가 하나의 클럭 사이클 내에서 완료되어야 하므로, 클럭 주기는 모든 명령어 중 가장 긴 지연 경로에 맞춰진다. 또한, 클럭 주기가 길어지면 프로세서의 최대 클럭 속도가 낮아지게 되어, 전반적인 성능이 제한될 수 있다. 

single cycle clk당 명령어

Multi Cycle

: 각 명령어가 여러 개의 클럭 사이클에 걸쳐 실행되는 프로세서이다. 각 사이클은 명령어의 한 부분을 처리한다. 한 명령어가 끝나면 다음 명령어가 처리된다.

  • 명령어가 여러 단계로 분할 : 각 단계는 하나의 클럭 사이클 동안 실행된다.
  • 단계적 처리 : 명령어 인출[Fetch], 해독[Decoder], 실행[Execute], 메모리 접근[MemAccess], 쓰기[WriteBack] 단계로 나눠 처리된다.
  • 동적인 사이클 시간 : 명령어 복잡도에 따라 필요한 사이클 수가 다르기 때문에 성능 향상이 가능하다.
  • 명령어 시간 지연 : 다음 명령어 실행이 느려질 수 있다.

Pipeline

: 여러 명령어를 동시에 서로 다른 단계에서 처리한다. 명령어의 한 부분이 다음 클럭으로 넘어가게 되면, 다음 명령어의 한 부분이 실행된다.

  • 병렬 처리 : 각 명령어가 서로 다른 단계에서 병렬로 처리된다. 하나의 명령어가 Decoder에 있을 때, 다른 명령어가 Fetch에 있을 수 있다.
  • 파이프라인 해저드 : 데이터, 제어, 주조적 해저드가 발생할 수 있다. 한 명령어의 정보 처리가 끝나지 않아 Register File에 정보가 저장되지 않았음에도 불구하고, 다음 명령어에서 Register File의 정보를 필요로 할 수 있다.

 

defines.sv

`define OP_TYPE_R 7'b0110011
`define OP_TYPE_IL 7'b0000011
`define OP_TYPE_I 7'b0010011
`define OP_TYPE_S 7'b0100011
`define OP_TYPE_B 7'b1100011
`define OP_TYPE_J 7'b1101111
`define OP_TYPE_JI 7'b1100111
`define OP_TYPE_U 7'b0110111
`define OP_TYPE_UA 7'b0010111

`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 4'b0000
`define BNE 4'b0001
`define BLT 4'b0100
`define BGE 4'b0101
`define BLTU 4'b0110
`define BGEU 4'b0111

 

 

DataMemory.sv

`timescale 1ns / 1ps

module DataMemory ( // RAM

    input  logic        clk,
    input  logic        we,
    input  logic [31:0] addr,
    input  logic [31:0] wdata,
    output logic [31:0] rdata
);
    logic [31:0] ram [0:63];

    initial begin
        int i;
        for (i=0 ; i<64 ; i++ ) begin
            ram[i] = 100 + i;
        end
    end

    assign rdata = ram[addr[31:2]];

    always_ff @(posedge clk) begin
        if (we) ram[addr[31:2]] <= wdata;
    end

endmodule

 

DataPath.sv

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

module DataPath (
    input  logic        clk,
    input  logic        reset,
    input  logic [31:0] machineCode,
    input  logic        regFileWe,
    input  logic [ 3:0] aluControl,
    output logic [31:0] instrMemRAddr,
    output logic [31:0] dataMemRAddr,
    output logic [31:0] dataMemWData,
    input  logic [31:0] dataMemRData,
    input  logic        AluSrcMuxSel,
    input  logic [ 2:0] extType,
    input  logic [ 2:0] RFWriteDataSrcMuxSel,
    input  logic        branch,
    input logic [ 1:0] PCMuxSel
);
    logic [31:0] w_ALUResult, w_RegFileRData1, w_RegFileRData2, w_PC_Data, w_PC_IMM_Data;
    logic [31:0] w_extendOut, w_AluSrcMuxOut, w_RFWriteDataSrcMuxOut;
    logic [31:0] w_PCAdderSrcMuxOut, w_PC_out, w_PC_Adder;
    logic w_btaken, w_PCAdderSrcMuxSel;
    assign dataMemRAddr = w_ALUResult;
    assign dataMemWData = w_RegFileRData2;

    Register U_PC (
        .clk  (clk),
        .reset(reset),
        .d    (w_PC_out),
        .q    (instrMemRAddr)
    );

    assign w_PCAdderSrcMuxSel = branch & w_btaken;

    mux_2x1 U_PCAdderSrcMux (
        .sel(w_PCAdderSrcMuxSel),
        .a  (32'd4),
        .b  (w_extendOut),
        .y  (w_PCAdderSrcMuxOut)
    );

    adder U_Adder_PC (
        .a(instrMemRAddr),
        .b(w_PCAdderSrcMuxOut),
        .y(w_PC_Data)
    );

    RegisterFile U_RegisterFile (
        .clk   (clk),
        .we    (regFileWe),
        .RAddr1(machineCode[19:15]),
        .RAddr2(machineCode[24:20]),
        .WAddr (machineCode[11:7]),
        .WData (w_RFWriteDataSrcMuxOut),
        .RData1(w_RegFileRData1),
        .RData2(w_RegFileRData2)
    );

    mux_2x1 U_ALUSrcMux (
        .sel(AluSrcMuxSel),
        .a  (w_RegFileRData2),
        .b  (w_extendOut),
        .y  (w_AluSrcMuxOut)
    );

    alu U_ALU (
        .a         (w_RegFileRData1),
        .b         (w_AluSrcMuxOut),
        .aluControl(aluControl),
        .result    (dataMemRAddr),
        .btaken    (w_btaken)
    );

    mux_5x1 U_RFWriteDataSrcMux (
        .sel(RFWriteDataSrcMuxSel),
        .a  (dataMemRAddr),
        .b  (dataMemRData),
        .c  (w_extendOut), // u-type
        .d  (w_PC_IMM_Data), // ua-type
        .e  (w_PC_Adder),   // j-type, i-type
        .y  (w_RFWriteDataSrcMuxOut)
    );

    extend U_Extend (
        .extType(extType),
        .instr  (machineCode[31:7]),  // except opcode
        .immext (w_extendOut)
    );

    adder U_Adder_PC_IMM (
        .a(w_extendOut),
        .b(instrMemRAddr),
        .y(w_PC_IMM_Data)
    );

    mux_3x1 U_PC_Mux (
        .sel(PCMuxSel),
        .a(w_PC_Data),
        .b(w_PC_IMM_Data),
        .c(dataMemRAddr),
        .y(w_PC_out)
    );

    adder U_PC_Adder_4 (
        .a(32'd4),
        .b(instrMemRAddr),
        .y(w_PC_Adder)
    );

endmodule

module RegisterFile (
    input  logic        clk,
    input  logic        we,
    input  logic [ 4:0] RAddr1,
    input  logic [ 4:0] RAddr2,
    input  logic [ 4:0] WAddr,
    input  logic [31:0] WData,
    output logic [31:0] RData1,
    output logic [31:0] RData2
);
    logic [31:0] RegFile[0:31];

    initial begin
        RegFile[0] = 32'd0;
        RegFile[1] = 32'd1;
        RegFile[2] = 32'd2;
        RegFile[3] = 32'd3;
        RegFile[4] = 32'd4;
        RegFile[5] = 32'd5;
    end

    always_ff @(posedge clk) begin
        if (we) RegFile[WAddr] <= WData;
    end

    assign RData1 = (RAddr1 != 0) ? RegFile[RAddr1] : 0;
    assign RData2 = (RAddr2 != 0) ? RegFile[RAddr2] : 0;
endmodule

module Register (
    input  logic        clk,
    input  logic        reset,
    input  logic [31:0] d,
    output logic [31:0] q
);
    always_ff @(posedge clk, posedge reset) begin
        if (reset) q <= 0;
        else q <= d;
    end
endmodule

module alu (
    input logic [31:0] a,
    input logic [31:0] b,
    input logic [3:0] aluControl,
    output logic btaken,
    output logic [31:0] result
);
    always_comb begin
        case (aluControl)
            `ADD:    result = a + b;
            `SUB:    result = a - b;
            `SLL:    result = a << b;
            `SRL:    result = a >> b;
            `SRA:    result = a >>> b;
            `SLT:    result = (a < b) ? 1 : 0;
            `SLTU:   result = (a < b) ? 1 : 0;
            `XOR:    result = a ^ b;
            `OR:     result = a | b;
            `AND:    result = a & b;
            default: result = 32'bx;
        endcase
    end

    always_comb begin : comparator  // B-Type
        case (aluControl[2:0])
            3'b000:  btaken = (a == b);  // BEQ: if (rs1 == rs2) PC += imm 
            3'b001:  btaken = (a != b);
            3'b100:  btaken = (a < b);
            3'b101:  btaken = (a >= b);
            3'b110:  btaken = (a < b);
            3'b111:  btaken = (a >= b);
            default: btaken = 1'bx;
        endcase
    end
endmodule

module adder (
    input  logic [31:0] a,
    input  logic [31:0] b,
    output logic [31:0] y
);

    assign y = a + b;
endmodule

module extend (  // immext
    input  logic [ 2:0] extType,
    input  logic [31:7] instr,    // except opcode
    output logic [31:0] immext
);
    always_comb begin
        case (extType)
            3'b000: immext = {{21{instr[31]}}, instr[31:20]};  // I-Type
            3'b001:
            immext = {{21{instr[31]}}, instr[30:25], instr[11:7]};  // S-Type
            3'b010:
            immext = {
                {20{instr[31]}}, instr[7], instr[30:25], instr[11:8], 1'b0
            };  // B-Type
            3'b011: immext = {instr[31:12], {12{1'b0}}};  // U-Type
            3'b100:
            immext = {
                {12{instr[31]}},
                instr[19:12],
                instr[20],
                instr[30:25],
                instr[24:21],
                1'b0
            };  // J-Type
            3'b111:
            immext = {
                {27{instr[31]}}, instr[24:20]
            };
        endcase
    end
endmodule

module mux_2x1 (
    input  logic        sel,
    input  logic [31:0] a,
    input  logic [31:0] b,
    output logic [31:0] y
);
    always_comb begin
        case (sel)
            1'b0: y = a;
            1'b1: y = b;
            default: y = 32'bx;
        endcase
    end
endmodule

module mux_3x1 (
    input  logic [ 1:0] sel,
    input  logic [31:0] a,
    input  logic [31:0] b,
    input  logic [31:0] c,
    output logic [31:0] y
);
    always_comb begin
        case (sel)
            2'b00:   y = a;
            2'b01:   y = b;
            2'b10:   y = c;
            default: y = 32'bx;
        endcase
    end
endmodule

module mux_5x1 (
    input  logic [ 2:0] sel,
    input  logic [31:0] a,
    input  logic [31:0] b,
    input  logic [31:0] c,
    input  logic [31:0] d,
    input  logic [31:0] e,
    output logic [31:0] y
);
    always_comb begin
        case (sel)
            3'b000:   y = a;
            3'b001:   y = b;
            3'b010:   y = c;
            3'b011:   y = d;
            3'b100:    y = e;
            default: y = 32'bx;
        endcase
    end
endmodule

 

ControlUnit.sv

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

module ControlUnit (
    input  logic [6:0] op,
    input  logic [2:0] funct3,
    input  logic [6:0] funct7,
    output logic       regFileWe,
    output logic       AluSrcMuxSel,
    output logic [2:0] RFWriteDataSrcMuxSel,
    output logic       dataMemWe,
    output logic [2:0] extType,
    output logic [3:0] aluControl,
    output logic       branch,
    output logic [1:0] PCMuxSel
);
    logic [11:0] controls;
    // logic [1:0] w_AluOp;
    assign {regFileWe, AluSrcMuxSel, RFWriteDataSrcMuxSel, dataMemWe, extType, branch, PCMuxSel} = controls;

    always_comb begin : main_decoder
        case (op)  // Opcode
            // regFisleWe, AluSrcMuxSel, RFWriteDataSrcMuxSel, dataMemWe, extType, branch, PCMuxSel
            `OP_TYPE_R:  controls = 12'b1_0_000_0_xxx_0_00;
            `OP_TYPE_IL: controls = 12'b1_1_001_0_000_0_00;
            `OP_TYPE_I:  
                if (funct3 == 3'b001 || funct3 == 3'b101) begin
                    controls = 12'b1_1_000_0_111_0_00;
                end
                else begin
                    controls = 12'b1_1_000_0_000_0_00;
                end
            `OP_TYPE_S:  controls = 12'b0_1_xxx_1_001_0_00;
            `OP_TYPE_B:  controls = 12'b0_0_xxx_0_010_1_00;
            `OP_TYPE_J:  controls = 12'b1_x_100_0_100_0_01;
            `OP_TYPE_JI: controls = 12'b1_1_100_0_000_0_10;
            `OP_TYPE_U:  controls = 12'b1_x_010_0_011_0_00;
            `OP_TYPE_UA: controls = 12'b1_x_011_0_011_0_00;
            default:     controls = 12'bx;
        endcase
    end

    always_comb begin : alu_control_signal
        case (op)
            `OP_TYPE_R: aluControl = {funct7[5], funct3};
            `OP_TYPE_IL: aluControl = {1'b0, 3'b000};    // only Add
            `OP_TYPE_I:
                if (funct3 == 3'b001 || funct3 == 3'b101) begin
                   aluControl = {funct7[5], funct3};
                end
                else begin
                    aluControl = {1'b0, 3'b000};
                end
            `OP_TYPE_S: aluControl = {1'b0, 3'b000};    // only Add
            `OP_TYPE_B: aluControl = {1'b0, funct3};
            `OP_TYPE_J: aluControl = {1'b0, 3'b000};
            `OP_TYPE_JI: aluControl = {1'b0, 3'b000};
            default:    aluControl = 4'bx;
        endcase
    end
endmodule

 

CPU_Core.sv

`timescale 1ns / 1ps

module CPU_Core (
    input  logic        clk,
    input  logic        reset,
    input  logic [31:0] machineCode,
    output logic [31:0] instrMemRAddr,
    output logic        dataMemWe,
    output logic [31:0] dataMemRAddr,
    output logic [31:0] dataMemWData,
    input  logic [31:0] dataMemRData
);

    logic w_regFileWe, w_AluSrcMuxSel, w_branch;
    logic [3:0] w_aluControl;
    logic [2:0] w_extType, w_RFWriteDataSrcMuxSel;
    logic [1:0] w_PCMuxSel;

    ControlUnit U_ControlUnit (
        .op                  (machineCode[6:0]),
        .funct3              (machineCode[14:12]),
        .funct7              (machineCode[31:25]),
        .regFileWe           (w_regFileWe),
        .AluSrcMuxSel        (w_AluSrcMuxSel),
        .RFWriteDataSrcMuxSel(w_RFWriteDataSrcMuxSel),
        .dataMemWe           (dataMemWe),
        .aluControl          (w_aluControl),
        .extType             (w_extType),
        .branch              (w_branch),
        .PCMuxSel            (w_PCMuxSel)
    );

    DataPath U_DataPath (
        .clk                 (clk),
        .reset               (reset),
        .machineCode         (machineCode),
        .regFileWe           (w_regFileWe),
        .aluControl          (w_aluControl),
        .instrMemRAddr       (instrMemRAddr),
        .AluSrcMuxSel        (w_AluSrcMuxSel),
        .RFWriteDataSrcMuxSel(w_RFWriteDataSrcMuxSel),
        .dataMemRAddr        (dataMemRAddr),
        .dataMemRData        (dataMemRData),
        .extType             (w_extType),
        .dataMemWData        (dataMemWData),
        .branch              (w_branch),
        .PCMuxSel            (w_PCMuxSel)
    );

endmodule

 

InstructionMemory.sv

`timescale 1ns / 1ps

module InstructionMemory (
    input  logic [31:0] addr,   // 1 byte standard
    output logic [31:0] data
);
    logic [31:0] rom[0:63];

    initial begin
        
        rom[0] = 32'h00520333;  // add x6, x4, x5
        rom[1] = 32'h401183b3;  // sub x7, x3, x1
        rom[2] = 32'h0020F433;  // and x8, x1, x2 
        rom[3] = 32'h0020E4B3;  // or  x9, x1, x2 
        rom[4] = 32'h00A02503;  // lw x10, x0, 10
        rom[5] = 32'h00A08193;  // addi x3, x1, 10
        rom[6] = 32'h00412223;  // sw x2 4 x4 -> sw rs1, imm, rs2 -> R[rs1 + imm %] = rs2
        rom[7] = 32'h00108463;  // beq x1 x1 8 -> if (x1 == X1), pc + imm => pc
        rom[9] = 32'h000015b7;  // lui x11 1 -> 4096
        rom[10] = 32'h00001617;  // auipc x12 1 -> 4096 + PC
        rom[11] = 32'h008006EF; // jal x13 8 -> x13 : PC+4, after PC+8
        //rom[13] = 32'h00820767; // jalr x14 x4 8 -> x14 : PC+4, after PC+(x4 + 8) -> PC = 12, when PC = 12, rom[3] machineCode run
        rom[13] = 32'h00C68767; // jalr x14 x13 12 -> x14 = PC+4=52, x13+12=60
        rom[15] = 32'h00269793; // slli x15 x13 2 -> x13<<2 = 48<<2=192, x15=192
        rom[16] = 32'h00275813; // srli x16 x14 2 -> x14>>2 = 56>>2=14, x16=14
        rom[17] = 32'h40A6D09; // srai x17 x13 2 -> x13>>>2 = 48>>>2=12, x17=12  4026D893
        

        /*
        // x0 = 0, x1 = 1, x2 = 2, x3 = 3, x4 = 4, x5 = 5
        //R-type
        rom[0] = 32'h00520333; // add x6, x4, x5  -> 9
        rom[1] = 32'h401183b3; // sub x7, x3, x1 -> 2
        rom[2] = 32'h00121433; //sll x8, x4, x1 -> 8
        rom[3] = 32'h001254b3; //srl x9, x4, x1 -> 2
        rom[4] = 32'h40125533; //sra x10, x4, x1 -> 2
        rom[5] = 32'h0030a5b3; //slt x11, x1, x3 -> 1 
        rom[6] = 32'h0030b633; //sltu x12, x1, x3 -> 1
        rom[7] = 32'h0020c6b3; //xor x13, x1, x2 -> 3
        rom[8] = 32'h0020e733; //or x14, x1, x2 -> 3
        rom[9] = 32'h0020f7b3; //and x15, x1, x2 -> 0
        //I-type
        rom[10] = 32'h0040a803; //lw x16 x1 4  -> 101 
        rom[11] = 32'h00908893; //addi x17 x1 9  -> 10 
        rom[12] = 32'h0040a913; //slti x18 x1 4  -> 1
        rom[13] = 32'h0040b993; //sltiu x19 x1 4 -> 1 
        rom[14] = 32'h0020ca13; //xori x20 x1 2  -> 3
        rom[15] = 32'h0020ea93; //ori x21 x1 2  -> 3
        rom[16] = 32'h0020fb13; //andi x22 x1 2  -> 0
        rom[17] = 32'h00221b93; //slli x23 x4 2  -> 16
        rom[18] = 32'h00225c13; //srli x24 x4 2  -> 1
        rom[19] = 32'h40225c93; //srai x25 x4 2  -> 1 

        //S-type
        rom[20] = 32'h00502423; //sw x0, 8 x5 -> Ram[2] = 5
    
        //B-type
        rom[21] = 32'h00108463; //beq x1 x1 8 -> pc = pc + 8
        rom[23] = 32'h00209463; //bne x1 x2 8 -> pc = pc + 8
        rom[25] = 32'h0020c463; //blt x1 x2 8 -> pc = pc + 8
        rom[27] = 32'h00125463; //bge x4 x1 8 -> pc = pc + 8
        rom[29] = 32'h0020e463; //bltu x1 x2 8 -> pc = pc + 8
        rom[31] = 32'h00127463; //bgeu x4 x1 8 -> pc = pc + 8
        
        //U-type
        rom[33] = 32'h00001d37; //lui x26 1 -> 4096
        
        //UA-type
        rom[34] = 32'h00001d97; //auipc x27 1 -> pc = pc + 4096
    
        //J-type
        rom[35] = 32'h00800e6f; //jal x28 8 -> rd = pc + 4 / pc = pc + imm
        
        //I-type
        rom[37] = 32'h00810ee7; //jalr x2 x29 8 -> rd = rd = pc + 4 / pc = rs1(2) + imm(8) 
        */
    end

    // use 4 byte (32bit)
    assign data = rom[addr[31:2]];  // 0, 4, 8 ...
endmodule

 

RV32I.sv

`timescale 1ns / 1ps

module RV32I(
    input logic clk,
    input logic reset
    );
    
    logic [31:0] w_InstrMemAddr, w_InstrMemData;
    logic w_dataMemWe;
    logic [31:0] w_dataMemRAddr, w_dataMemRData, w_dataMemWData;

    CPU_Core U_CPU_Core(
        .clk(clk),
        .reset(reset),
        .machineCode(w_InstrMemData),
        .instrMemRAddr(w_InstrMemAddr),
        .dataMemWe(w_dataMemWe),
        .dataMemRAddr(w_dataMemRAddr),
        .dataMemRData(w_dataMemRData),
        .dataMemWData(w_dataMemWData)
    );
    
    DataMemory U_RAM(
        .clk(clk),
        .we(w_dataMemWe),
        .addr(w_dataMemRAddr),
        .wdata(w_dataMemWData),
        .rdata(w_dataMemRData)
    );

    InstructionMemory U_ROM(
        .addr(w_InstrMemAddr),
        .data(w_InstrMemData)
    );
endmodule

 

schematic

 

tb_RV32I.sv

`timescale 1ns / 1ps

module tb_RV32I();

    logic clk;
    logic reset;

    RV32I dut(
        .clk(clk),
        .reset(reset)
    );

    always #5 clk = ~clk;

    initial begin
        clk  = 0;
        reset = 1'b1;
        #40 reset = 1'b0;
    end
endmodule

 

schematic

 

1) RegisterFile

 

 

2) RAM

 

 


 

Assmebly Language

RISC-V Assembly Programmer&rsquo;s Handbook.pdf
0.23MB

 

Instruction Set

RV32I Base Instruction Set_v3.pdf
0.06MB

'[하만]세미콘 아카데미 > verilog' 카테고리의 다른 글

0604 RISC-v GPO GPI GPIO  (0) 2024.07.10
0603 RISC-v GPI GPO  (0) 2024.07.09
0523 Team Project  (0) 2024.07.09
0529 DedicatedProcessor stackSum  (0) 2024.07.09
0529 Dedicated Processor ALU  (0) 2024.07.09