Line 1... |
Line 1... |
module sub86( CLK, RSTN, IA, ID, A, D, Q, WEN,BEN );
|
module sub86( CLK, RSTN, IA, ID, A, D, Q, WEN,BEN,CE,RD );
|
input CLK,RSTN;
|
input CLK,RSTN,CE;
|
output [31:0] IA;
|
output [31:0] IA;
|
input [15:0] ID;
|
input [15:0] ID;
|
output [31:0] A;
|
output [31:0] A;
|
input [31:0] D;
|
input [31:0] D;
|
output [31:0] Q;
|
output [31:0] Q;
|
output WEN;
|
output WEN;
|
|
output RD;
|
output [1:0] BEN;
|
output [1:0] BEN;
|
wire nncry,neqF,ngF,nlF,naF,nbF,divF1,divF2;
|
wire nncry,neqF,ngF,nlF,naF,nbF,divF1,divF2;
|
reg [31:0] EAX,EBX,ECX,EDX,EBP,ESP,PC,regsrc,regdest,alu_out;
|
reg [31:0] EAX,EBX,ECX,EDX,EBP,ESP,PC,regsrc,regdest,alu_out;
|
reg [5:0] state,nstate;
|
reg [5:0] state,nstate;
|
reg [2:0] src,dest;
|
reg [2:0] src,dest;
|
reg cry,ncry,prefx,nprefx,cmpr,eqF,gF,lF,aF,bF;
|
reg RD,cry,ncry,prefx,nprefx,cmpr,eqF,gF,lF,aF,bF;
|
wire [31:0] pc_ja,pc_jae,pc_jb,pc_jbe,pc_jg,pc_jge,pc_jl,pc_jle,pc_eq,pc_jp,pc_neq;
|
wire [31:0] pc_ja,pc_jae,pc_jb,pc_jbe,pc_jg,pc_jge,pc_jl,pc_jle,pc_eq,pc_jp,pc_neq,pc_sh;
|
wire [31:0] Sregsrc,Zregsrc,incPC,sft_out,smlEAX,smlECX;
|
wire [31:0] Sregsrc,Zregsrc,incPC,sft_out,smlEAX,smlECX;
|
wire [32:0] adder_out,sub_out;
|
wire [32:0] adder_out,sub_out;
|
wire [4:0] EBX_shtr;
|
wire [4:0] EBX_shtr;
|
wire signed [31:0] ssregsrc, ssregdest;
|
wire signed [31:0] ssregsrc, ssregdest;
|
`define fetch 6'b111111
|
`define fetch 6'b111111
|
Line 59... |
Line 60... |
`define sdv1 6'b101000
|
`define sdv1 6'b101000
|
`define sdv2 6'b101001
|
`define sdv2 6'b101001
|
`define sdv3 6'b101010
|
`define sdv3 6'b101010
|
`define sdv4 6'b101011
|
`define sdv4 6'b101011
|
`define div1 6'b101100
|
`define div1 6'b101100
|
|
`define leas 6'b101101
|
`define init 6'b000000
|
`define init 6'b000000
|
always @(posedge CLK)
|
always @(posedge CLK)
|
|
if ((CE ==1'b1) || (RSTN ==1'b0))
|
begin
|
begin
|
case (state) // cry control
|
case (state) // cry control
|
`sml1,`sdv1: cry <= EAX[31] ^ ECX[31];
|
`sml1,`sdv1: cry <= EAX[31] ^ ECX[31];
|
`div1 : cry <= 1'b0;
|
`div1 : cry <= 1'b0;
|
default : cry <= ncry & RSTN;
|
default : cry <= ncry & RSTN;
|
endcase
|
endcase
|
prefx <= nprefx & RSTN;
|
prefx <= nprefx & RSTN;
|
state <= nstate & {6{RSTN}};
|
state <= nstate & {6{RSTN}};
|
if (cmpr) begin eqF <= neqF & RSTN; lF <= nlF & RSTN; gF <= ngF & RSTN;
|
if (cmpr) begin eqF <= neqF & RSTN; lF <= nlF & RSTN; gF <= ngF & RSTN;
|
bF <= bF & RSTN; aF <= naF & RSTN; end
|
bF <= nbF & RSTN; aF <= naF & RSTN; end
|
else begin eqF <= eqF & RSTN; lF <= lF & RSTN; gF <= gF & RSTN;
|
else begin eqF <= eqF & RSTN; lF <= lF & RSTN; gF <= gF & RSTN;
|
bF <= bF & RSTN; aF <= aF & RSTN; end
|
bF <= bF & RSTN; aF <= aF & RSTN; end
|
case(state) // EAX control
|
case(state) // EAX control
|
|
`init : EAX <= 32'b0;
|
`mul,`sml2 : EAX <= {EAX[30:0],1'b0};
|
`mul,`sml2 : EAX <= {EAX[30:0],1'b0};
|
`mul2 : EAX <= EBX;
|
`mul2 : EAX <= EBX;
|
`sml1 : EAX <= smlEAX;
|
`sml1 : EAX <= smlEAX;
|
`sml3 : if (cry==1'b0) EAX <= EBX; else EAX <= ((~EBX) + 1'b1);
|
`sml3 : if (cry==1'b0) EAX <= EBX; else EAX <= ((~EBX) + 1'b1);
|
`sdv1,`div1 : EAX <= 32'b0;
|
`sdv1,`div1 : EAX <= 32'b0;
|
`sdv3 : if (nlF==1'b0) EAX <= EAX + ( 1 << EBX_shtr); else EAX <=EAX;
|
`sdv3 : if (nlF==1'b0) EAX <= EAX + ( 1 << EBX_shtr); else EAX <=EAX;
|
`sdv4 : if (cry==1'b1) EAX <= ((~EAX) + 1'b1); else EAX <= EAX;
|
`sdv4 : if (cry==1'b1) EAX <= ((~EAX) + 1'b1); else EAX <= EAX;
|
default: if (dest==3'b000) EAX <= alu_out; else EAX<=EAX;
|
default: if (dest==3'b000) EAX <= alu_out; else EAX<=EAX;
|
endcase
|
endcase
|
case(state) // EBX control
|
case(state) // EBX control
|
|
`init : EBX <= 32'b0;
|
`jmp , `jg, `jge , `jl, `jle, `je, `jne, `imm, `call, `jb,`jbe,`ja,`jae,
|
`jmp , `jg, `jge , `jl, `jle, `je, `jne, `imm, `call, `jb,`jbe,`ja,`jae,
|
`lea : EBX<={EBX[31:16],ID[7:0],ID[15:8]};
|
`lea : EBX<={EBX[31:16],ID[7:0],ID[15:8]};
|
|
`leas : EBX<={ {24{ID[15]}} , ID[15:8]}+EBP;
|
`imm2 : EBX<={ID[7:0],ID[15:8], EBX[15:0]};
|
`imm2 : EBX<={ID[7:0],ID[15:8], EBX[15:0]};
|
`lea2 : EBX<={ID[7:0],ID[15:8], EBX[15:0]}+EBP;
|
`lea2 : EBX<={ID[7:0],ID[15:8], EBX[15:0]}+EBP;
|
`mul,`sml2 : if (ECX[0] == 1'b1) EBX <= EAX+EBX; else EBX <= EBX;
|
`mul,`sml2 : if (ECX[0] == 1'b1) EBX <= EAX+EBX; else EBX <= EBX;
|
`shift : EBX<={EBX[31:5],EBX_shtr};
|
`shift : EBX<={EBX[31:5],EBX_shtr};
|
`sdv1 : EBX<={EAX[31],ECX[31],EBX[29:0]};
|
`sdv1 : EBX<={EAX[31],ECX[31],EBX[29:0]};
|
`div1 : EBX<={ 2'b00,EBX[29:0]};
|
`div1 : EBX<={ 2'b00,EBX[29:0]};
|
`sdv2 : if (divF1==1'b0 ) EBX <= {EBX[31:5],(EBX[4:0]+1'b1)}; else EBX <= EBX;
|
`sdv2 : if (divF1==1'b0 ) EBX <= {EBX[31:5],(EBX[4:0]+1'b1)}; else EBX <= EBX;
|
`sdv3 : if (divF1==1'b1 ) EBX <= {EBX[31:5],EBX_shtr}; else EBX <= EBX;
|
`sdv3 : if (divF1==1'b1 ) EBX <= {EBX[31:5],EBX_shtr}; else EBX <= EBX;
|
default : if (dest==3'b011) EBX <= alu_out; else EBX <= EBX;
|
default : if (ID[15:8] == 8'hb3) EBX<= {EBX[31:24],ID[7:0]};
|
|
else if (dest==3'b011) EBX <= alu_out; else EBX <= EBX;
|
endcase
|
endcase
|
case(state) // ECX control
|
case(state) // ECX control
|
|
`init : ECX <= 32'b0;
|
`mul,`sml2 : ECX <= {1'b0,ECX[31:1]};
|
`mul,`sml2 : ECX <= {1'b0,ECX[31:1]};
|
`sml1,`sdv1 : ECX <= smlECX;
|
`sml1,`sdv1 : ECX <= smlECX;
|
`div1 : ECX <= ECX;
|
`div1 : ECX <= ECX;
|
`sdv2 : if (divF1==1'b0 ) ECX <= {ECX[30:0],1'b0}; else ECX<=ECX;
|
`sdv2 : if (divF1==1'b0 ) ECX <= {ECX[30:0],1'b0}; else ECX<=ECX;
|
`sdv3 : if((divF1==1'b1 ) && (divF2==1'b0)) ECX <= {1'b0,ECX[31:1]}; else ECX<=ECX;
|
`sdv3 : if((divF1==1'b1 ) && (divF2==1'b0)) ECX <= {1'b0,ECX[31:1]}; else ECX<=ECX;
|
`sdv4 : if (EBX[30] == 1'b1) ECX <= ((~ECX) + 1); else ECX<=ECX;
|
`sdv4 : if (EBX[30] == 1'b1) ECX <= ((~ECX) + 1); else ECX<=ECX;
|
default : if (dest==3'b001) ECX <= alu_out; else ECX<=ECX;
|
default : if (dest==3'b001) ECX <= alu_out; else ECX<=ECX;
|
endcase
|
endcase
|
case(state) // EDX control
|
case(state) // EDX control
|
|
`init : EDX <= 32'b0;
|
`sdv1 : EDX <= smlEAX;
|
`sdv1 : EDX <= smlEAX;
|
`div1 : EDX <= EAX;
|
`div1 : EDX <= EAX;
|
`sdv3 : if (nlF==1'b0) EDX <= EDX - ECX; else EDX <= EDX;
|
`sdv3 : if (nlF==1'b0) EDX <= EDX - ECX; else EDX <= EDX;
|
`sdv4 : if (EBX[31] == 1'b1) EDX <= ((~EDX) + 1); else EDX<=EDX;
|
`sdv4 : if (EBX[31] == 1'b1) EDX <= ((~EDX) + 1); else EDX<=EDX;
|
default : if (dest==3'b010) EDX <= alu_out; else EDX<=EDX;
|
default : if (dest==3'b010) EDX <= alu_out; else EDX<=EDX;
|
endcase
|
endcase
|
case(state) // ESP control
|
case(state) // ESP control
|
`init : ESP<=32'h00ff;
|
`init : ESP <= 32'hfffe01ff;
|
`call : ESP<=ESP - 4'b0100;
|
`call : ESP<=ESP - 4'b0100;
|
`ret2 : ESP<=ESP + 4'b0100;
|
`ret2 : ESP<=ESP + 4'b0100;
|
default: if (dest==3'b100) ESP <= alu_out; else ESP<=ESP;
|
default: if (dest==3'b100) ESP <= alu_out; else ESP<=ESP;
|
endcase
|
endcase
|
if (dest==3'b101) EBP <= alu_out; else EBP<=EBP; // EBP control
|
if (dest==3'b101) EBP <= alu_out; else EBP<=EBP; // EBP control
|
Line 135... |
Line 144... |
`jne2 : PC<=pc_neq;
|
`jne2 : PC<=pc_neq;
|
`jmp2,`call2 : PC<=pc_jp ;
|
`jmp2,`call2 : PC<=pc_jp ;
|
`ret2 : PC<=D ;
|
`ret2 : PC<=D ;
|
`mul,`mul2,`sml1,`sml2,`sml3,`sml4,`sdv1,`sdv2,`sdv3,`sdv4,`div1,
|
`mul,`mul2,`sml1,`sml2,`sml3,`sml4,`sdv1,`sdv2,`sdv3,`sdv4,`div1,
|
`shift : PC<=PC ;
|
`shift : PC<=PC ;
|
default : if (nstate == `shift) PC<=PC; else PC<=incPC ;
|
default : if (nstate == `shift) PC<=PC;
|
|
else if (ID[15:8]==8'heb) PC <= pc_sh;
|
|
else if((ID[15:8]==8'h75) && (eqF==1'b0)) PC <= pc_sh;
|
|
else if((ID[15:8]==8'h74) && (eqF==1'b1)) PC <= pc_sh;
|
|
else PC<=incPC ;
|
endcase
|
endcase
|
end
|
end
|
// muxing for source selection, used in alu & moves
|
// muxing for source selection, used in alu & moves
|
always@(src,EAX,ECX,EDX,EBX,ESP,EBP,D)
|
always@(src,EAX,ECX,EDX,EBX,ESP,EBP,D)
|
case(src)
|
case(src)
|
3'b000 : regsrc = EAX;
|
3'b000 : regsrc = EAX;
|
3'b001 : regsrc = ECX;
|
3'b001 : regsrc = ECX;
|
3'b010 : regsrc = EDX;
|
3'b010 : regsrc = EDX;
|
3'b100 : regsrc = ESP;
|
3'b100 : regsrc = ESP;
|
3'b101 : regsrc = EBP;
|
3'b101 : regsrc = EBP;
|
|
3'b110 : regsrc = 32'h04;
|
3'b111 : regsrc = D;
|
3'b111 : regsrc = D;
|
default: regsrc = EBX;
|
default: regsrc = EBX;
|
endcase
|
endcase
|
// muxing for 2nd operand selection, used in alu only
|
// muxing for 2nd operand selection, used in alu only
|
always@(dest,EAX,ECX,EDX,EBX,ESP,EBP,D)
|
always@(dest,EAX,ECX,EDX,EBX,ESP,EBP,D)
|
Line 157... |
Line 171... |
3'b000 : regdest = EAX;
|
3'b000 : regdest = EAX;
|
3'b001 : regdest = ECX;
|
3'b001 : regdest = ECX;
|
3'b010 : regdest = EDX;
|
3'b010 : regdest = EDX;
|
3'b100 : regdest = ESP;
|
3'b100 : regdest = ESP;
|
3'b101 : regdest = EBP;
|
3'b101 : regdest = EBP;
|
|
3'b110 : regdest = 32'h04;
|
3'b111 : regdest = D ;
|
3'b111 : regdest = D ;
|
default: regdest = EBX;
|
default: regdest = EBX;
|
endcase
|
endcase
|
// alu
|
// alu
|
always@(state,regdest,regsrc,ID,cry,Zregsrc,Sregsrc,sft_out,adder_out,sub_out)
|
always@(state,regdest,regsrc,ID,cry,Zregsrc,Sregsrc,sft_out,adder_out,sub_out)
|
Line 185... |
Line 200... |
// Main instruction decode
|
// Main instruction decode
|
always @(ID,state,ECX,EBX_shtr,EAX,divF1,divF2)
|
always @(ID,state,ECX,EBX_shtr,EAX,divF1,divF2)
|
begin
|
begin
|
// One cycle instructions, operand selection
|
// One cycle instructions, operand selection
|
if ((state == `fetch) || (state ==`shift))
|
if ((state == `fetch) || (state ==`shift))
|
case ({ID[15:14],ID[9],ID[7]})
|
casex ({ID[15:14],ID[13],ID[9],ID[7]})
|
4'b1000 : begin src=ID[5:3]; dest= 3'b111; end // store into ram (x89 x00)
|
5'b10x00 : begin RD=0; src=ID[5:3]; dest= 3'b111; end // store into ram (x89 x00)
|
4'b1010 : begin src= 3'b111; dest=ID[5:3]; end // load from ram (x8b x00)
|
5'b10010 : begin RD=1; src= 3'b111; dest=ID[5:3]; end // load from ram (x8b x00)
|
//4'b1001 : begin src=ID[5:3]; dest=ID[2:0]; end // reg2reg xfer (x89 xC0)
|
5'b10110 : begin RD=0; src= 3'b111; dest=ID[5:3]; end // load bl with immediate
|
4'b1011 : begin src=ID[2:0]; dest=ID[5:3]; end // reg2reg xfer (x8b xC0)
|
5'b10x11 : begin RD=0; src=ID[2:0]; dest=ID[5:3]; end // reg2reg xfer (x8b xC0)
|
//4'b0001 : begin src=ID[5:3]; dest=ID[2:0]; end // alu op
|
5'b00x11 : begin RD=0; src=ID[2:0]; dest=ID[5:3]; end // alu op
|
4'b0011 : begin src=ID[2:0]; dest=ID[5:3]; end // alu op
|
default : begin RD=0; src=ID[5:3]; dest=ID[2:0]; end // shift
|
default : begin src=ID[5:3]; dest=ID[2:0]; end // shift
|
|
endcase
|
endcase
|
else if (state==`ret)
|
else if (state==`ret)
|
begin src = 3'b011; dest = 3'b100; end
|
begin src = 3'b011; dest = 3'b100; RD=0; end
|
else if (state==`sdv3)
|
else if (state==`sdv3)
|
begin src = 3'b001; dest = 3'b010; end
|
begin src = 3'b001; dest = 3'b010; RD=0; end
|
else begin src = 3'b000; dest = 3'b000; end
|
else begin src = 3'b000; dest = 3'b000; RD=0; end
|
// instructions that require more than one cycle to execute
|
// instructions that require more than one cycle to execute
|
if (state == `fetch)
|
if (state == `fetch)
|
begin
|
begin
|
casex(ID)
|
casex(ID)
|
16'h90e9: nstate = `jmp;
|
16'h90e9: nstate = `jmp;
|
Line 216... |
Line 230... |
16'h0f8c: nstate = `jl;
|
16'h0f8c: nstate = `jl;
|
16'h0f85: nstate = `jne;
|
16'h0f85: nstate = `jne;
|
16'h0f84: nstate = `je;
|
16'h0f84: nstate = `je;
|
16'h90bb: nstate = `imm;
|
16'h90bb: nstate = `imm;
|
16'h8d9d: nstate = `lea;
|
16'h8d9d: nstate = `lea;
|
|
16'h8d5d: nstate = `leas;
|
16'h90e8: nstate = `call;
|
16'h90e8: nstate = `call;
|
16'h90c3: nstate = `ret;
|
16'h90c3: nstate = `ret;
|
16'hc1xx: nstate = `shift;
|
16'hc1xx: nstate = `shift;
|
16'hd3xx: nstate = `shift;
|
16'hd3xx: nstate = `shift;
|
16'hf7e1: nstate = `mul;
|
16'hf7e1: nstate = `mul;
|
Line 269... |
Line 284... |
assign ssregsrc = regsrc;
|
assign ssregsrc = regsrc;
|
assign ssregdest= regdest;
|
assign ssregdest= regdest;
|
assign IA = PC ;
|
assign IA = PC ;
|
assign A = (state == `call2) ? ESP : EBX ;
|
assign A = (state == `call2) ? ESP : EBX ;
|
assign Q = (state == `call2) ? incPC : regsrc ;
|
assign Q = (state == `call2) ? incPC : regsrc ;
|
assign WEN = (ID[15:8]==8'h90) ? 1'b1 :
|
assign WEN = (CE == 1'b0) ? 1'b1 :
|
(state == `call2) ? 1'b0 :
|
({ID[15:9],ID[7]}==8'h88)? 1'b0 :
|
(dest == 3'b111) ? 1'b0 : 1'b1 ;
|
(state == `call2) ? 1'b0 : 1'b1 ;
|
assign Sregsrc = ID[8] ? { {16{regsrc[15]}} , regsrc[15:0] } :
|
assign Sregsrc = ID[8] ? { {16{regsrc[15]}} , regsrc[15:0] } :
|
{ {24{regsrc[7] }} , regsrc[7:0] } ;
|
{ {24{regsrc[7] }} , regsrc[7:0] } ;
|
assign Zregsrc = ID[8] ? { 16'b0 , regsrc[15:0] } :
|
assign Zregsrc = ID[8] ? { 16'b0 , regsrc[15:0] } :
|
{ 24'b0 , regsrc[7:0] } ;
|
{ 24'b0 , regsrc[7:0] } ;
|
assign BEN = (state == `call2 ) ? 1'b1 : { prefx , ID[8] } ;
|
assign BEN = (state == `call2 ) ? 1'b1 : { prefx , ID[8] } ;
|
Line 294... |
Line 309... |
assign pc_ja = (aF ) ? pc_jp : incPC;
|
assign pc_ja = (aF ) ? pc_jp : incPC;
|
assign pc_jb = (bF ) ? pc_jp : incPC;
|
assign pc_jb = (bF ) ? pc_jp : incPC;
|
assign pc_eq = (eqF ) ? pc_jp : incPC;
|
assign pc_eq = (eqF ) ? pc_jp : incPC;
|
assign pc_neq = (eqF ) ? incPC : pc_jp;
|
assign pc_neq = (eqF ) ? incPC : pc_jp;
|
assign pc_jp = incPC+{ID,EBX[15:0]};
|
assign pc_jp = incPC+{ID,EBX[15:0]};
|
|
assign pc_sh = incPC + { {24{ID[7]}} , ID[7:0] };
|
assign sft_out = (src == 3'b111) ? {regdest[31],regdest[31:1]} : //sar
|
assign sft_out = (src == 3'b111) ? {regdest[31],regdest[31:1]} : //sar
|
(src == 3'b101) ? { 1'b0,regdest[31:1]} : //shr
|
(src == 3'b101) ? { 1'b0,regdest[31:1]} : //shr
|
{regdest[30:0],1'b0 } ; //shl
|
{regdest[30:0],1'b0 } ; //shl
|
assign adder_out= nncry + regsrc + regdest;
|
assign adder_out= nncry + regsrc + regdest;
|
assign sub_out= regdest - regsrc - nncry;
|
assign sub_out= regdest - regsrc - nncry;
|