발표시간 10~15분, 기본은 10분 systemverilog verification하면 20분
개인으로 발표
ppt 20장 내외
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
`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
`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, ...)
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