[하만]세미콘 아카데미/verilog
0529 Dedicated Processor ALU
내머리속은이런걸로
2024. 7. 9. 17:46
- R1 = 0
- R2 = 0
- R3 = 1
- R1 = R1 + R3 = 0 + 1 = 1
- R2 = R2 + R3 = 0 + 1 = 1
- R3 = R1 - R2 = 1 - 1 = 0
- R4 = R1 & R3 = 1 & 0 = 0
- R5 = R2 | R3 = 1 | 0 = 1
- R6 = R1 + R2 = 1 + 1 = 2
- R7 = R2 + R6 = 1 + 2 = 3
- output = R7
Control Signal Truth Table
Instruction | state | RFSrcMuxSel | we | waddr[2:0] | raddr[2:0] | raddr2[2:0] | op[1:0] | OutLoad |
R1 = 0 | S0 | 0 | 1 | 1 | 0 | 0 | x | 0 |
R2 = 0 | S1 | 0 | 1 | 2 | 0 | 0 | x | 0 |
R3 = 1 | S2 | 1 | 1 | 3 | 0 | 0 | x | 0 |
R1 = R1 + R3 | S3 | 0 | 1 | 1 | 1 | 3 | 0 | 0 |
R2 = R2 + R3 | S4 | 0 | 1 | 2 | 2 | 3 | 0 | 0 |
R3 = R1 - R2 | S5 | 0 | 1 | 3 | 1 | 2 | 1 | 0 |
R4 = R1 & R3 | S6 | 0 | 1 | 4 | 1 | 3 | 2 | 0 |
R5 = R2 | R3 | S7 | 0 | 1 | 5 | 2 | 3 | 3 | 0 |
R6 = R1 + R2 | S8 | 0 | 1 | 6 | 1 | 2 | 0 | 0 |
R7 = R2 + R6 | S9 | 0 | 1 | 7 | 2 | 6 | 0 | 0 |
output = R7 | S10 | x | 0 | x | 7 | x | x | 1 |
halt | S11 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
DataPath
`timescale 1ns / 1ps
module DataPath (
input clk,
input reset,
input [1:0] op,
input RFSrcMuxSel,
input we,
input [2:0] raddr1,
input [2:0] raddr2,
input [2:0] waddr,
input OutLoad,
//output Le10,
output [7:0] outPort
);
logic [7:0] w_AdderResult, w_RFSrcMuxOut, w_rdata1, w_rdata2;
mux_2x1 U_RFSrcMus (
.sel(RFSrcMuxSel),
.a (w_AdderResult),
.b (8'b1),
.y (w_RFSrcMuxOut)
);
RegisterFile U_RF (
.clk (clk),
.we (we),
.waddr (waddr),
.raddr1(raddr1),
.raddr2(raddr2),
.wdata (w_RFSrcMuxOut),
.rdata1(w_rdata1),
.rdata2(w_rdata2)
);
// adder U_Adder (
// .a(w_rdata1),
// .b(w_rdata2),
// .y(w_AdderResult)
// );
ALU U_ALU (
.a(w_rdata1),
.b(w_rdata2),
.op(op),
.y(w_AdderResult)
);
// comparator U_Comp (
// .a (w_rdata1),
// .b (8'd10),
// .le(Le10)
// );
register U_OutReg (
.clk (clk),
.reset(reset),
.load (OutLoad),
.d (w_rdata1),
.q (outPort)
);
endmodule
module RegisterFile (
input clk,
input we,
input [2:0] waddr,
input [2:0] raddr1,
input [2:0] raddr2,
input [7:0] wdata,
output [7:0] rdata1,
output [7:0] rdata2
);
logic [7:0] regFile[0:7]; // 8bit regFile 4
always_ff @(posedge clk) begin
if (we) regFile[waddr] <= wdata;
end
// If address is 0, rdata is 0.
assign rdata1 = (raddr1 != 0) ? regFile[raddr1] : 0;
assign rdata2 = (raddr2 != 0) ? regFile[raddr2] : 0;
endmodule
module mux_2x1 (
input sel,
input [7:0] a,
input [7:0] b,
output logic [7:0] y // logic = reg & wire
);
always_comb begin : mux_2x1
case (sel)
1'b0: y = a;
1'b1: y = b;
endcase
end
endmodule
module comparator (
input [7:0] a,
input [7:0] b,
output le // less than equal
);
assign le = a <= b;
endmodule
module adder (
input [7:0] a,
input [7:0] b,
output [7:0] y
);
assign y = a + b;
endmodule
module register (
input clk,
input reset,
input load,
input [7:0] d,
output logic [7:0] q
);
always_ff @(posedge clk, posedge reset) begin : register
if (reset) begin
q <= 0;
end else begin
if (load) q <= d;
end
end : register // end of register, don't have to write
endmodule
module ALU (
input [7:0] a,
input [7:0] b,
input [1:0] op, // +, -, and, or
output logic [7:0] y
);
always_comb begin
case (op)
2'b00: y = (a + b);
2'b01: y = (a - b);
2'b10: y = (a & b);
2'b11: y = (a | b);
endcase
end
endmodule
ControlUnit.sv
`timescale 1ns / 1ps
module ControlUnit (
input clk,
input reset,
//input Le10,
output logic [1:0] op,
output logic RFSrcMuxSel,
output logic we,
output logic [2:0] raddr1,
output logic [2:0] raddr2,
output logic [2:0] waddr,
output logic OutLoad
);
enum logic [3:0] { S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11} state, state_next;
always_ff @(posedge clk, posedge reset) begin
if (reset) state <= S0;
else state <= state_next;
end
always_comb begin
state_next = state;
case (state)
S0: state_next = S1;
S1: state_next = S2;
S2: state_next = S3;
S3: state_next = S4;
S4: state_next = S5;
S5: state_next = S6;
S6: state_next = S7;
S7: state_next = S8;
S8: state_next = S9;
S9: state_next = S10;
S10: state_next = S11;
S11: state_next = S11;
default : state_next = state;
endcase
end
always_comb begin
RFSrcMuxSel = 1'b0;
we = 1'b0;
waddr = 3'd0;
raddr1 = 3'd0;
raddr2 = 3'd0;
OutLoad = 1'd0;
op = 2'd0;
case (state)
S0: begin
RFSrcMuxSel = 1'b0;
we = 1'b1;
waddr = 3'd1;
raddr1 = 3'd0;
raddr2 = 3'd0;
OutLoad = 1'd0;
op = 2'd0;
end
S1: begin
RFSrcMuxSel = 1'b0;
we = 1'b1;
waddr = 3'd2;
raddr1 = 3'd0;
raddr2 = 3'd0;
OutLoad = 1'd0;
op = 2'd0;
end
S2: begin
RFSrcMuxSel = 1'b1;
we = 1'b1;
waddr = 3'd3;
raddr1 = 3'd0;
raddr2 = 3'd0;
OutLoad = 1'd0;
op = 2'd0;
end
S3: begin
RFSrcMuxSel = 1'b0;
we = 1'b1;
waddr = 3'd1;
raddr1 = 3'd1;
raddr2 = 3'd3;
OutLoad = 1'd0;
op = 2'd0;
end
S4: begin
RFSrcMuxSel = 1'b0;
we = 1'b1;
waddr = 3'd2;
raddr1 = 3'd2;
raddr2 = 3'd3;
OutLoad = 1'd0;
op = 2'd0;
end
S5: begin
RFSrcMuxSel = 1'b0;
we = 1'b1;
waddr = 3'd3;
raddr1 = 3'd1;
raddr2 = 3'd2;
OutLoad = 1'd0;
op = 2'd1;
end
S6: begin
RFSrcMuxSel = 1'b0;
we = 1'b1;
waddr = 3'd4;
raddr1 = 3'd1;
raddr2 = 3'd3;
OutLoad = 1'd0;
op = 2'd2;
end
S7: begin
RFSrcMuxSel = 1'b0;
we = 1'b1;
waddr = 3'd5;
raddr1 = 3'd2;
raddr2 = 3'd3;
OutLoad = 1'd0;
op = 2'd3;
end
S8: begin
RFSrcMuxSel = 1'b0;
we = 1'b1;
waddr = 3'd6;
raddr1 = 3'd1;
raddr2 = 3'd2;
OutLoad = 1'd0;
op = 2'd0;
end
S9: begin
RFSrcMuxSel = 1'b0;
we = 1'b1;
waddr = 3'd7;
raddr1 = 3'd2;
raddr2 = 3'd6;
OutLoad = 1'd0;
op = 2'd0;
end
S10: begin
RFSrcMuxSel = 1'b0;
we = 1'b0;
waddr = 3'd0;
raddr1 = 3'd7;
raddr2 = 3'd0;
OutLoad = 1'd1;
op = 2'd0;
end
S11: begin
RFSrcMuxSel = 1'b0;
we = 1'b0;
waddr = 3'd0;
raddr1 = 3'd0;
raddr2 = 3'd0;
OutLoad = 1'd0;
op = 2'd0;
end
endcase
end
endmodule
DedicatedProcessor.sv
`timescale 1ns / 1ps
module DedicatedProcessor(
input clk,
input reset,
output [7:0] outPort
);
logic RFSrcMuxSel, we, OutLoad;
logic [1:0] op;
logic [2:0] waddr, raddr1, raddr2;
ControlUnit U_ControlUnit(
.*
);
DataPath U_DataPath(
.*
);
endmodule
schematic
tb_dp.sv
`timescale 1ns / 1ps
module tb_dp();
logic clk;
logic reset;
logic [7:0] outPort;
DedicatedProcessor dut(
.clk(clk),
.reset(reset),
.outPort(outPort)
);
always #5 clk = ~clk;
initial begin
clk <= 1'b0;
reset <= 1'b1;
#40 reset <= 1'b0;
end
endmodule
simulation