본문내용
M,
output pcsrcD, branchD, alusrcE,
output regdstE, regwriteE,
output regwriteM, regwriteW,
output jumpD,
output [2:0] alucontrolE); // memtoregE, memtoregM, memtoregW, memwriteM, pcsrcD, branchD, alusrcE,
// regdstE, regwriteE, regwriteM, regwriteW, jumpD를 output으로 지정하고,
// 2bits의 alucontrolE를 output으로 지정한다.
wire [1:0] aluopD; // 2bits aluhopD를 내부변수로 지정한다.
wire memtoregD, memwriteD, alusrcD,//각 컨트롤러에 대해서 내부 변수 정의
regdstD, regwriteD; // memtoregd, memwriteD, alusrcD, regdstD, regwriteD 를 내부변수로 지정한다.
wire [2:0] alucontrolD; // //3비트
wire memwriteE;
// Main Decoder and ALU Decoder subunits.
maindec md(opD, memtoregD, memwriteD, branchD,
alusrcD, regdstD, regwriteD, jumpD,
aluopD);
aludec ad(functD, aluopD, alucontrolD);
assign pcsrcD = branchD & equalD;
module maindec(input [5:0] op,
output memtoreg, memwrite,
output branch, alusrc,
output regdst, regwrite,
output jump,
output [1:0] aluop);
reg [8:0] controls;//8비트 컨트롤러 정의
assign {regwrite, regdst, alusrc,/컨트롤러에 대해서 정의 한다.
branch, memwrite,
memtoreg, jump, aluop} = controls;
always @(*)
case(op)
6\'b000000: controls <= 9\'b110000010; //Rtyp
6\'b100011: controls <= 9\'b101001000; //LW
6\'b101011: controls <= 9\'b001010000; //SW
6\'b000100: controls <= 9\'b000100001; //BEQ
6\'b001000: controls <= 9\'b101000000; //ADDI
6\'b000010: controls <= 9\'b000000100; //J
default: controls <= 9\'bxxxxxxxxx; //모두 아닌 경우 돈케어로 정의
endcase
endmodule
module aludec(input [5:0] funct,// 각 명령어에 대한 정의
input [1:0] aluop,
output reg [2:0] alucontrol);
always @(*)
case(aluop)
2\'b00: alucontrol <= 3\'b010; // add
2\'b01: alucontrol <= 3\'b110; // sub
default: case(funct) // RTYPE
6\'b100000: alucontrol <= 3\'b010; // ADD
6\'b100010: alucontrol <= 3\'b110; // SUB
6\'b100100: alucontrol <= 3\'b000; // AND
6\'b100101: alucontrol <= 3\'b001; // OR
6\'b101010: alucontrol <= 3\'b111; // SLT
default: alucontrol <= 3\'bxxx; // ???
endcase
endcase
endmodule
파이프 라인에서 작동하는 ALU와 컨트롤러과 데이터 패스를 정의 했다. 싱글사이클과 멀티사이클을 참고해서 코드를 만들었고 각 파이프라인의 사이클에 동작하게 끔 만들었다. 디코더를 이용해서 각 6피트 op 코드를 비트마다 정의했는데 각 논리게이트 동작 및 쉬프트 연산에 책에 있는 281쪽을 참고 R타입 과 저장명령어를 정의 했다.
module hazard(input [4:0] rsD, rtD, rsE, rtE,
input [4:0] writeregE,
writeregM, writeregW,
input regwriteE, regwriteM,
regwriteW,
input memtoregE, memtoregM, branchD,
output forwardaD, forwardbD,
output reg [1:0] forwardaE, forwardbE,
output stallF, stallD, flushE);
wire lwstallD, branchstallD;
// forwarding sources to D stage (branch equality)
assign forwardaD = (rsD !=0 & rsD == writeregM & regwriteM);
assign forwardbD = (rtD !=0 & rtD == writeregM & regwriteM);
// forwarding sources to E stage (ALU)
always @(*)
begin
forwardaE = 2\'b00; forwardbE = 2\'b00;
if (rsE != 0)
if (rsE == writeregM & regwriteM)
forwardaE = 2\'b10;
else if (rsE == writeregW & regwriteW)
forwardaE = 2\'b01;
if (rtE != 0)
if (rtE == writeregM & regwriteM)
forwardbE = 2\'b10;
else if (rtE == writeregW & regwriteW)
forwardbE = 2\'b01;
end
endmodule
이번에 해저드를 생각했을 때 데이터 해저드를 생각해서 만들어 보긴 했지만 실제 해저드가 발생 했을때 돌아가는지는 확인해보지 못했다. 각 구조적 해저드나 버블을(stall)에 대해선 생각은 해
output pcsrcD, branchD, alusrcE,
output regdstE, regwriteE,
output regwriteM, regwriteW,
output jumpD,
output [2:0] alucontrolE); // memtoregE, memtoregM, memtoregW, memwriteM, pcsrcD, branchD, alusrcE,
// regdstE, regwriteE, regwriteM, regwriteW, jumpD를 output으로 지정하고,
// 2bits의 alucontrolE를 output으로 지정한다.
wire [1:0] aluopD; // 2bits aluhopD를 내부변수로 지정한다.
wire memtoregD, memwriteD, alusrcD,//각 컨트롤러에 대해서 내부 변수 정의
regdstD, regwriteD; // memtoregd, memwriteD, alusrcD, regdstD, regwriteD 를 내부변수로 지정한다.
wire [2:0] alucontrolD; // //3비트
wire memwriteE;
// Main Decoder and ALU Decoder subunits.
maindec md(opD, memtoregD, memwriteD, branchD,
alusrcD, regdstD, regwriteD, jumpD,
aluopD);
aludec ad(functD, aluopD, alucontrolD);
assign pcsrcD = branchD & equalD;
module maindec(input [5:0] op,
output memtoreg, memwrite,
output branch, alusrc,
output regdst, regwrite,
output jump,
output [1:0] aluop);
reg [8:0] controls;//8비트 컨트롤러 정의
assign {regwrite, regdst, alusrc,/컨트롤러에 대해서 정의 한다.
branch, memwrite,
memtoreg, jump, aluop} = controls;
always @(*)
case(op)
6\'b000000: controls <= 9\'b110000010; //Rtyp
6\'b100011: controls <= 9\'b101001000; //LW
6\'b101011: controls <= 9\'b001010000; //SW
6\'b000100: controls <= 9\'b000100001; //BEQ
6\'b001000: controls <= 9\'b101000000; //ADDI
6\'b000010: controls <= 9\'b000000100; //J
default: controls <= 9\'bxxxxxxxxx; //모두 아닌 경우 돈케어로 정의
endcase
endmodule
module aludec(input [5:0] funct,// 각 명령어에 대한 정의
input [1:0] aluop,
output reg [2:0] alucontrol);
always @(*)
case(aluop)
2\'b00: alucontrol <= 3\'b010; // add
2\'b01: alucontrol <= 3\'b110; // sub
default: case(funct) // RTYPE
6\'b100000: alucontrol <= 3\'b010; // ADD
6\'b100010: alucontrol <= 3\'b110; // SUB
6\'b100100: alucontrol <= 3\'b000; // AND
6\'b100101: alucontrol <= 3\'b001; // OR
6\'b101010: alucontrol <= 3\'b111; // SLT
default: alucontrol <= 3\'bxxx; // ???
endcase
endcase
endmodule
파이프 라인에서 작동하는 ALU와 컨트롤러과 데이터 패스를 정의 했다. 싱글사이클과 멀티사이클을 참고해서 코드를 만들었고 각 파이프라인의 사이클에 동작하게 끔 만들었다. 디코더를 이용해서 각 6피트 op 코드를 비트마다 정의했는데 각 논리게이트 동작 및 쉬프트 연산에 책에 있는 281쪽을 참고 R타입 과 저장명령어를 정의 했다.
module hazard(input [4:0] rsD, rtD, rsE, rtE,
input [4:0] writeregE,
writeregM, writeregW,
input regwriteE, regwriteM,
regwriteW,
input memtoregE, memtoregM, branchD,
output forwardaD, forwardbD,
output reg [1:0] forwardaE, forwardbE,
output stallF, stallD, flushE);
wire lwstallD, branchstallD;
// forwarding sources to D stage (branch equality)
assign forwardaD = (rsD !=0 & rsD == writeregM & regwriteM);
assign forwardbD = (rtD !=0 & rtD == writeregM & regwriteM);
// forwarding sources to E stage (ALU)
always @(*)
begin
forwardaE = 2\'b00; forwardbE = 2\'b00;
if (rsE != 0)
if (rsE == writeregM & regwriteM)
forwardaE = 2\'b10;
else if (rsE == writeregW & regwriteW)
forwardaE = 2\'b01;
if (rtE != 0)
if (rtE == writeregM & regwriteM)
forwardbE = 2\'b10;
else if (rtE == writeregW & regwriteW)
forwardbE = 2\'b01;
end
endmodule
이번에 해저드를 생각했을 때 데이터 해저드를 생각해서 만들어 보긴 했지만 실제 해저드가 발생 했을때 돌아가는지는 확인해보지 못했다. 각 구조적 해저드나 버블을(stall)에 대해선 생각은 해
소개글