Psst.. new poll here.
Psst.. new forums here.
Microsoft is blocking us again (TY IP Reputation!) so just use oauth login instead. :)
Paste
Pasted as Verilog by Goran Dakov ( 15 years ago )
module cpu2(input clk,input busrdy,input busfetch,output reg [31:0] addr,input [63:0] busdata, output reg [63:0] busdataw,output reg buswrt,output reg busen);
//output IP;
integer file_tty,chr_in;
reg [31:0] registers [0:31];
reg [31:0] IP=0,IPjmp,IPprev;
reg [31:0] data1 [4095:0];
reg [31:0] instr=10,instr0;
reg [31:0] val1,val2,valres;
reg [5:0] code;
reg [4:0] rA,rB,rC;
reg [15:0] const1,const2;
reg CF,VF,ZF,NF;
//reg [31:0] addr;
//reg [63:0] busdataw;
//reg buswrt=0,busen=0;
reg stall=1,init=1;
reg [7:0] initcount=255;
reg [1:0] countread,countwritten;
reg dofetch=0, dofetch0A=0, dofetch1=0, dofetch2=0, dofetch3=0, dofetch4=0, dofetch5=0, dofetch6=0, dofetch7=0, dofetch8=0;
reg [31:0] addrfetch;
reg [127:0] datafetch,datafetchw;
reg [31:0] codeaddr;
reg codewrt=0,codeen=0;
wire codemiss;
reg [3:0] codereqsize;
wire [127:0] codedata;
reg [127:0] codedataw;
wire [27:0] codeaddrflush;
cpu2data L1code(clk,codeaddr,codewrt,codeen,codemiss,codereqsize,
codedata,codedataw,codeaddrflush);
reg donecyc1=0;
reg [1:0] stginhibit=2'b10;
always @(posedge clk)
begin
codewrt=0;
codeen=0;
buswrt=0;
busen=0;
donecyc1<=0;
dofetch=0;
//cycle 1
if (init)
begin
codewrt=0;
codeen=1;
codeaddr=initcount;
codereqsize=15;
//$display("init: %d",initcount);
initcount<=initcount-1;
if (initcount==0)
begin
init<=0;
stall<=0;
end
end //if init
if (codemiss && donecyc1)
begin
//addrfetch={IPprev[31:4],4'b0000};
$display("codemiss && donecyc1");
countread=0;
countwritten=0;
dofetch=1;
stall=1;
end
if (dofetch | dofetch0A)
begin
/*case (countread)
0:
begin
addr=addrfetch;
end
endcase*/
if (busrdy)
begin
addr={IPprev[31:4],4'b0000};
buswrt=0;
busen=1;
dofetch0A<=0;
dofetch1<=1;
// addrfetch<={IPprev[31:4],4'b1000};
$display("dofetch addrfetch [%h]",{IPprev[31:4],4'b1000});
end
else
begin
dofetch1<=0;
dofetch0A<=1;
end
end //dofetch
if (dofetch1)
begin
$display("dofetch1");
if (busfetch)
begin
datafetch[63:0]=busdata;
dofetch1<=0;
dofetch2=1;
end
else
begin
dofetch1<=1;
end
end //dofetch1
if (dofetch2)
begin
$display("dofetch2");
if (busrdy)
begin
addr={IPprev[31:4],4'b1000};
buswrt=0;
busen=1;
dofetch2<=0;
dofetch3<=1;
// addrfetch<=IPprev+8;
end
else
begin
dofetch3<=0;
dofetch2<=1;
end
end //dofetch2
if (dofetch3)
begin
if (busfetch)
begin
datafetch[127:64]=busdata;
dofetch3<=0;
dofetch4=1;
end
else
begin
dofetch3<=1;
end
end //dofetch3
if (dofetch4)
begin
codeaddr={IPprev[31:4],4'b0000};
codewrt=0; //0
codeen=1;
codereqsize=15;
codedataw=datafetch;
dofetch4<=0;
dofetch5<=1;
end
if (dofetch5)
begin
if (!codemiss)
begin
datafetchw=codedata;
dofetch6=1;
end
else
begin
dofetch8=1;
end
dofetch5<=0;
end //dofetch5
if (dofetch6)
begin
if (busrdy)
begin
addr={IPprev[31:4],4'b0000};
buswrt=1;
busen=1;
busdataw=datafetchw[63:0];
dofetch7<=1;
dofetch6<=0;
//addrfetch<=IPprev+8;
end
else
begin
dofetch6<=1;
end
end //dofetch6
if (dofetch7)
begin
if (busrdy)
begin
addr={IPprev[31:4],4'b1000};
buswrt=1;
busen=1;
busdataw=datafetchw[127:64];
dofetch8=1;
dofetch7<=0;
//addrfetch<=IPprev+8;
end
else
begin
dofetch7<=1;
end
end//dofetch7
if (dofetch8)
begin
dofetch8<=0;
stall=0; //extra logic in the future
$display("fetch %h of [%h]",IPprev,datafetch);
case (IPprev[3:2])
0:instr0=datafetch[31:0];
1:instr0=datafetch[63:32];
2:instr0=datafetch[95:64];
3:instr0=datafetch[127:96];
endcase
end
if (!stall)
begin
$display("IP: [%h]",IP);
codewrt=0;
codeen=1;
codeaddr=IP;
codereqsize=2;
IPprev<=IP;
IP<=IP+4;
donecyc1<=1;
stginhibit[1]<=1;
end
/*instr0=code1[IP[13:2]];
instr<=instr0;
code<=instr0[5:0];
rA<=instr0[10:6]; //op 1 register
rB<=instr0[15:11]; //op 2 register
rC<=instr0[20:16]; //write register
const1<={instr0[15:11],instr0[31:21]};
const2<={instr0[20:16],instr0[31:21]};
if (instr0[31])
IPjmp<=IP+{14'b11111111111111,instr0[31:31],rC,2'b0} ;
else IPjmp<=IP+{14'b0,instr0[31:31],rC,2'b0};
IP<=IP+4;*/
//if (!stall && donecyc1)
// instr0=codedata[31:0];
//cycle 2
if ((!stginhibit[1]) && (!stall))
begin
code=instr0[5:0];
rA=instr0[10:6]; //op 1 register
rB=instr0[15:11]; //op 2 register
rC=instr0[20:16]; //write register
const1={instr0[15:11],instr0[31:21]};
const2={instr0[20:16],instr0[31:21]};
if (instr0[31])
IPjmp=IP+{14'b11111111111111,instr0[31:16],2'b0} ;
else IPjmp=IP+{14'b0,instr0[31:16],2'b0};
$display("instr : %h,code %d",instr0,code);
end
if ((!stginhibit[1]) && (!stall))
begin
val1=registers[rA]; val2=registers[rB];
case(code) //perform operations
0:begin
valres={const1,val1[15:0]};
end
1:begin
valres={16'b0, const1}; //maybe should be signed???
end
2:begin
valres=val1 & val2;
end
3:begin
valres=val1 & {16'b0, const1};
end
4:begin
valres=val1 | val2;
end
5:begin
valres=val1 | {16'b0, const1};
end
6:begin
valres=val1 ^ val2;
end
7:begin
valres=val1 ^ {16'b0, const1};
end
8:begin
valres=val1 + val2;
end
9:begin
valres=val1 +{16'b0, const1};
end
8:begin
valres=val1 - val2;
end
9:begin
valres=val1 -{16'b0, const1};
end
//10:no-op
11:begin
valres=val1 & {16'b1111111111111111, const1};
end
32:begin
{CF,valres}=val1 - val2;
NF=valres[31];
ZF=(val1==val2);
VF<=(val1[31] & !val2[31] & !valres[31]) | (!val1[31] & val2[31] & valres[31]);
if (CF) begin IP<=IPjmp; stginhibit<=2'b10; end //jump costs 2 cycle if taken; prediction tbd
end
33:begin
{CF,valres}=val1 - val2;
NF=valres[31];
ZF=(val1==val2);
VF<=(val1[31] & !val2[31] & !valres[31]) | (!val1[31] & val2[31] & valres[31]);
if (!CF) begin IP<=IPjmp; stginhibit<=2'b10; end
end
34:begin
{CF,valres}=val1 - val2;
NF=valres[31];
ZF=(val1==val2);
VF<=(val1[31] & !val2[31] & !valres[31]) | (!val1[31] & val2[31] & valres[31]);
$display("cjeq %d,%d=%d",val1,val2,ZF);
if (ZF) begin IP<=IPjmp; stginhibit<=2'b10; end
end
35:begin
{CF,valres}=val1 - val2;
NF=valres[31];
ZF=(val1==val2);
VF<=(val1[31] & !val2[31] & !valres[31]) | (!val1[31] & val2[31] & valres[31]);
if (!ZF) begin IP<=IPjmp; stginhibit<=2'b10; end
end
36:begin //redundant
{CF,valres}=val1 - val2;
NF=valres[31];
ZF=(val1==val2);
VF<=(val1[31] & !val2[31] & !valres[31]) | (!val1[31] & val2[31] & valres[31]);
if (CF ^ ZF) begin IP<=IPjmp; stginhibit<=2'b10; end
end
37:begin //redundant
{CF,valres}=val1 - val2;
NF=valres[31];
ZF=(val1==val2);
VF<=(val1[31] & !val2[31] & !valres[31]) | (!val1[31] & val2[31] & valres[31]);
if (!(CF ^ ZF)) begin IP<=IPjmp; stginhibit<=2'b10; end
end
38:begin
{CF,valres}=val1 - val2;
NF=valres[31];
ZF=(val1==val2);
VF<=(val1[31] & !val2[31] & !valres[31]) | (!val1[31] & val2[31] & valres[31]);
if (NF) begin IP<=IPjmp; stginhibit<=2'b10; end
end
39:begin
{CF,valres}=val1 - val2;
NF=valres[31];
ZF=(val1==val2);
VF<=(val1[31] & !val2[31] & !valres[31]) | (!val1[31] & val2[31] & valres[31]);
if (!NF) begin IP<=IPjmp; stginhibit<=2'b10; end
end
40:begin
{CF,valres}=val1 - val2;
NF=valres[31];
ZF=(val1==val2);
VF<=(val1[31] & !val2[31] & !valres[31]) | (!val1[31] & val2[31] & valres[31]);
if (VF ^ NF) begin IP<=IPjmp; stginhibit<=2'b10; end
end
41:begin
{CF,valres}=val1 - val2;
NF=valres[31];
ZF=(val1==val2);
VF<=(val1[31] & !val2[31] & !valres[31]) | (!val1[31] & val2[31] & valres[31]);
if (!(VF ^ NF)) begin IP<=IPjmp; stginhibit<=2'b10; end
end
42:begin
{CF,valres}=val1 - val2;
NF=valres[31];
ZF=(val1==val2);
VF<=(val1[31] & !val2[31] & !valres[31]) | (!val1[31] & val2[31] & valres[31]);
if ((VF ^ NF) | ZF) begin IP<=IPjmp; stginhibit<=2'b10; end
end
43:begin
{CF,valres}=val1 - val2;
NF=valres[31];
ZF=(val1==val2);
VF<=(val1[31] & !val2[31] & !valres[31]) | (!val1[31] & val2[31] & valres[31]);
if (!((VF ^ NF) |ZF)) begin IP<=IPjmp; stginhibit<=2'b10; end
end
44:begin
{CF,valres}=val1 - val2;
NF=valres[31];
ZF=(val1==val2);
VF<=(val1[31] & !val2[31] & !valres[31]) | (!val1[31] & val2[31] & valres[31]);
if (VF) begin IP<=IPjmp; stginhibit<=2'b10; end
end
45:begin
{CF,valres}=val1 - val2;
NF=valres[31];
ZF=(val1==val2);
VF<=(val1[31] & !val2[31] & !valres[31]) | (!val1[31] & val2[31] & valres[31]);
if (!VF) begin IP<=IPjmp; stginhibit<=2'b10; end
end
56:begin
if (val1[31:30]!=2'b11) begin
valres=data1[val1[13:2]]; //offset tdb maybe
end
else begin //io adress
chr_in=$fgetc(file_tty);
valres=chr_in;
end
end
58:begin
if (val1[31:30]!=2'b11)
begin
$display("ldb [%d]",val1);
case (val1[1:0])
0:valres=data1[val1[13:2]][7:0];
1:valres=data1[val1[13:2]][15:8];
2:valres=data1[val1[13:2]][23:16];
3:valres=data1[val1[13:2]][31:24];
endcase
end
else begin //io adress
chr_in=0;//$fgetc(file_tty);
valres=chr_in;
end
end
60:begin
$display("stl %h,%h",val1,val2);
if (val1[31:30]!=2'b11) begin
data1[val1[13:2]]=val2;
end
else begin
$display("%c",val2[7:0]);
end
end
endcase
end
if ((!stginhibit[1]) && !stall)
case (code) //write result to register file
0,1,2,3,4,5,6,7,8,9,11,48:
begin
registers[rC]<=valres;
$display("regstore r%d,r%d,r%d=%h",rA,rB,rC,valres);
end
endcase
end
initial begin
//clk=0;
//IP=0; instr=10;
//file_tty=$fopen("/dev/tty","r+");
end
endmodule
Revise this Paste