https://hackmd.io/@BqIJeKQXSZWMQp1qeh8GSQ/ByPSjP1Xn
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
module pc(
input clock,
input reset,
input branchFlag,
input ce, // changeEnable
input [15:0] dr,
output reg [15:0] pc,
output reg [15:0] pcPlusOne
);
always @(*) begin
pcPlusOne <= pc + 1;
end
always @(posedge clock) begin
if (reset) begin
pc <= 0;
end else if (ce) begin
if (branchFlag) begin
pc <= dr;
end else begin
pc <= pcPlusOne;
end
end
end
endmodule
things to add
ADDI
SUBI
CMPI
module Fwd(input clock,reset,ce,//changeEnable
input [1:0] value,
output reg [1:0] register);
always @(posedge clock) begin
if(reset == 1'b 1)begin
register <= 2'b00;
end else begin
if(ce == 1'b1)begin
register <= value;
end
end
end
endmodule
module HazardDetectionUnit(input [2:0] RegRs,RegRt,p3_RegRa,p3_RegRd,p4_data_input_3,//p3_RegRa=ar_addr
input p3_memRead,branchFlag,
output reg pcWren,irWren,irFlush,p3_RegFlush);//p3_Reg=ar,br,control3,ir3
always @(*) begin
pcWren <= 1'b1;
irWren <= 1'b1;
irFlush <= 1'b0;
p3_RegFlush <= 1'b0;
if((p3_memRead == 1'b1) & ((p3_RegRa == RegRs) | (p3_RegRa == RegRt)) ) begin//LD→ADD,p3_memRead == 1'b1(ロード命令ならば)
pcWren <= 1'b0;
irWren <= 1'b0;
p3_RegFlush <= 1'b1;
end if((p4_data_input_3 == 1'b1) & ((p3_RegRd == RegRs) | (p3_RegRd == RegRt)) ) begin//IN命令ならばp3レジスタをフラッシュさせずに残す。
pcWren <= 1'b0;
irWren <= 1'b0;
p3_RegFlush <= 1'b1;
end if(branchFlag == 1'b1) begin//分岐ハザード
irFlush <= 1'b1;
end
end
endmodule
module ForwardingUnit(input [2:0] RegRs,RegRt,p3_RegRd,p4_RegRd,
input p3_RegWren,p4_RegWren,
output [1:0] FwdA,FwdB);
//組み合わせ回路で
//FwdA,FwdBはともにデフォルトの値が2'b00
//p3_RegWren&&p3_RegRd==RegRsならば、FwdAを2'b10
//p4_RegWren&&p4_RegRd==RegRsならば、FwdAを2'b01
//p3_RegWren&&p3_RegRd==RegRtならば、FwdBを2'b10
//p4_RegWren&&p4_RegRd==RegRtならば、FwdBを2'b01
assign FwdA[1] = p3_RegWren&(p3_RegRd==RegRs);
assign FwdA[0] = ~FwdA[1]&p4_RegWren&(p4_RegRd==RegRs);
assign FwdB[1] = p3_RegWren&(p3_RegRd==RegRt);
//二回以上連続で一個前にフォワーディングするときに、FwdB=2'b11になってしまう。
assign FwdB[0] = ~FwdB[1]&p4_RegWren&(p4_RegRd==RegRt);
endmodule
module branch_predictor(
input wire clk,
input wire reset,
input wire branch_taken,
input wire correct_prediction,
output reg prediction
);
always @(posedge clk or posedge reset) begin
if (reset)
prediction <= 1'b0;
else if (branch_taken)
prediction <= branch_taken;
end
endmodule
module pipeline_controller(
input wire clk,
input wire reset,
input wire branch_taken,
input wire correct_prediction,
output reg stall
);
wire prediction;
branch_predictor predictor(.clk(clk), .reset(reset), .branch_taken(branch_taken),
.correct_prediction(correct_prediction), .prediction(prediction));
always @(posedge clk or posedge reset) begin
if (reset)
stall <= 1'b0;
else if (prediction != correct_prediction)
stall <= 1'b1;
else
stall <= 1'b0;
end
endmodule
if( twobit == 2'b11 )begin
opcode_wire <= opcode_reg;
end else if(twobit == 2'b10 && brch_reg == 3'b000) begin
opcode_wire <= 4'b0110;
end else if(twobit == 2'b10 && (brch_reg == 3'b001 || brch_reg == 3'b010 || brch_reg == 3'b011)) begin //ADDI, SUBI, CMPI
opcode_wire <= {1'b0, brch_reg}; // Extend brch_reg to 4 bits
RegWrite_wire <= 1'b1; // Assuming that you write to a register for these instructions
ALUSrc1_wire <= 1'b1; // Assuming that these instructions take an immediate value as one source
ALUSrc2_wire <= 1'b1; // Assuming that these instructions take a register value as one source
end else begin
opcode_wire <= 4'b0000;
end
LI 1,1
LI 3,1
LI 0,2
SLL 0,10
SUB 0,1
LI 2,1
SLL 2,10
LI 5,0
LI 6,2
SLL 6,10
LD 4,0,2
AND 4,3
BNE 1
ADD 5,1
ADD 2,1
CMP 2,0
BLT -7
LI 2,1
SLL 2,10
ADD 5,6
LD 4,0,2
LD 7,0,2
AND 4,3
BNE 2
ST 7,0,5
ADD 5,1
AND 4,3
BE 2
ST 7,0,6
ADD 6,1
ADD 2,1
CMP 2,0
BLT -13
LI 2,2
SLL 2,10
LI 7,1
SLL 7,10
LD 4,0,2
ADD 2,1
ST 4,0,7
ADD 7,1
CMP 7,0
BLT -6
SLL 3,1
LI 5,1
SLL 5,14
CMP 3,5
BLT -43
LI 3,1
SLL 3,15
LI 2,1
SLL 2,10
LI 5,0
LI 6,2
SLL 6,10
LD 4,0,2
AND 4,3
BE 1
ADD 5,1
ADD 2,1
CMP 2,0
BLT -7
LI 2,1
SLL 2,10
ADD 5,6
LD 4,0,2
LD 7,0,2
AND 4,3
BNE 2
ST 7,0,6
ADD 6,1
AND 4,3
BE 2
ST 7,0,5
ADD 5,1
ADD 2,1
CMP 2,0
BLT -13
LI 2,2
SLL 2,10
SLL 3,1
LI 7,1
SLL 7,10
LD 4,0,2
ADD 2,1
ST 4,0,7
ADD 7,1
CMP 7,0
BLT -6
LI 2,1
SLL 2,10
LD 4,0,2
OUT 4
ADD 2,1
CMP 2,0
BLE -5
HLT
SLI 0,1,10
SLI 1,1,11
LD 4,0,0
LD 5,1,0
ADDI 0,1
CMP 4,5
BLT 2
BE 29
B 9
LD 4,0,0
LD 5,1,0
ADDI 0,1
CMP 0,1
BNE 1
HLT
CMP 4,5
BLE -8
B 29
LD 4,0,0
LD 5,1,0
ADDI 0,1
CMP 0,1
BNE 11
SLI 0,1,10
SUBI 1,1
LD 4,0,0
LD 5,0,1
ST 4,0,1
ST 5,0,0
ADDI 0,1
SUBI 1,1
CMP 0,1
BLE -8
HLT
CMP 5,4
BLE -18
B 10
LD 4,0,0
LD 5,1,0
ADDI 0,1
CMP 0,1
BNE 1
HLT
CMP 4,5
BE -8
BLE -37
B -29
# Initialize registers
LI 0, 1024 # Base address of input values
LI 1, 2048 # Base address of output values
LI 2, 0 # Current byte value
LI 3, 0 # Current histogram index
LI 4, 0 # Temporary register for input value
LI 5, 0 # Temporary register for histogram value
LI 6, 0 # Temporary register for output value
LI 7, 256 # Total number of byte values
# Initialize histogram to zero
HistogramInit:
ST 2, 0, 3 # Store 0 at current histogram index
ADD 3, 1 # Move to next histogram index
CMP 3, 7 # Check if all histogram indices have been initialized
BNE -3
# Count occurrences of each byte value
CountLoop:
LD 4, 0, 0 # Load input value
LD 5, 4, 3 # Load histogram value for current input value
ADD 5, 1 # Increment histogram value
ST 5, 4, 3 # Store updated histogram value
ADD 0, 1 # Move to next input value
CMP 0, 7 # Check if all input values have been processed
BNE -6
# Output sorted byte values
LI 2, 0 # Reset current byte value
OutputLoop:
LD 5, 2, 3 # Load histogram value for current byte value
OutputLoop2:
CMP 5, 0 # Check if all occurrences of current byte value have been output
BEQ NextByte
ST 2, 0, 1 # Output current byte value
ADD 1, 1 # Move to next output location
SUB 5, 1 # Decrement histogram value
B -4
NextByte:
ADD 2, 1 # Move to next byte value
CMP 2, 7 # Check if all byte values have been output
BNE -7