URL
https://opencores.org/ocsvn/suslik/suslik/trunk
Subversion Repositories suslik
Compare Revisions
- This comparison shows the changes necessary to convert path
/suslik
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/trunk/rtl/datacache.v
0,0 → 1,453
`include "config.v" |
|
module datacache(input clk,input stall,input [4:0] stginhibit,input [4:0] codemiss,input [31:0] addrA,output `muxnet [511:0] dataA,input [511:0] cacheLine,input [31:0] writeData,output `muxnet cacheHit,input readen,input writeen,input insert,input initEntry,input [1:0] readsz,output `muxnet [31:0] oldAddr); |
|
wire tagwe; |
wire [31:0] tagAddrA; |
wire [31:0] tagAddrW; |
wire [119:0] tagDataA; |
`muxnet [119:0] tagDataW; |
reg [31:0] tagAddrA_reg; |
|
reg readen_reg=0; |
reg writeen_reg=0; |
reg insert_reg=0; |
reg initEntry_reg=0; |
reg [119:0] tagDataA_fwd; |
wire [119:0] ramTagDataA; |
reg tag_fwd=0; |
|
wire [31:0] pad0; |
wire [31:0] pad1; |
wire [31:0] pad2; |
wire [31:0] pad3; |
wire [1:0] pos0; |
wire [1:0] pos1; |
wire [1:0] pos2; |
wire [1:0] pos3; |
wire val0; |
wire val1; |
wire val2; |
wire val3; |
wire dir0; |
wire dir1; |
wire dir2; |
wire dir3; |
|
wire [1:0] newPos0; |
wire [1:0] newPos1; |
wire [1:0] newPos2; |
wire [1:0] newPos3; |
|
`muxnet hit3,hit2,hit1,hit0; |
wire hit; |
|
wire ram0We,ram1We,ram2We,ram3We; |
wire [31:0] ramAddrW; |
wire [31:0] ramAddrA; |
wire [511:0] ramDataR0; |
wire [511:0] ramDataR1; |
wire [511:0] ramDataR2; |
wire [511:0] ramDataR3; |
wire [511:0] ramDataW0; |
wire [511:0] ramDataW1; |
wire [511:0] ramDataW2; |
wire [511:0] ramDataW3; |
wire [511:0] ramDataWA0; |
wire [511:0] ramDataWA1; |
wire [511:0] ramDataWA2; |
wire [511:0] ramDataWA3; |
reg [511:0] cacheLine_reg; |
|
wire [31:0] dataA0; |
wire [31:0] dataA1; |
wire [31:0] dataA2; |
wire [31:0] dataA3; |
|
reg [1:0] readsz_reg; |
|
|
datacacheramtag tag0(clk,tagwe,tagAddrA[11:6],tagAddrW[11:6],ramTagDataA,tagDataW); |
datacache_get_new_pos newpos0(pos0,pos1,pos2,pos3,hit0,hit1,hit2,hit3,newPos0,newPos1,newPos2,newPos3); |
datacacheramfwd ram0(clk,ram0We,ramAddrA,ramAddrW,ramDataR0,ramDataW0); |
datacacheramfwd ram1(clk,ram1We,ramAddrA,ramAddrW,ramDataR1,ramDataW1); |
datacacheramfwd ram2(clk,ram2We,ramAddrA,ramAddrW,ramDataR2,ramDataW2); |
datacacheramfwd ram3(clk,ram3We,ramAddrA,ramAddrW,ramDataR3,ramDataW3); |
datacache_data_sel data_sel0(ramDataR0,tagAddrA_reg[5:0],readsz_reg,dataA0); |
datacache_data_sel data_sel1(ramDataR1,tagAddrA_reg[5:0],readsz_reg,dataA1); |
datacache_data_sel data_sel2(ramDataR2,tagAddrA_reg[5:0],readsz_reg,dataA2); |
datacache_data_sel data_sel3(ramDataR3,tagAddrA_reg[5:0],readsz_reg,dataA3); |
datacache_get_write_data wrtdat0 (ramDataR0,writeData,tagAddrA_reg,readsz_reg,ramDataWA0); |
datacache_get_write_data wrtdat1 (ramDataR1,writeData,tagAddrA_reg,readsz_reg,ramDataWA1); |
datacache_get_write_data wrtdat2 (ramDataR2,writeData,tagAddrA_reg,readsz_reg,ramDataWA2); |
datacache_get_write_data wrtdat3 (ramDataR3,writeData,tagAddrA_reg,readsz_reg,ramDataWA3); |
|
assign tagAddrA=addrA; |
assign tagDataA=tag_fwd ? tagDataA_fwd : ramTagDataA; |
assign tagwe=((readen_reg || writeen_reg) && !stall && !stginhibit[4] && !codemiss[4] ) || insert_reg || initEntry_reg; |
assign tagAddrW=tagAddrA_reg; |
|
assign { pad3[31:6],pad2[31:6],pad1[31:6],pad0[31:6], |
pos3,pos2,pos1,pos0, |
val3,val2,val1,val0, |
dir3,dir2,dir1,dir0 } = tagDataA; |
assign pad3[5:0]=6'b0; |
assign pad2[5:0]=6'b0; |
assign pad1[5:0]=6'b0; |
assign pad0[5:0]=6'b0; |
|
assign hit3=(readen_reg || writeen_reg) ? val3 && (pad3[31:6]==tagAddrA_reg[31:6]) : 1'b`muxval; |
assign hit2=(readen_reg || writeen_reg) ? val2 && (pad2[31:6]==tagAddrA_reg[31:6]) : 1'b`muxval; |
assign hit1=(readen_reg || writeen_reg) ? val1 && (pad1[31:6]==tagAddrA_reg[31:6]) : 1'b`muxval; |
assign hit0=(readen_reg || writeen_reg) ? val0 && (pad0[31:6]==tagAddrA_reg[31:6]) : 1'b`muxval; |
|
assign hit3=insert_reg ? (pos3==2'b11) : 1'b`muxval; |
assign hit2=insert_reg ? (pos2==2'b11) : 1'b`muxval; |
assign hit1=insert_reg ? (pos1==2'b11) : 1'b`muxval; |
assign hit0=insert_reg ? (pos0==2'b11) : 1'b`muxval; |
|
assign hit3=(!insert_reg && !readen_reg && !writeen_reg) ? 1'b0 : 1'b`muxval; |
assign hit2=(!insert_reg && !readen_reg && !writeen_reg) ? 1'b0 : 1'b`muxval; |
assign hit1=(!insert_reg && !readen_reg && !writeen_reg) ? 1'b0 : 1'b`muxval; |
assign hit0=(!insert_reg && !readen_reg && !writeen_reg) ? 1'b0 : 1'b`muxval; |
|
assign hit=hit3 || hit2 || hit1 || hit0; |
|
assign cacheHit= (insert_reg && hit0) ? val0 && dir0 : 1'b`muxval; |
assign cacheHit= (insert_reg && hit1) ? val1 && dir1 : 1'b`muxval; |
assign cacheHit= (insert_reg && hit2) ? val2 && dir2 : 1'b`muxval; |
assign cacheHit= (insert_reg && hit3) ? val3 && dir3 : 1'b`muxval; |
assign cacheHit= insert_reg ? 1'b`muxval : hit; |
|
assign tagDataW=readen_reg ? { pad3[31:6],pad2[31:6],pad1[31:6],pad0[31:6], |
newPos3,newPos2,newPos1,newPos0, |
val3,val2,val1,val0, |
dir3,dir2,dir1,dir0 } : 120'b`muxval; |
assign tagDataW=(writeen_reg && hit0) ? { pad3[31:6],pad2[31:6],pad1[31:6],pad0[31:6], |
newPos3,newPos2,newPos1,newPos0, |
val3,val2,val1,val0, |
dir3,dir2,dir1,1'b1 } : 120'b`muxval; |
assign tagDataW=(writeen_reg && hit1) ? { pad3[31:6],pad2[31:6],pad1[31:6],pad0[31:6], |
newPos3,newPos2,newPos1,newPos0, |
val3,val2,val1,val0, |
dir3,dir2,1'b1,dir0 } : 120'b`muxval; |
assign tagDataW=(writeen_reg && hit2) ? { pad3[31:6],pad2[31:6],pad1[31:6],pad0[31:6], |
newPos3,newPos2,newPos1,newPos0, |
val3,val2,val1,val0, |
dir3,1'b1,dir1,dir0 } : 120'b`muxval; |
assign tagDataW=(writeen_reg && hit3) ? { pad3[31:6],pad2[31:6],pad1[31:6],pad0[31:6], |
newPos3,newPos2,newPos1,newPos0, |
val3,val2,val1,val0, |
1'b1,dir2,dir1,dir0 } : 120'b`muxval; |
assign tagDataW=(writeen_reg && !hit) ? { pad3[31:6],pad2[31:6],pad1[31:6],pad0[31:6], |
newPos3,newPos2,newPos1,newPos0, |
val3,val2,val1,val0, |
dir3,dir2,dir1,dir0 } : 120'b`muxval; |
|
assign tagDataW=(insert_reg && hit0) ? { pad3[31:6],pad2[31:6],pad1[31:6],tagAddrA_reg[31:6], |
newPos3,newPos2,newPos1,newPos0, |
val3,val2,val1,1'b1, |
dir3,dir2,dir1,1'b0 } : 120'b`muxval; |
assign tagDataW=(insert_reg && hit1) ? { pad3[31:6],pad2[31:6],tagAddrA_reg[31:6],pad0[31:6], |
newPos3,newPos2,newPos1,newPos0, |
val3,val2,1'b1,val0, |
dir3,dir2,1'b0,dir0 } : 120'b`muxval; |
assign tagDataW=(insert_reg && hit2) ? { pad3[31:6],tagAddrA_reg[31:6],pad1[31:6],pad0[31:6], |
newPos3,newPos2,newPos1,newPos0, |
val3,1'b1,val1,val0, |
dir3,1'b0,dir1,dir0 } : 120'b`muxval; |
assign tagDataW=(insert_reg && hit3) ? { tagAddrA_reg[31:6],pad2[31:6],pad1[31:6],pad0[31:6], |
newPos3,newPos2,newPos1,newPos0, |
1'b1,val2,val1,val0, |
1'b0,dir2,dir1,dir0 } : 120'b`muxval; |
// assign tagDataW=(insert_reg && !hit) ? 120'b0 : 120'bz; |
assign tagDataW=initEntry_reg ? { 26'b0,26'b0,26'b0,26'b0, |
2'b11,2'b10,2'b01,2'b00, |
1'b0,1'b0,1'b0,1'b0, |
1'b0,1'b0,1'b0,1'b0} : 120'b`muxval; |
assign tagDataW=(!insert_reg && !readen_reg && !writeen_reg && !initEntry_reg) ? 120'b0 : 120'b`muxval; |
|
assign dataA=(!insert_reg && hit0) ? {480'b0,dataA0} : 512'b`muxval; |
assign dataA=(!insert_reg && hit1) ? {480'b0,dataA1} : 512'b`muxval; |
assign dataA=(!insert_reg && hit2) ? {480'b0,dataA2} : 512'b`muxval; |
|
assign dataA=(!insert_reg && hit3) ? {480'b0,dataA3} : 512'b`muxval; |
|
assign dataA=(insert_reg && hit0) ? ramDataR0 : 512'b`muxval; |
|
assign dataA=(insert_reg && hit1) ? ramDataR1 : 512'b`muxval; |
assign dataA=(insert_reg && hit2) ? ramDataR2 : 512'b`muxval; |
assign dataA=(insert_reg && hit3) ? ramDataR3 : 512'b`muxval; |
|
assign dataA= hit ? 512'b`muxval : 512'b0; //change to accomodate non-read ops |
|
assign ramDataW0=insert_reg ? cacheLine_reg : ramDataWA0; |
assign ramDataW1=insert_reg ? cacheLine_reg : ramDataWA1; |
assign ramDataW2=insert_reg ? cacheLine_reg : ramDataWA2; |
assign ramDataW3=insert_reg ? cacheLine_reg : ramDataWA3; |
|
assign ram0We=(insert_reg || (writeen_reg && !stall && !codemiss[4] && !stginhibit[4])) && hit0; |
assign ram1We=(insert_reg || (writeen_reg && !stall && !codemiss[4] && !stginhibit[4])) && hit1; |
assign ram2We=(insert_reg || (writeen_reg && !stall && !codemiss[4] && !stginhibit[4])) && hit2; |
assign ram3We=(insert_reg || (writeen_reg && !stall && !codemiss[4] && !stginhibit[4])) && hit3; |
|
assign oldAddr=(insert_reg && hit0) ? pad0 : 32'b`muxval; |
assign oldAddr=(insert_reg && hit1) ? pad1 : 32'b`muxval; |
assign oldAddr=(insert_reg && hit2) ? pad2 : 32'b`muxval; |
assign oldAddr=(insert_reg && hit3) ? pad3 : 32'b`muxval; |
assign oldAddr=(!insert_reg) ? 32'b0 : 32'b`muxval; |
|
assign ramAddrA={tagAddrA[31:6],6'b0}; |
assign ramAddrW={tagAddrA_reg[31:6],6'b0}; |
|
always @(posedge clk) |
begin |
tagDataA_fwd<=tagDataW; |
tag_fwd<=tagwe && (addrA[11:6]==tagAddrA_reg[11:6]); |
tagAddrA_reg<=tagAddrA; |
readen_reg<=readen; |
writeen_reg<=writeen; |
insert_reg<=insert; |
initEntry_reg<=initEntry; |
cacheLine_reg<=cacheLine; |
readsz_reg<=readsz; |
end |
|
endmodule |
|
module datacacheram(input clk,input we,input [5:0] addrA,input [5:0] addrW,output reg [511:0] dataA,input [511:0] dataW); |
reg [511:0] ram [63:0]; |
|
always @(posedge clk) |
begin |
dataA<=ram[addrA]; |
if (we) ram[addrW]<=dataW; |
end |
|
endmodule |
|
module datacacheramfwd(input clk,input we,input [31:0] addrA,input [31:0] addrW,output wire [511:0] dataA,input [511:0] dataW); |
wire [511:0] ramDataA; |
reg we_reg; |
reg [511:0] dataW_reg; |
reg [31:0] addrW_reg; |
reg fwd=0; |
|
datacacheram ram0(clk,we,addrA[11:6],addrW[11:6],ramDataA,dataW); |
|
|
assign dataA=fwd ? dataW_reg : ramDataA; |
|
always@(posedge clk) |
begin |
we_reg<=we; |
dataW_reg<=dataW; |
addrW_reg<=addrW; |
fwd<=we && (addrW[11:6]==addrA[11:6]); |
end |
|
endmodule |
|
/* |
tag for 4 way set-asociative LRU data cache |
{ |
{pad3,pad2,pad1,pad0}, //4x 26 bit physical address |
{pos3,pos2,pos1,pos0}, //4xeach 2 bit LRU position, 8 bit |
{val3,val2,val1,val0} //4x 1 bit valid entry, 4 bit |
{dir3,dir2,dir1,dir0} //4x dirty bit |
} |
length =30*4=120 bit tag |
*/ |
|
module datacacheramtag(input clk,input we,input [5:0] addrA,input [5:0] addrW,output reg [119:0] dataA,input [119:0] dataW); |
reg [119:0] ram [63:0]; |
|
always @(posedge clk) |
begin |
dataA<=ram[addrA]; |
if (we) ram[addrW]<=dataW; |
end |
|
endmodule |
|
module datacache_get_new_pos(input [1:0] pos0,input [1:0] pos1,input [1:0] pos2,input [1:0] pos3, |
input hit0,input hit1,input hit2,input hit3, |
output `muxnet [1:0] newPos0,output `muxnet [1:0] newPos1,output `muxnet [1:0] newPos2,output `muxnet [1:0] newPos3); |
wire hit; |
|
assign hit=hit0 || hit1 || hit2 || hit3; |
|
assign newPos0=hit0 ? 0 : 2'b`muxval; |
assign newPos1=hit0 ? ((pos1<pos0) ? pos1+1:pos1 ) : 2'b`muxval; |
assign newPos2=hit0 ? ((pos2<pos0) ? pos2+1:pos2 ) : 2'b`muxval; |
assign newPos3=hit0 ? ((pos3<pos0) ? pos3+1:pos3 ) : 2'b`muxval; |
|
assign newPos1=hit1 ? 0 : 2'b`muxval; |
assign newPos0=hit1 ? ((pos0<pos1) ? pos0+1:pos0 ) : 2'b`muxval; |
assign newPos2=hit1 ? ((pos2<pos1) ? pos2+1:pos2 ) : 2'b`muxval; |
assign newPos3=hit1 ? ((pos3<pos1) ? pos3+1:pos3 ) : 2'b`muxval; |
|
assign newPos2=hit2 ? 0 : 2'b`muxval; |
assign newPos1=hit2 ? ((pos1<pos2) ? pos1+1:pos1 ) : 2'b`muxval; |
assign newPos0=hit2 ? ((pos0<pos2) ? pos0+1:pos0 ) : 2'b`muxval; |
assign newPos3=hit2 ? ((pos3<pos2) ? pos3+1:pos3 ) : 2'b`muxval; |
|
assign newPos3=hit3 ? 0 : 2'b`muxval; |
assign newPos1=hit3 ? ((pos1<pos3) ? pos1+1:pos1 ) : 2'b`muxval; |
assign newPos2=hit3 ? ((pos2<pos3) ? pos2+1:pos2 ) : 2'b`muxval; |
assign newPos0=hit3 ? ((pos0<pos3) ? pos0+1:pos0 ) : 2'b`muxval; |
|
assign newPos0=hit ? 2'b`muxval : pos0; |
assign newPos1=hit ? 2'b`muxval : pos1; |
assign newPos2=hit ? 2'b`muxval : pos2; |
assign newPos3=hit ? 2'b`muxval : pos3; |
|
endmodule |
|
|
module datacache_data_sel(input [511:0] dataIn,input [5:0] sel, input [1:0] readsz, output `muxnet [31:0] dataOut); |
wire [255:0] bit5Data; |
wire [127:0] bit4Data; |
wire [63:0] bit3Data; |
wire [31:0] data32; |
wire [15:0] data16; |
wire [7:0] data8; |
|
assign bit5Data=sel[5] ? dataIn[511:256] : dataIn[255:0]; |
assign bit4Data=sel[4] ? bit5Data[255:128] : bit5Data[127:0]; |
assign bit3Data=sel[3] ? bit4Data[127:64] : bit4Data[63:0]; |
|
assign data32 =sel[2] ? bit3Data[63:32] : bit3Data[31:0]; |
assign data16 =sel[1] ? data32[31:16] : data32[15:0]; |
assign data8 =sel[0] ? data16[15:8] : data16[7:0]; |
|
assign dataOut=(readsz==0) ? {24'b0,data8} : 32'b`muxval; |
assign dataOut=(readsz==1) ? {16'b0,data16} : 32'b`muxval; |
assign dataOut=(readsz==2) ? data32 : 32'b`muxval; |
assign dataOut=(readsz==4) ? 32'b0 : 32'b`muxval; |
|
endmodule |
|
|
module datacache_write_shift(input [31:0] dataIn,input [1:0] writesz,input [31:0] addr, output wire [511:0] dataOut, output wire [63:0] byteEnable); |
`muxnet [511:0] data6; |
wire [511:0] data5; |
wire [511:0] data4; |
wire [511:0] data3; |
wire [511:0] data2; |
wire [511:0] data1; |
wire [511:0] data0; |
|
`muxnet [63:0] byteEnable6; |
wire [63:0] byteEnable5; |
wire [63:0] byteEnable4; |
wire [63:0] byteEnable3; |
wire [63:0] byteEnable2; |
wire [63:0] byteEnable1; |
wire [63:0] byteEnable0; |
|
// change data6 to explicit mux! |
assign data6=(writesz==0) ? {504'b0,dataIn[7:0]} : 512'b`muxval; |
assign data6=(writesz==1) ? {496'b0,dataIn[15:0]} : 512'b`muxval; |
assign data6=(writesz==2) ? {480'b0,dataIn} : 512'b`muxval; |
assign data6=(writesz==3) ? 512'b0 : 512'b`muxval; |
|
assign data5=addr[5] ? { data6[255:0], 256'b0 }: data6; |
assign data4=addr[4] ? { data5[383:0], 128'b0 }: data5; |
assign data3=addr[3] ? { data4[447:0], 64'b0 }: data4; |
assign data2=addr[2] ? { data3[479:0], 32'b0 }: data3; |
assign data1=addr[1] ? { data2[495:0], 16'b0 }: data2; |
assign data0=addr[0] ? { data1[503:0], 8'b0 }: data1; |
|
assign dataOut=data0; |
//change byteEnable6 to explicit mux! |
assign byteEnable6=(writesz==0) ? 64'b0001 : 64'b`muxval; |
assign byteEnable6=(writesz==1) ? 64'b0011 : 64'b`muxval; |
assign byteEnable6=(writesz==2) ? 64'b1111 : 64'b`muxval; |
assign byteEnable6=(writesz==3) ? 64'b0000 : 64'b`muxval; |
|
assign byteEnable5=addr[5] ? { byteEnable6[31:0],32'b0 } : byteEnable6; |
assign byteEnable4=addr[4] ? { byteEnable5[47:0],16'b0 } : byteEnable5; |
assign byteEnable3=addr[3] ? { byteEnable4[55:0],8'b0 } : byteEnable4; |
assign byteEnable2=addr[2] ? { byteEnable3[59:0],4'b0 } : byteEnable3; |
assign byteEnable1=addr[1] ? { byteEnable2[61:0],2'b0 } : byteEnable2; |
assign byteEnable0=addr[0] ? { byteEnable1[62:0],1'b0 } : byteEnable1; |
|
assign byteEnable=byteEnable0; |
|
endmodule |
|
|
module datacache_get_write_data(input [511:0] prevCacheline, input [31:0] data, input [31:0] addr, input [1:0] writesz,output wire [511:0] newCacheline); |
wire [511:0] cacheLine1; |
wire [63:0] byteEnable; |
datacache_write_shift shift0(data,writesz,addr,cacheLine1,byteEnable); |
assign newCacheline= |
{ |
byteEnable[63] ? cacheLine1[511:504] : prevCacheline[511:504], |
byteEnable[62] ? cacheLine1[503:496] : prevCacheline[503:496], |
byteEnable[61] ? cacheLine1[495:488] : prevCacheline[495:488], |
byteEnable[60] ? cacheLine1[487:480] : prevCacheline[487:480], |
byteEnable[59] ? cacheLine1[479:472] : prevCacheline[479:472], |
byteEnable[58] ? cacheLine1[471:464] : prevCacheline[471:464], |
byteEnable[57] ? cacheLine1[463:456] : prevCacheline[463:456], |
byteEnable[56] ? cacheLine1[455:448] : prevCacheline[455:448], |
byteEnable[55] ? cacheLine1[447:440] : prevCacheline[447:440], |
byteEnable[54] ? cacheLine1[439:432] : prevCacheline[439:432], |
byteEnable[53] ? cacheLine1[431:424] : prevCacheline[431:424], |
byteEnable[52] ? cacheLine1[423:416] : prevCacheline[423:416], |
byteEnable[51] ? cacheLine1[415:408] : prevCacheline[415:408], |
byteEnable[50] ? cacheLine1[407:400] : prevCacheline[407:400], |
byteEnable[49] ? cacheLine1[399:392] : prevCacheline[399:392], |
byteEnable[48] ? cacheLine1[391:384] : prevCacheline[391:384], |
byteEnable[47] ? cacheLine1[383:376] : prevCacheline[383:376], |
byteEnable[46] ? cacheLine1[375:368] : prevCacheline[375:368], |
byteEnable[45] ? cacheLine1[367:360] : prevCacheline[367:360], |
byteEnable[44] ? cacheLine1[359:352] : prevCacheline[359:352], |
byteEnable[43] ? cacheLine1[351:344] : prevCacheline[351:344], |
byteEnable[42] ? cacheLine1[343:336] : prevCacheline[343:336], |
byteEnable[41] ? cacheLine1[335:328] : prevCacheline[335:328], |
byteEnable[40] ? cacheLine1[327:320] : prevCacheline[327:320], |
byteEnable[39] ? cacheLine1[319:312] : prevCacheline[319:312], |
byteEnable[38] ? cacheLine1[311:304] : prevCacheline[311:304], |
byteEnable[37] ? cacheLine1[303:296] : prevCacheline[303:296], |
byteEnable[36] ? cacheLine1[295:288] : prevCacheline[295:288], |
byteEnable[35] ? cacheLine1[287:280] : prevCacheline[287:280], |
byteEnable[34] ? cacheLine1[279:272] : prevCacheline[279:272], |
byteEnable[33] ? cacheLine1[271:264] : prevCacheline[271:264], |
byteEnable[32] ? cacheLine1[263:256] : prevCacheline[263:256], |
byteEnable[31] ? cacheLine1[255:248] : prevCacheline[255:248], |
byteEnable[30] ? cacheLine1[247:240] : prevCacheline[247:240], |
byteEnable[29] ? cacheLine1[239:232] : prevCacheline[239:232], |
byteEnable[28] ? cacheLine1[231:224] : prevCacheline[231:224], |
byteEnable[27] ? cacheLine1[223:216] : prevCacheline[223:216], |
byteEnable[26] ? cacheLine1[215:208] : prevCacheline[215:208], |
byteEnable[25] ? cacheLine1[207:200] : prevCacheline[207:200], |
byteEnable[24] ? cacheLine1[199:192] : prevCacheline[199:192], |
byteEnable[23] ? cacheLine1[191:184] : prevCacheline[191:184], |
byteEnable[22] ? cacheLine1[183:176] : prevCacheline[183:176], |
byteEnable[21] ? cacheLine1[175:168] : prevCacheline[175:168], |
byteEnable[20] ? cacheLine1[167:160] : prevCacheline[167:160], |
byteEnable[19] ? cacheLine1[159:152] : prevCacheline[159:152], |
byteEnable[18] ? cacheLine1[151:144] : prevCacheline[151:144], |
byteEnable[17] ? cacheLine1[143:136] : prevCacheline[143:136], |
byteEnable[16] ? cacheLine1[135:128] : prevCacheline[135:128], |
byteEnable[15] ? cacheLine1[127:120] : prevCacheline[127:120], |
byteEnable[14] ? cacheLine1[119:112] : prevCacheline[119:112], |
byteEnable[13] ? cacheLine1[111:104] : prevCacheline[111:104], |
byteEnable[12] ? cacheLine1[103:96] : prevCacheline[103:96], |
byteEnable[11] ? cacheLine1[95:88] : prevCacheline[95:88], |
byteEnable[10] ? cacheLine1[87:80] : prevCacheline[87:80], |
byteEnable[9] ? cacheLine1[79:72] : prevCacheline[79:72], |
byteEnable[8] ? cacheLine1[71:64] : prevCacheline[71:64], |
byteEnable[7] ? cacheLine1[63:56] : prevCacheline[63:56], |
byteEnable[6] ? cacheLine1[55:48] : prevCacheline[55:48], |
byteEnable[5] ? cacheLine1[47:40] : prevCacheline[47:40], |
byteEnable[4] ? cacheLine1[39:32] : prevCacheline[39:32], |
byteEnable[3] ? cacheLine1[31:24] : prevCacheline[31:24], |
byteEnable[2] ? cacheLine1[23:16] : prevCacheline[23:16], |
byteEnable[1] ? cacheLine1[15:8] : prevCacheline[15:8], |
byteEnable[0] ? cacheLine1[7:0] : prevCacheline[7:0] |
}; |
|
endmodule |
/trunk/rtl/codecache.v
0,0 → 1,209
`include "config.v" |
|
module codecache(input clk,input [31:0] addrA,output `muxnet [31:0] dataA,input [511:0] cacheLine,output wire hit,input readen,input insert,input initEntry); |
wire tagwe; |
wire [31:0] tagAddrA; |
wire [31:0] tagAddrW; |
wire [115:0] tagDataA; |
`muxnet [115:0] tagDataW; |
reg [31:0] tagAddrA_reg; |
|
wire ram0We,ram1We,ram2We,ram3We; |
wire [31:0] ramAddrW; |
wire [511:0] ramDataR0; |
wire [511:0] ramDataR1; |
wire [511:0] ramDataR2; |
wire [511:0] ramDataR3; |
wire [511:0] ramDataW; |
reg [511:0] cacheLine_reg; |
|
wire [31:0] pad0; |
wire [31:0] pad1; |
wire [31:0] pad2; |
wire [31:0] pad3; |
wire [1:0] pos0; |
wire [1:0] pos1; |
wire [1:0] pos2; |
wire [1:0] pos3; |
wire val0; |
wire val1; |
wire val2; |
wire val3; |
|
wire [1:0] newPos0; |
wire [1:0] newPos1; |
wire [1:0] newPos2; |
wire [1:0] newPos3; |
|
|
`muxnet hit3,hit2,hit1,hit0; |
reg readen_reg=0; |
reg insert_reg=0; |
reg initEntry_reg=0; |
reg [31:0] addrA_reg; |
reg [115:0] tagDataA_fwd; |
wire [115:0] ramTagDataA; |
reg tag_fwd=0; |
|
wire [31:0] dataA0; |
wire [31:0] dataA1; |
wire [31:0] dataA2; |
wire [31:0] dataA3; |
|
codecacheramtag tag0(clk,tagwe,tagAddrA[11:6],tagAddrW[11:6],ramTagDataA,tagDataW); |
codecacheram ram0(clk,ram0We,tagAddrA[11:6],ramAddrW[11:6],ramDataR0,ramDataW); |
codecacheram ram1(clk,ram1We,tagAddrA[11:6],ramAddrW[11:6],ramDataR1,ramDataW); |
codecacheram ram2(clk,ram2We,tagAddrA[11:6],ramAddrW[11:6],ramDataR2,ramDataW); |
codecacheram ram3(clk,ram3We,tagAddrA[11:6],ramAddrW[11:6],ramDataR3,ramDataW); |
instr_sel instr_sel0(ramDataR0,tagAddrA_reg[5:2],dataA0); |
instr_sel instr_sel1(ramDataR1,tagAddrA_reg[5:2],dataA1); |
instr_sel instr_sel2(ramDataR2,tagAddrA_reg[5:2],dataA2); |
instr_sel instr_sel3(ramDataR3,tagAddrA_reg[5:2],dataA3); |
get_new_pos newpos0(pos0,pos1,pos2,pos3,hit0,hit1,hit2,hit3,newPos0,newPos1,newPos2,newPos3); |
|
assign tagAddrA=addrA; |
assign tagwe=readen_reg || insert_reg || initEntry_reg; |
assign tagAddrW=tagAddrA_reg; |
|
assign tagDataA=tag_fwd ? tagDataA_fwd : ramTagDataA; |
|
assign { pad3[31:6],pad2[31:6],pad1[31:6],pad0[31:6],pos3,pos2,pos1,pos0,val3,val2,val1,val0 } = tagDataA; |
assign pad3[5:0]=6'b0; |
assign pad2[5:0]=6'b0; |
assign pad1[5:0]=6'b0; |
assign pad0[5:0]=6'b0; |
|
assign tagDataW=readen_reg ? { pad3[31:6],pad2[31:6],pad1[31:6],pad0[31:6],newPos3,newPos2,newPos1,newPos0,val3,val2,val1,val0 } : 116'b`muxval; |
assign tagDataW=(insert_reg && hit0) ? { pad3[31:6],pad2[31:6],pad1[31:6],tagAddrA_reg[31:6],newPos3,newPos2,newPos1,newPos0,val3,val2,val1,1'b1 } : 116'b`muxval; |
assign tagDataW=(insert_reg && hit1) ? { pad3[31:6],pad2[31:6],tagAddrA_reg[31:6],pad0[31:6],newPos3,newPos2,newPos1,newPos0,val3,val2,1'b1,val0 } : 116'b`muxval; |
assign tagDataW=(insert_reg && hit2) ? { pad3[31:6],tagAddrA_reg[31:6],pad1[31:6],pad0[31:6],newPos3,newPos2,newPos1,newPos0,val3,1'b1,val1,val0 } : 116'b`muxval; |
assign tagDataW=(insert_reg && hit3) ? { tagAddrA_reg[31:6],pad2[31:6],pad1[31:6],pad0[31:6],newPos3,newPos2,newPos1,newPos0,1'b1,val2,val1,val0 } : 116'b`muxval; |
// assign tagDataW=(insert_reg && !hit) ? 116'b0 : 116'bz; |
assign tagDataW=initEntry_reg ? { 26'b0,26'b0,26'b0,26'b0,2'b11,2'b10,2'b01,2'b00,1'b0,1'b0,1'b0,1'b0} : 116'b`muxval; |
assign tagDataW=(!insert_reg && !readen_reg && !initEntry_reg) ? 116'b0 : 116'b`muxval; |
|
assign hit3=readen_reg ? val3 && (pad3[31:6]==tagAddrA_reg[31:6]) : 1'b`muxval; |
assign hit2=readen_reg ? val2 && (pad2[31:6]==tagAddrA_reg[31:6]) : 1'b`muxval; |
assign hit1=readen_reg ? val1 && (pad1[31:6]==tagAddrA_reg[31:6]) : 1'b`muxval; |
assign hit0=readen_reg ? val0 && (pad0[31:6]==tagAddrA_reg[31:6]) : 1'b`muxval; |
|
assign hit3=insert_reg ? (pos3==2'b11) : 1'b`muxval; |
assign hit2=insert_reg ? (pos2==2'b11) : 1'b`muxval; |
assign hit1=insert_reg ? (pos1==2'b11) : 1'b`muxval; |
assign hit0=insert_reg ? (pos0==2'b11) : 1'b`muxval; |
|
assign hit3=(!insert_reg && !readen_reg) ? 1'b0 : 1'b`muxval; |
assign hit2=(!insert_reg && !readen_reg) ? 1'b0 : 1'b`muxval; |
assign hit1=(!insert_reg && !readen_reg) ? 1'b0 : 1'b`muxval; |
assign hit0=(!insert_reg && !readen_reg) ? 1'b0 : 1'b`muxval; |
|
assign hit=hit3 || hit2 || hit1 || hit0; |
|
assign ram0We=insert_reg && hit0; |
assign ram1We=insert_reg && hit1; |
assign ram2We=insert_reg && hit2; |
assign ram3We=insert_reg && hit3; |
|
assign dataA=hit0 ? dataA0 : 32'b`muxval; |
assign dataA=hit1 ? dataA1 : 32'b`muxval; |
assign dataA=hit2 ? dataA2 : 32'b`muxval; |
assign dataA=hit3 ? dataA3 : 32'b`muxval; |
assign dataA= hit ? 32'b`muxval : 32'b0; |
|
assign ramDataW=cacheLine_reg; |
assign ramAddrW=tagAddrA_reg; |
|
always @(posedge clk) |
begin |
readen_reg<=readen; |
tagAddrA_reg<=tagAddrA; |
insert_reg<=insert; |
addrA_reg<=addrA; |
cacheLine_reg<=cacheLine; |
initEntry_reg<=initEntry; |
tagDataA_fwd<=ramTagDataA; |
tag_fwd<=(readen_reg || insert_reg || initEntry_reg) && (addrA[11:6]==addrA_reg[11:6]); |
end |
|
endmodule |
|
module codecacheram(input clk,input we,input [5:0] addrA,input [5:0] addrW,output reg [511:0] dataA,input [511:0] dataW); |
reg [511:0] ram [63:0]; |
|
always @(posedge clk) |
begin |
dataA<=ram[addrA]; |
if (we) ram[addrW]<=dataW; |
end |
|
endmodule |
|
/* |
tag for 4 way set-asociative LRU code cache |
{ |
{pad3,pad2,pad1,pad0}, //4x 26 bit physical address |
{pos3,pos2,pos1,pos0}, //4xeach 2 bit LRU position, 8 bit |
{val3,val2,val1,val0} //4x 1 bit valid entry, 4 bit |
} |
length =29*4=116 bit tag |
*/ |
|
module codecacheramtag(input clk,input we,input [5:0] addrA,input [5:0] addrW,output reg [115:0] dataA,input [115:0] dataW); |
reg [115:0] ram [63:0]; |
|
always @(posedge clk) |
begin |
dataA<=ram[addrA]; |
if (we) ram[addrW]<=dataW; |
end |
|
endmodule |
|
|
|
module instr_sel(input [511:0] dataIn,input [3:0] sel, output [31:0] instr); |
wire [255:0] bit3Data; |
wire [127:0] bit2Data; |
wire [63:0] bit1Data; |
|
assign bit3Data=sel[3] ? dataIn[511:256] : dataIn[255:0]; |
assign bit2Data=sel[2] ? bit3Data[255:128] : bit3Data[127:0]; |
assign bit1Data=sel[1] ? bit2Data[127:64] : bit2Data[63:0]; |
assign instr =sel[0] ? bit1Data[63:32] : bit1Data[31:0]; |
|
endmodule |
|
|
module get_new_pos(input [1:0] pos0,input [1:0] pos1,input [1:0] pos2,input [1:0] pos3, |
input hit0,input hit1,input hit2,input hit3, |
output `muxnet [1:0] newPos0,output `muxnet [1:0] newPos1,output `muxnet [1:0] newPos2,output `muxnet [1:0] newPos3); |
wire hit; |
|
assign hit=hit0 || hit1 || hit2 || hit3; |
|
assign newPos0=hit0 ? 0 : 2'b`muxval; |
assign newPos1=hit0 ? ((pos1<pos0) ? pos1+1:pos1 ) : 2'b`muxval; |
assign newPos2=hit0 ? ((pos2<pos0) ? pos2+1:pos2 ) : 2'b`muxval; |
assign newPos3=hit0 ? ((pos3<pos0) ? pos3+1:pos3 ) : 2'b`muxval; |
|
assign newPos1=hit1 ? 0 : 2'b`muxval; |
assign newPos0=hit1 ? ((pos0<pos1) ? pos0+1:pos0 ) : 2'b`muxval; |
assign newPos2=hit1 ? ((pos2<pos1) ? pos2+1:pos2 ) : 2'b`muxval; |
assign newPos3=hit1 ? ((pos3<pos1) ? pos3+1:pos3 ) : 2'b`muxval; |
|
assign newPos2=hit2 ? 0 : 2'b`muxval; |
assign newPos1=hit2 ? ((pos1<pos2) ? pos1+1:pos1 ) : 2'b`muxval; |
assign newPos0=hit2 ? ((pos0<pos2) ? pos0+1:pos0 ) : 2'b`muxval; |
assign newPos3=hit2 ? ((pos3<pos2) ? pos3+1:pos3 ) : 2'b`muxval; |
|
assign newPos3=hit3 ? 0 : 2'b`muxval; |
assign newPos1=hit3 ? ((pos1<pos3) ? pos1+1:pos1 ) : 2'b`muxval; |
assign newPos2=hit3 ? ((pos2<pos3) ? pos2+1:pos2 ) : 2'b`muxval; |
assign newPos0=hit3 ? ((pos0<pos3) ? pos0+1:pos0 ) : 2'b`muxval; |
|
assign newPos0=hit ? 2'b`muxval : pos0; |
assign newPos1=hit ? 2'b`muxval : pos1; |
assign newPos2=hit ? 2'b`muxval : pos2; |
assign newPos3=hit ? 2'b`muxval : pos3; |
|
endmodule |
/trunk/rtl/cpu.v
0,0 → 1,664
|
module aluplus(instr, val1, val2, valres, wrtval, cjmpinstr,cjmp,const1,retaddr); |
|
input [31:0] instr, val1, val2; |
output [31:0] valres; |
output wire wrtval,cjmpinstr; |
output cjmp; |
input [31:0] const1; |
input [31:0] retaddr; |
wire [5:0] code; |
wire [31:0] valcmp; |
wire CF,NF,VF,ZF; |
|
/* |
wrtval=1 if valres needs to be stored in register. |
cjmpinstr=1 if compare and jump instruction |
cjmp=1 if jump taken 0 otherwise (only valid if cjmpinstr=1) |
*/ |
|
//assign const1={{16{instr[31]}},instr[31:21],instr[15:11]}; |
assign code=instr[5:0]; |
|
assign valres=(code==0) ? {const1[15:0],val1[15:0]} : 32'bz; |
assign valres=(code==1) ? const1 : 32'bz; |
assign valres=(code==2) ? val1 & val2 : 32'bz; |
assign valres=(code==3) ? val1 & const1 : 32'bz; |
assign valres=(code==4) ? val1 | val2 : 32'bz; |
assign valres=(code==5) ? val1 | const1 : 32'bz; |
assign valres=(code==6) ? val1 ^ val2 : 32'bz; |
assign valres=(code==7) ? val1 ^ const1 : 32'bz; |
assign valres=(code==8) ? val1 + val2 : 32'bz; |
assign valres=(code==9) ? val1 + const1 : 32'bz; |
assign valres=(code==10)? val1 - val2 : 32'bz; |
assign valres=(code==11)? val1 - const1 : 32'bz; |
//12=no-op |
assign valres=(code==13)? val1 & {16'b1111111111111111, const1[15:0]} : 32'bz; |
assign valres=(code==46) ? retaddr : 32'bz; |
assign valres=(code==14)? val1 << val2[5:0] : 32'bz; |
assign valres=(code==15)? val1 << const1[5:0] : 32'bz; |
assign valres=(code==16)? val1 >> val2[5:0] : 32'bz; |
assign valres=(code==17)? val1 >> const1[5:0] : 32'bz; |
assign valres=(code==18)? {32{val1[31]},val1} >> val2[5:0] : 32'bz; |
assign valres=(code==19)? {32{val1[31]},val1} >> const1[5:0] : 32'bz; |
|
assign valres=wrtval ? 32'bz : 32'b0; |
|
assign wrtval=((code<=11) || (code>=13 && code<=19) || (code==46)); |
|
//flags for compare &jump |
assign {CF,valcmp}=val1 - val2; |
assign NF=valcmp[31]; |
assign ZF=(val1==val2); |
assign VF=(val1[31] & !val2[31] & !valcmp[31]) | (!val1[31] & val2[31] & valcmp[31]); |
|
assign cjmpinstr=((code>=32)&&(code<=45)); |
|
assign cjmp= (code==32) ? (CF) : 1'bz; |
assign cjmp= (code==33) ? (!CF) : 1'bz; |
assign cjmp= (code==34) ? (ZF) : 1'bz; |
assign cjmp= (code==35) ? (!ZF) : 1'bz; |
assign cjmp= (code==36) ? (CF ^ ZF) : 1'bz; |
assign cjmp= (code==37) ? !(CF ^ ZF) : 1'bz; |
assign cjmp= (code==38) ? (NF) : 1'bz; |
assign cjmp= (code==39) ? !(NF) : 1'bz; |
assign cjmp= (code==40) ? (VF ^ NF) : 1'bz; |
assign cjmp= (code==41) ? !(VF ^ NF) : 1'bz; |
assign cjmp= (code==42) ? ((VF ^ NF) | ZF) : 1'bz; |
assign cjmp= (code==43) ? !((VF ^ NF) | ZF) : 1'bz; |
assign cjmp= (code==44) ? (VF) : 1'bz; |
assign cjmp= (code==45) ? (!VF) : 1'bz; |
|
assign cjmp= cjmpinstr ? 1'bz : 1'b0; |
|
endmodule |
|
module subagu(input clk, input stall,input [4:0] stginhibit,input [31:0] baseOP,input [31:0] instr0,input [31:0] instr, input [31:0] instrprev,output wire [31:0] addr,output wire aguwrtval,output wire delayedstall, output reg [1:0] readsz, output wire readen,output wire writeen, input [31:0] offset); |
wire [4:0] instr_rA,instrprev_rF; |
wire writeinstrprev; |
wire [5:0] instrprev_code,instr_code,instr0_code; |
wire instr0_load,instr0_store,instr_load,instr_store; |
reg aguwrtval_reg; |
reg delayedstall_reg=0; |
//reg readen_reg; |
//wire [18:0] shortaddr; |
|
assign instr_rA=instr[10:6]; |
assign instrprev_rF=instrprev[20:16]; |
assign instrprev_code=instrprev[5:0]; |
assign instr_code=instr[5:0]; |
assign instr0_code=instr0[5:0]; |
|
assign writereginstrprev=((instrprev_code<=11) || (instrprev_code==13) || |
((instrprev_code >= 56) && (instrprev_code <=58))) && !stginhibit[4] && !stall; //remove !stall ?? |
assign delayedstall=writereginstrprev && (instr_load || instr_store) && ( instr_rA==instrprev_rF ) && (!stginhibit[3]); //add constant add stalless support |
|
assign instr_load=(instr_code >= 56) && (instr_code <=58); |
assign instr_store=(instr_code >= 60) && (instr_code <=62); |
assign instr0_load=(instr0_code >= 56) && (instr0_code <=58); |
assign instr0_store=(instr0_code >= 60) && (instr0_code <=62); |
|
assign addr=baseOP + offset; |
//assign shortaddr=baseOP[18:0] + offset[18:0]; |
|
assign readen=instr_load && !stall && !stginhibit[3]; |
assign writeen=instr_store && !stall && !stginhibit[3] && !delayedstall_reg; |
assign aguwrtval=!stall && !stginhibit[4] && aguwrtval_reg; |
|
always @(posedge clk) |
begin |
if (!stall && !stginhibit[3]) aguwrtval_reg<=instr_load; |
///*if (!stall && !stginhibit[2]) */readen_reg<=instr0_load; |
if (!stall && !stginhibit[2]) |
case (instr0_code) |
56: readsz<=2; |
57: readsz<=1; |
58: readsz<=0; |
60: readsz<=2; |
61: readsz<=1; |
62: readsz<=0; |
default: readsz<=0; |
endcase |
delayedstall_reg<=delayedstall; |
end |
|
endmodule |
|
|
module regfileint0(clk,we,rA,rB,rC,rF,dataA,dataB,dataC,dataF); |
input [4:0] rA,rB,rC,rF; |
output wire [31:0] dataA,dataB,dataC; |
input [31:0] dataF; |
input clk,we; |
reg [31:0] regs [31:0]; |
|
regram ram0(clk,we,rA,rF,dataA,dataF); |
regram ram1(clk,we,rB,rF,dataB,dataF); |
regram ram2(clk,we,rC,rF,dataC,dataF); |
|
endmodule |
|
module regram(input clk,input we,input [4:0] rA, input [4:0] rF, output reg [31:0] dataA, input [31:0] dataF); |
reg [31:0] regs[31:0]; |
always @(posedge clk) |
begin |
dataA<=regs[rA]; |
if (we) regs[rF]<=dataF; |
end |
endmodule |
|
module ioinstr(input clk,input stall, input [4:0] stginhibit,input [31:0] instr,input [31:0] val1,input [31:0] val2, output [31:0] valres, input multiCycleStall, |
output wire wrtVal, output wire doStall, output wire keepStalling, |
output wire [31:0] ioBusAddr,output reg [1:0] ioBusSize, output wire [31:0] ioBusOut, input [31:0] ioBusIn, input ioBusRdy, |
output wire ioBusWr,output wire ioBusRd); |
|
wire [5:0] code; |
wire [5:0] auxCode; |
reg keepStalling_reg=0; |
reg [31:0] inputValue; |
assign code=instr[5:0]; |
assign auxCode=instr[26:21]; |
assign doStall=(code==31) && !multiCycleStall && !stall && !stginhibit[4]; |
assign wrtVal=multiCycleStall && (code==31) && ((auxCode==0) || (auxCode==1) || (auxCode==2)) && !stall && !stginhibit[4]; |
assign ioBusAddr=val1; |
assign ioBusOut=val2; |
|
assign ioBusOut=val2; |
assign ioBusAddr=val1; |
assign ioBusWr=!stall && !stginhibit[4] && !multiCycleStall && (code==31) && ((auxCode==4) || (auxCode==5) || (auxCode==6)); |
assign ioBusRd=!stall && !stginhibit[4] && !multiCycleStall && (code==31) && ((auxCode==0) || (auxCode==1) || (auxCode==2)); |
assign valres=inputValue; |
|
assign keepStalling=keepStalling_reg; |
|
always @(auxCode) |
begin |
case(auxCode) |
0,4: ioBusSize=0; |
1,5: ioBusSize=1; |
2,6: ioBusSize=2; |
default: ioBusSize=0; |
endcase |
end |
|
always @(posedge clk) |
begin |
if (!stall && !stginhibit[4] && (code==31) && !multiCycleStall) |
begin |
keepStalling_reg<=1; |
end |
if (ioBusRdy) |
begin |
keepStalling_reg<=0; |
end |
if (ioBusRdy) |
begin |
inputValue<=ioBusIn; |
end |
end |
|
endmodule |
|
module brpred(input clk,input stall, input [4:0] stginhibit,input [31:0] fetchaddr, output wire hit, output wire [31:0] branchinstr, |
output wire [31:0] nextaddr,output wire branchtaken, |
input [31:0] insertaddr, input [31:0] insertinstr,input [31:0] inserttargetnext,input inserttaken,input jumpinstr,output wire addrMismatch); |
wire wen; |
wire [5:0] ramAddrB; |
wire [96:0] ramDataA; |
wire [96:0] ramDataB; |
wire [96:0] dataA; |
reg [31:0] fetchaddr_reg=0; |
reg branchtaken3; |
reg branchtaken4; |
reg branchtaken5; |
reg wen_reg=0; |
reg fwd; |
reg [96:0] fwdData; |
reg init=1; |
reg [5:0] initcount=63; |
|
reg [31:0] nextaddr3; |
reg [31:0] nextaddr4; |
reg [31:0] nextaddr5; |
|
brpred_ram ram0(clk,fetchaddr[7:2],ramAddrB,wen, ramDataA, ramDataB); |
|
assign dataA=fwd ? fwdData : ramDataA; |
|
assign hit=(dataA[63:32]==fetchaddr_reg); |
assign branchinstr=dataA[31:0]; |
assign branchtaken=dataA[96]; |
assign nextaddr=dataA[95:64]; |
|
assign wen=((!stall && !stginhibit[4]) && (branchtaken5 ^ inserttaken) && jumpinstr) | init; //only write on failed prediction |
assign ramDataB=(!init) ? {inserttaken,inserttargetnext,insertaddr,insertinstr} : {1'b0,32'b0,32'b11,32'b0}; |
assign ramAddrB= init ? initcount : insertaddr[7:2]; |
|
assign addrMismatch=jumpinstr && (inserttargetnext != nextaddr5) && branchtaken5; |
|
always @(posedge clk) |
begin |
wen_reg<=wen; |
fwd<=wen && (ramAddrB == fetchaddr[7:2]); |
fwdData<=ramDataB; |
|
if (init) |
begin |
initcount<=initcount-1; |
if (initcount==0) init<=0; |
end |
|
if (!stall) |
begin |
fetchaddr_reg<=fetchaddr; |
end |
if (!stall && !stginhibit[1]) |
begin |
branchtaken3<=hit && branchtaken; |
nextaddr3<=nextaddr; |
end |
if (!stall && !stginhibit[2]) |
begin |
branchtaken4<=branchtaken3; |
nextaddr4<=nextaddr3; |
end |
if (!stall && !stginhibit[3]) |
begin |
branchtaken5<=branchtaken4; |
nextaddr5<=nextaddr4; |
end |
if (!stall && !stginhibit[4]) |
begin |
end |
end |
endmodule |
|
module brpred_ram(input clk, input [5:0] addrA, input [5:0] addrB, input wen, output reg [96:0] dataA, input [96:0] dataB); |
reg [96:0] ram[63:0]; |
always @(posedge clk) |
begin |
dataA<=ram[addrA]; |
if (wen) ram[addrB]<=dataB; |
end |
endmodule |
|
module cpu(input clk,input busEnRead,input busEnWrite, input busDataReady, output wire busRead, output wire busWrite,output wire [31:0] busAddr, |
input [511:0] busInput,output wire [511:0] busOutput, |
output wire [31:0] ioBusAddr,output wire [1:0] ioBusSize, output wire [31:0] ioBusOut, input [31:0] ioBusIn, input ioBusRdy, |
output wire ioBusWr,output wire ioBusRd,output wire [3:0] dummy); |
wire [31:0] fetchaddr,fetchdata,readaddr,readdata; |
reg [31:0] readaddr_reg; |
reg [4:0] stginhibit=5'b11110; |
reg [4:0] stginhibit_wrt; |
reg [31:0] IP=32'b0,IP2,IP3,IP4,IP5,instr=0,instr4=0; |
reg stall0=0; |
wor stall; |
wire [4:0] rA0,rB0,rC,rF0,rFprev,rFprevprev; |
//reg [31:0] cjmpoff; |
reg [4:0] rA,rB,rF,rAprev,rBprev; |
wire intregwe; |
wire [31:0] intregdataF; |
wire [31:0] intregdataA,intregdataB,intregdataC; |
wire [31:0] opA,opB,opC,opF; |
reg rAfwd,rBfwd,rCfwd,rAfwd0,rBfwd0,rCfwd0; |
reg cycle1prev=0; |
reg [31:0] instr0=0; |
//reg [31:0] reg_instr0; |
wire aluwrtval,alucjmpinstr,alucjmp; |
//reg regfwrt=0; |
reg [31:0] regfwd; |
wire [31:0] aguaddr; |
wire agustall,aguwrtval; |
wire [1:0] agureadsz; |
wire agureaden; |
wire aguwriteen; |
reg agureaden_reg; |
reg aguwriteen_reg; |
reg agustall_reg=0; |
//aguwrtval ignores exceptions for now |
reg [31:0] cjmpoffset; |
reg [31:0] cjmpoffset0; |
reg [31:0] cjmpaddr; |
wire brpred_hit; |
wire [31:0] brpred_instr; |
wire [31:0] brpred_nextaddr; |
wire brpred_taken; |
wire [31:0] brpred_instertaddr; |
wire [31:0] brpred_instertinstr; |
wire [31:0] brpred_insertnextaddr; |
wire brpred_inserttaken; |
wire brpred_jumpinstr; |
wire brpred_addrMismatch; |
|
reg brtaken3,brtaken4,brtaken5; |
|
reg init=1; |
reg ccInit=1; |
reg dcInit=1; |
reg [6:0] initcount=66; |
reg [5:0] ccInitCount=63; |
reg [5:0] dcInitCount=63; |
reg [4:0] codeMiss=0; |
wire [31:0] ccFetchAddr; |
//wire [511:0] cacheLineInput; |
wire ccHit,ccReadEn,ccInsert; |
reg ccInsertInProgress_tsk=0; |
reg ccInsertRamReq_tsk=0; |
reg ccInsertInsert_tsk=0; |
reg ccInsertWait1_tsk=0; |
reg ccInsertWait2_tsk=0; |
|
wire [31:0] dcAddr; |
wire [511:0] dcDataA; |
wire [511:0] dcDataWriteBack; |
reg [511:0] dcDataWriteBack_reg; |
wire dcHit; |
wire dcReadEn,dcWriteEn,dcInsert,dcInitEntry; |
reg dcInsertInProgress_tsk=0; |
reg dcInsertRamReq_tsk=0; |
reg dcInsertInsert_tsk=0; |
reg dcInsertCheckDirty_tsk=0; |
reg dcInsertWriteBack_tsk=0; |
reg [31:0] dcReadAddr; |
reg [31:0] dcOldAddr_reg; |
wire [31:0] dcOldAddr; |
|
reg [31:0] constBits; // contains the constant bits |
reg [31:0] constBits4; |
reg prevUpperBits=0; //bit 0 set => constBits countains the upper constant bits of the next instruction |
|
wire [31:0] retAddr; |
wire uJmpInstr; |
reg [31:0] aguaddr_reg; |
|
reg [4:0] multiCycleStall=0; |
|
wire [31:0] ioInstrResult; |
wire wasGlobalStall=multiCycleStall[4]; |
wire ioInstrWrtVal; |
wire ioInstrDoStall; |
wire ioInstrKeepStalling; |
|
|
//dataunit data0(clk,stall,stginhibit,readaddr,readdata,agureadsz,agureaden,aguwriteen,opB); |
datacache datacache0(clk,stall,stginhibit,codeMiss,dcAddr,dcDataA,busInput,opB,dcHit,dcReadEn,dcWriteEn,dcInsert,dcInitEntry,agureadsz,dcOldAddr); |
regfileint0 regf0(clk,intregwe,rA,rB,rC,rF,intregdataA,intregdataB,intregdataC,intregdataF); |
aluplus alu0(instr4,opA,opB,opF,aluwrtval,alucjmpinstr,alucjmp,constBits4,retAddr); |
ioinstr ioinstr0(clk,stall,stginhibit,instr4,opA,opB,ioInstrResult,wasGlobalStall,ioInstrWrtVal,ioInstrDoStall,ioInstrKeepStalling, |
ioBusAddr,ioBusSize,ioBusOut,ioBusIn,ioBusRdy,ioBusWr,ioBusRd); |
subagu agu0(clk,stall,stginhibit,opC,instr0,instr,instr4,aguaddr,aguwrtval,agustall,agureadsz,agureaden,aguwriteen,constBits); |
brpred brpred0(clk,stall,stginhibit,fetchaddr,brpred_hit,brpred_instr,brpred_nextaddr,brpred_taken, |
brpred_instertaddr,brpred_instertinstr,brpred_insertnextaddr,brpred_inserttaken,brpred_jumpinstr,brpred_addrMismatch); |
codecache codecache0(clk,ccFetchAddr,fetchdata,busInput,ccHit,ccReadEn,ccInsert,ccInit); |
|
assign dummy=stginhibit[4:1]; |
assign fetchaddr=!(!stall && !stginhibit[1] && brpred_hit&&brpred_taken) ? IP : brpred_nextaddr; |
assign stall=init || ccInsertInProgress_tsk || dcInsertInProgress_tsk || ioInstrKeepStalling; |
|
assign readdata=dcDataA[31:0]; |
assign dcReadEn=agureaden && !agustall; |
assign dcWriteEn=aguwriteen && !agustall; |
assign dcInsert=dcInsertInsert_tsk && busDataReady; |
assign dcInitEntry=dcInit; |
|
assign dcAddr=dcInit ? { 20'b0,dcInitCount,6'b0} : 32'bz; |
assign dcAddr=(dcReadEn || dcWriteEn) ? readaddr : 32'bz; |
assign dcAddr=dcInsert ? dcReadAddr : 32'bz; |
assign dcAddr=(!dcInit && !dcReadEn && !dcWriteEn && !dcInsert) ? 32'b0 : 32'bz; |
|
assign ccFetchAddr=ccInit ? { 20'b0,ccInitCount,6'b0} : 32'bz; |
assign ccFetchAddr=(!ccInit && !ccInsertInsert_tsk)? fetchaddr : 32'bz; //that should change to accomodate cache line insert |
assign ccFetchAddr=ccInsertInsert_tsk ? IP & 32'hffff_ffc0 : 32'bz; |
|
assign ccReadEn=!stall && !codeMiss[1] && !ccInit && !init; |
assign ccInsert=ccInsertInsert_tsk && busDataReady; |
|
assign busAddr=ccInsertRamReq_tsk ? IP & 32'hffff_ffc0 :32'bz; |
assign busAddr=dcInsertRamReq_tsk ? dcReadAddr & 32'hffff_ffc0: 32'bz; |
assign busAddr=dcInsertWriteBack_tsk ? dcOldAddr_reg : 32'bz; |
assign busAddr=(!ccInsertRamReq_tsk && !dcInsertRamReq_tsk && !dcInsertWriteBack_tsk) ? 32'b0 : 32'bz; |
|
assign busRead=(ccInsertRamReq_tsk || dcInsertRamReq_tsk) && busEnRead; |
assign busWrite=dcInsertWriteBack_tsk && busEnWrite; |
|
assign dcDataWriteBack=dcDataA; |
assign busOutput=dcDataWriteBack_reg; |
|
assign rA0=instr0[10:6]; |
assign rB0=instr0[15:11]; |
assign rF0=instr0[20:16]; |
assign rC=instr0[10:6]; |
|
assign intregwe=!stall && !stginhibit[4] && (aluwrtval || aguwrtval) && (!agustall_reg) && !((agureaden_reg || aguwriteen_reg) && !dcHit); // adjust for other cases ie mem read-done; |
assign intregdataF= aguwrtval ? readdata : opF; //adjust for ie mem read-done |
assign opA=rAfwd ? regfwd : intregdataA; |
assign opB=rBfwd ? regfwd : intregdataB; |
assign opC=rCfwd ? regfwd : intregdataC; |
|
//assign instr0=fetchdata; //change for branch prediction |
|
assign rFprev=instr[20:16]; |
assign rFprevprev=instr4[20:16]; |
//assign rAfwd=(rA==rFprev); |
//assign rBfwd=(rB==rFprev); |
//assign intregdataF=opF; |
|
assign readaddr=aguaddr; |
|
assign brpred_jumpinstr=alucjmpinstr || uJmpInstr; |
assign brpred_inserttaken=alucjmp || uJmpInstr; |
assign brpred_instertinstr=instr4; |
assign brpred_instertaddr=IP5; |
assign brpred_insertnextaddr=alucjmpinstr ? cjmpaddr : aguaddr_reg ; |
|
assign retAddr=IP5+4; |
assign uJmpInstr=(instr4[5:0]==46 || instr4[5:0]==47); |
|
//regfwrt<=0; |
always @(posedge clk) |
begin |
if (init) |
begin |
initcount<=initcount-1; |
if (initcount==0) init<=0; |
end |
if (ccInit) |
begin |
ccInitCount<=ccInitCount-1; |
if (ccInitCount==0) ccInit<=0; |
end |
if (dcInit) |
begin |
dcInitCount<=dcInitCount-1; |
if (dcInitCount==0) dcInit<=0; |
end |
if (ccInsertRamReq_tsk && busEnRead) |
begin |
ccInsertRamReq_tsk<=0; |
ccInsertInsert_tsk<=1; |
end |
if (ccInsertInsert_tsk && busDataReady) |
begin |
ccInsertInsert_tsk<=0; |
ccInsertWait1_tsk<=1; |
end |
if (ccInsertWait1_tsk) |
begin |
ccInsertWait1_tsk<=0; |
ccInsertWait2_tsk<=1; |
end |
if (ccInsertWait2_tsk) |
begin |
ccInsertWait2_tsk<=0; |
ccInsertInProgress_tsk<=0; |
end |
if (dcInsertRamReq_tsk && busEnRead) |
begin |
dcInsertRamReq_tsk<=0; |
dcInsertInsert_tsk<=1; |
end |
if (dcInsertInsert_tsk && busDataReady) |
begin |
dcInsertInsert_tsk<=0; |
dcInsertCheckDirty_tsk<=1; |
end |
if (dcInsertCheckDirty_tsk) |
begin |
dcInsertCheckDirty_tsk<=0; |
if (dcHit) |
begin |
dcInsertWriteBack_tsk<=1; |
dcOldAddr_reg<=dcOldAddr; |
dcDataWriteBack_reg<=dcDataWriteBack; |
end |
else |
begin |
dcInsertInProgress_tsk<=0; |
end |
end |
if (dcInsertWriteBack_tsk && busEnWrite) |
begin |
dcInsertWriteBack_tsk<=0; |
dcInsertInProgress_tsk<=0; |
end |
//stginhibit_wrt=stginhibit; |
if (stginhibit[1]) stginhibit_wrt[2]=1; |
if (stginhibit[2]) stginhibit_wrt[3]=1; |
if (stginhibit[3]) stginhibit_wrt[4]=1; |
agustall_reg<=agustall; |
agureaden_reg<=agureaden; |
aguwriteen_reg<=aguwriteen; |
readaddr_reg<=readaddr; |
//cycle 1 |
if (!stall) |
begin |
stginhibit[1]<=0; |
cycle1prev<=1; |
IP<=fetchaddr+4; |
IP2<=fetchaddr; |
multiCycleStall[1]<=multiCycleStall[0]; |
multiCycleStall[0]<=0; |
end |
else cycle1prev<=0; |
|
//cycle 2 |
if (!stall && !stginhibit[1]) |
begin |
stginhibit[2]<=0; |
IP3<=IP2; |
multiCycleStall[2]<=multiCycleStall[1]; |
if (!(brpred_hit&&brpred_taken)) instr0<=ccHit ? fetchdata : 32'b01100; |
else instr0<=brpred_instr; |
brtaken3<=(brpred_hit&&brpred_taken); |
if (!ccHit) |
begin |
codeMiss[1]<=1; |
codeMiss[2]<=1; |
end |
if (codeMiss[1]) codeMiss[2]<=1; |
|
end |
//cycle 3 |
if (!stall && !stginhibit[2]) |
begin |
instr<=instr0; |
//reg_instr0<=fetchdata; |
stginhibit[3]<=0; |
multiCycleStall[3]<=multiCycleStall[2]; |
IP4<=IP3; |
rA<=instr0[10:6]; |
rB<=instr0[15:11]; |
brtaken4<=brtaken3; |
codeMiss[3]<=codeMiss[2]; |
cjmpoffset0<={ {14{instr0[31]}}, instr0[31:16],2'b0 }; |
if (instr0[5:0]==30) //upper bits instr |
begin |
prevUpperBits<=1; |
constBits[31:16]<=instr0[31:16]; |
end |
else |
begin |
prevUpperBits<=0; |
end |
if (instr0[5:0]==60 || instr0[5:0]==61 || instr0[5:0]==62) //store instr |
begin |
constBits[15:0]<=instr0[31:16]; |
end |
else //non-store instr |
begin |
constBits[15:0]<={instr0[31:21],instr0[15:11]}; |
end |
if (!prevUpperBits) constBits[31:16]<={16{instr0[31]}}; |
end |
//cycle 4 |
if (!stall && !stginhibit[3]) |
begin |
constBits4<=constBits; |
stginhibit[4]<=0; |
IP5<=IP4; |
multiCycleStall[4]<=multiCycleStall[3]; |
rAfwd0<=(rA0==rFprev); |
rBfwd0<=(rB0==rFprev); |
instr4<=instr; |
rF<=instr[20:16]; |
cjmpoffset<={ {14{instr[31]}}, instr[31:16],2'b0 }; |
cjmpaddr<=IP4+cjmpoffset0; |
brtaken5<=brtaken4; |
codeMiss[4]<=codeMiss[3]; |
aguaddr_reg<=aguaddr; |
end |
//cycle 5 |
|
if (!stall && !stginhibit[4]) //remove !stall ?? |
begin |
rAfwd<=rAfwd0 && (aluwrtval || aguwrtval) && (!agustall_reg); //adjust for other sources of data |
rBfwd<=rBfwd0 && (aluwrtval || aguwrtval) && (!agustall_reg); //these 2 indicate forwarding of operands from regfwd |
rCfwd<=(rA0==rFprevprev) && (aluwrtval || aguwrtval) && (!agustall_reg); |
|
regfwd<=aguwrtval ? readdata : opF; |
if (codeMiss[4]) |
begin |
stginhibit<=5'b11110; |
codeMiss<=0; |
IP<=IP5; |
ccInsertInProgress_tsk<=1; |
ccInsertRamReq_tsk<=1; |
end |
else if ((agureaden_reg || aguwriteen_reg) && !dcHit && !agustall_reg) |
begin |
stginhibit<=5'b11110; |
codeMiss<=0; |
IP<=IP5; |
dcInsertInProgress_tsk<=1; |
dcInsertRamReq_tsk<=1; |
dcReadAddr<=readaddr_reg; |
end |
else if ((((alucjmpinstr && alucjmp) || uJmpInstr) ^ brtaken5) || brpred_addrMismatch) |
begin |
stginhibit<=5'b11110; |
codeMiss<=0; |
IP<=(alucjmp || uJmpInstr) ? (alucjmpinstr ? (IP5+cjmpoffset) : (opA+constBits4) ): IP5+4; |
end |
else if (agustall_reg) |
begin |
stginhibit<=5'b11110; |
codeMiss<=0; |
IP<=IP5; |
end |
else if (ioInstrDoStall) |
begin |
stginhibit<=5'b11110; |
codeMiss<=0; |
IP<=IP5; |
multiCycleStall[0]<=1; |
end |
end |
else |
begin |
rAfwd<=0; |
rBfwd<=0; |
rCfwd<=0; |
end |
// |
end |
endmodule |
/trunk/rtl/sim_test.v
0,0 → 1,104
`timescale 1 ns / 100 ps |
|
module testram(input clk,input we, input [31:0] addrA, output reg [511:0] dataA,input [511:0] dataW); |
reg [31:0] ram0 [32767:0]; |
always @(posedge clk) |
begin |
dataA<= |
{ |
ram0[{addrA[16:6],4'd15}], |
ram0[{addrA[16:6],4'd14}], |
ram0[{addrA[16:6],4'd13}], |
ram0[{addrA[16:6],4'd12}], |
ram0[{addrA[16:6],4'd11}], |
ram0[{addrA[16:6],4'd10}], |
ram0[{addrA[16:6],4'd9}], |
ram0[{addrA[16:6],4'd8}], |
ram0[{addrA[16:6],4'd7}], |
ram0[{addrA[16:6],4'd6}], |
ram0[{addrA[16:6],4'd5}], |
ram0[{addrA[16:6],4'd4}], |
ram0[{addrA[16:6],4'd3}], |
ram0[{addrA[16:6],4'd2}], |
ram0[{addrA[16:6],4'd1}], |
ram0[{addrA[16:6],4'd0}] |
}; |
if (we) |
begin |
ram0[{addrA[16:6],4'd0}]<=dataW[31:0]; |
ram0[{addrA[16:6],4'd1}]<=dataW[63:32]; |
ram0[{addrA[16:6],4'd2}]<=dataW[95:64]; |
ram0[{addrA[16:6],4'd3}]<=dataW[127:96]; |
ram0[{addrA[16:6],4'd4}]<=dataW[159:128]; |
ram0[{addrA[16:6],4'd5}]<=dataW[191:160]; |
ram0[{addrA[16:6],4'd6}]<=dataW[223:192]; |
ram0[{addrA[16:6],4'd7}]<=dataW[255:224]; |
ram0[{addrA[16:6],4'd8}]<=dataW[287:256]; |
ram0[{addrA[16:6],4'd9}]<=dataW[319:288]; |
ram0[{addrA[16:6],4'd10}]<=dataW[351:320]; |
ram0[{addrA[16:6],4'd11}]<=dataW[383:352]; |
ram0[{addrA[16:6],4'd12}]<=dataW[415:384]; |
ram0[{addrA[16:6],4'd13}]<=dataW[447:416]; |
ram0[{addrA[16:6],4'd14}]<=dataW[479:448]; |
ram0[{addrA[16:6],4'd15}]<=dataW[511:480]; |
end |
|
end |
endmodule |
|
module cpu2r6test(); |
|
reg clk=0; |
wire busEnRead=1; |
wire busEnWrite=1; |
wire busRead; |
wire busWrite; |
wire [31:0] busAddr; |
wire [511:0] busInput; |
wire [511:0] ramDataA; |
wire [511:0] ramDataW; |
reg [511:0] dataW_reg; |
reg we_reg=0; |
wire we; |
reg [31:0] addr_reg; |
reg busRdy=0; |
|
wire [31:0] ioBusAddr; |
wire [1:0] ioBusSize; |
wire [31:0] ioBusOut; |
wire [31:0] ioBusIn; |
reg ioBusRdy=0; |
wire ioBusWr; |
wire ioBusRd; |
wire [3:0] dummy; |
|
cpu2r6 mycpu2(clk,busEnRead,busEnWrite,busRdy,busRead,busWrite,busAddr,busInput,ramDataW, |
ioBusAddr,ioBusSize,ioBusOut,ioBusIn,ioBusRdy,ioBusWr,ioBusRd,dummy); |
testram ram0(clk,we,busAddr,ramDataA,ramDataW); |
|
assign busInput=(we_reg && (busAddr==addr_reg)) ? dataW_reg : ramDataA; |
assign we=busWrite; |
|
always @(posedge clk) |
begin |
ioBusRdy<=ioBusWr || ioBusRd; |
we_reg<=we; |
dataW_reg<=ramDataW; |
addr_reg<=busAddr; |
busRdy<=busRead; |
if (ioBusWr) $display("out addr %h,data %h",ioBusAddr,ioBusOut); |
if (ioBusRd) $display("in addr %h",ioBusAddr); |
end |
|
always |
#100 clk<=!clk; |
|
initial |
begin |
$readmemh("testmem6.hex",ram0.ram0); |
$monitor("r2=0x%h",mycpu2.regf0.ram0.regs[2]); |
end |
|
endmodule |
|
|
/trunk/native asm/calltestio.s
0,0 → 1,16
lc 0,r0 |
lc 3,r3 |
lc 1,r4 |
loop1: |
call r0,outr2,r31 |
addi r4,1,r4 |
subi r3,1,r3 |
cjsge r3,r0,loop1 |
loopend: |
cjeq r0,r0,loopend |
|
outr2: |
and r4,r4,r2 |
lc 0x300,r5 |
outl r5,r4 |
ret r31 |
/trunk/native asm/testmem6.s
0,0 → 1,407
lc 0,r0 ;always zero |
lc 0,r2 ;$monitor-ed register; small numbers=pass test, numbers>0x1000=error |
|
; test #9 - write back test |
|
lc cl3,r3 ; adress |
lc 10,r4 ; loop counter |
lc 1000,r5 ; value to store |
loop9_w: |
stl r3,0,r5 |
addi r5,11,r5 |
addi r3,0x1000,r3 |
subi r4,1,r4 |
cjuge r4,r0,loop9_w |
lc cl3,r3 ; adress |
lc 10,r4 ; loop counter |
lc 1000,r5 ; value to compare |
; r6 - load value |
loop9_r: |
ldl r3,0,r6 |
cjne r6,r5,error9_1 |
addi r5,11,r5 |
addi r3,0x1000,r3 |
subi r4,1,r4 |
cjuge r4,r0,loop9_r |
cjeq r0,r0,skiperr9 |
error9_1: |
lc 0x9000,r2 |
cjeq r0,r0,error9_1 |
skiperr9: |
|
lc 9,r2 |
|
; test #10 - more complete write back test |
|
lc cl3,r3 ; adress |
lc 10,r4 ; loop counter |
lc 1000,r5 ; value to store |
loop10_w_32: |
lc 32,r7 ; inner loop counter |
and r3,r3,r8 ; inner loop pointer |
loop10_w_1: |
stw r8,0,r5 |
addi r5,11,r5 |
addi r8,2,r8 |
subi r7,1,r7 |
cjuge r7,r0,loop10_w_1 |
addi r3,0x1000,r3 |
subi r4,1,r4 |
cjuge r4,r0,loop10_w_32 |
|
lc cl3,r3 ; adress |
lc 10,r4 ; loop counter |
lc 1000,r5 ; value to compare |
; r6 - load value |
loop10_r_32: |
lc 32,r7 ; inner loop counter |
and r3,r3,r8 ; inner loop pointer |
loop10_r_1: |
ldw r8,0,r6 |
cjne r6,r5,error10_1 |
addi r5,11,r5 |
addi r8,2,r8 |
subi r7,1,r7 |
cjuge r7,r0,loop10_r_1 |
addi r3,0x1000,r3 |
subi r4,1,r4 |
cjuge r4,r0,loop10_r_32 |
cjeq r0,r0,skiperr10 |
error10_1: |
lc 0xa000,r2 |
cjeq r0,r0,error10_1 |
skiperr10: |
|
lc 10,r2 |
|
|
; test #1 |
lc cl1,r3 ;data base register |
lc 0,r4 ;effective address |
lc 0x1, r5 ; value to compare |
; load data into r6 |
lc 8,r7 ; x1 loop counter |
lc 8,r8 ; x8 loop counter |
|
and r3,r3,r4 |
|
loop1_8: |
lc 8,r7 |
loop1_1: |
ldb r4,0,r6 |
cjne r6,r5,error1_1 |
addi r4,1,r4 |
addi r5,1,r5 |
subi r7,1,r7 |
cjuge r7,r0,loop1_1 |
addi r5,8,r5 |
subi r8,1,r8 |
cjuge r8,r0,loop1_8 |
cjeq r0,r0,skiperr1 |
error1_1: |
lc 0x1000,r1 ;error code |
or r1,r5,r2 |
cjeq r0,r0, error1_1 |
skiperr1: ;test 1 passed |
lc 1,r2 |
|
; test #2 |
lc cl1,r3 ;data base register |
lc 0,r4 ;effective address |
lc 0x0201, r5 ; value to compare |
; load data into r6 |
lc 4,r7 ; x2 loop counter |
lc 8,r8 ; x8 loop counter |
|
and r3,r3,r4 |
|
loop2_8: |
lc 4,r7 |
loop2_2: |
ldw r4,0,r6 |
cjne r6,r5,error2_1 |
addi r4,2,r4 |
addi r5,0x0202,r5 |
subi r7,1,r7 |
cjuge r7,r0,loop2_2 |
addi r5,0x0808,r5 |
subi r8,1,r8 |
cjuge r8,r0,loop2_8 |
cjeq r0,r0,skiperr2 |
error2_1: |
lc 0x2000,r1 ;error code |
andi r5,0xff,r5 |
or r1,r5,r2 |
cjeq r0,r0, error2_1 |
skiperr2: ;test 2 passed |
|
lc 2,r2 |
|
; test #3 read long |
lc cl1,r3 ;data base register |
lc 0,r4 ;effective address |
lc 0x0201, r5 ; value to compare |
lch r5,0x0403,r5 |
; load data into r6 |
lc 2,r7 ; x4 loop counter |
lc 8,r8 ; x8 loop counter |
lc 0x0404,r9 ; value to add to r5 |
lch r9,0x0404,r9 |
lc 0x0808,r10 ; add to r5 on loop3_8 |
lch r10,0x0808,r10 |
|
and r3,r3,r4 |
|
loop3_8: |
lc 2,r7 |
loop3_4: |
ldl r4,0,r6 |
cjne r6,r5,error3_1 |
addi r4,4,r4 |
add r5,r9,r5 |
subi r7,1,r7 |
cjuge r7,r0,loop3_4 |
add r5,r10,r5 |
subi r8,1,r8 |
cjuge r8,r0,loop3_8 |
cjeq r0,r0,skiperr3 |
error3_1: |
lc 0x3000,r1 ;error code |
andi r5,0xff,r5 |
or r1,r5,r2 |
cjeq r0,r0, error3_1 |
skiperr3: ;test 3 passed |
|
lc 3,r2 |
|
;test #4 - write byte |
|
lc cl1,r3 ; base of data |
lc cl1,r4 ;adress of write |
lc 64,r5 ; write loop counter |
;r6 save data |
lc 0xff,r7 ; value to store |
loop4_w: |
ldb r4,0,r6 |
stb r4,0,r7 |
and r3,r3,r8 ; adress for read loop |
lc 64,r9 ; counter which gets =r5 for the written item |
lc 0x01, r10 ; compare value |
lc 8, r11 ; x8 loop counter |
;r12 - read data |
|
loop4_chk_8: |
lc 8,r13 ; chk loop x1 counter |
loop4_chk_1: |
ldb r8,0,r12 |
cjeq r9,r5,test4_stored_val |
cjne r12,r10,error4_1 |
test4_good: |
addi r10,1,r10 |
subi r13,1,r13 |
addi r8,1,r8 |
subi r9,1,r9 |
cjuge r13,r0,loop4_chk_1 |
addi r10,8,r10 |
subi r11,1,r11 |
cjuge r11,r0,loop4_chk_8 |
stb r4,0,r6 |
addi r4,1,r4 |
subi r5,1,r5 |
cjuge r5,r0,loop4_w |
cjeq r0,r0,test4_end |
|
error4_1: |
andi r10,0xff,r12 |
ori r12,0x4000,r2 |
cjeq r0,r0,error4_1 |
|
test4_stored_val: |
cjne r12,r7,error4_1 |
cjeq r0,r0,test4_good |
|
test4_end: |
|
lc 4,r2 |
|
|
;test #5 - write word |
|
lc cl1,r3 ; base of data |
lc cl1,r4 ;adress of write |
lc 64,r5 ; write loop counter |
;r6 save data |
lc 0xffff,r7 ; value to store |
loop5_w: |
ldw r4,0,r6 |
stw r4,0,r7 |
and r3,r3,r8 ; adress for read loop |
lc 64,r9 ; counter which gets =r5 for the written item |
lc 0x0201, r10 ; compare value |
lc 8, r11 ; x8 loop counter |
;r12 - read data |
|
loop5_chk_8: |
lc 4,r13 ; chk loop x2 counter |
loop5_chk_2: |
ldw r8,0,r12 |
cjeq r9,r5,test5_stored_val |
cjne r12,r10,error5_1 |
test5_good: |
addi r10,0x0202,r10 |
subi r13,1,r13 |
addi r8,2,r8 |
subi r9,2,r9 |
cjuge r13,r0,loop5_chk_2 |
addi r10,0x0808,r10 |
subi r11,1,r11 |
cjuge r11,r0,loop5_chk_8 |
stw r4,0,r6 |
addi r4,2,r4 |
subi r5,2,r5 |
cjuge r5,r0,loop5_w |
cjeq r0,r0,test5_end |
|
error5_1: |
andi r10,0xff,r12 |
ori r12,0x5000,r2 |
cjeq r0,r0,error5_1 |
|
test5_stored_val: |
cjne r12,r7,error5_1 |
cjeq r0,r0,test5_good |
|
test5_end: |
|
lc 5,r2 |
|
|
;test #6 - write longword |
|
lc cl1,r3 ; base of data |
lc cl1,r4 ;adress of write |
lc 64,r5 ; write loop counter |
;r6 save data |
lc 0xffff,r7 ; value to store |
lch r7,0xffff,r7 |
loop6_w: |
ldl r4,0,r6 |
stl r4,0,r7 |
and r3,r3,r8 ; adress for read loop |
lc 64,r9 ; counter which gets =r5 for the written item |
lc 0x0201, r10 ; compare value |
lch r10,0x0403,r10 |
lc 8, r11 ; x8 loop counter |
;r12 - read data |
lc 0x0404,r14 ; add value to r10 |
lch r14,0x0404,r14 |
lc 0x0808,r15 ; add value r10 - x8 loop |
lch r15,0x0808,r15 |
|
loop6_chk_8: |
lc 2,r13 ; chk loop x4 counter |
loop6_chk_4: |
ldl r8,0,r12 |
cjeq r9,r5,test6_stored_val |
cjne r12,r10,error6_1 |
test6_good: |
add r10,r14,r10 |
subi r13,1,r13 |
addi r8,4,r8 |
subi r9,4,r9 |
cjuge r13,r0,loop6_chk_4 |
add r10,r15,r10 |
subi r11,1,r11 |
cjuge r11,r0,loop6_chk_8 |
stl r4,0,r6 |
addi r4,4,r4 |
subi r5,4,r5 |
cjuge r5,r0,loop6_w |
cjeq r0,r0,test6_end |
|
error6_1: |
andi r10,0xff,r12 |
ori r12,0x6000,r2 |
cjeq r0,r0,error6_1 |
|
test6_stored_val: |
cjne r12,r7,error6_1 |
cjeq r0,r0,test6_good |
|
test6_end: |
|
lc 6,r2 |
|
;test #7 - cacheline register forwarding |
lc cl2,r3 |
lc 5,r4 |
lc cl2_6,r5 |
lc 0,r7 |
lc 15,r8 |
loop7: |
ldl r3,0,r6 |
stl r5,0,r6 |
ldl r5,0,r6 |
add r7,r6,r7 |
addi r3,4,r3 |
subi r4,1,r4 |
cjuge r4,r0,loop7 |
cjeq r8,r7,skiperr7 |
error7_1: |
lc 0x7000,r2 |
cjeq r0,r0,error7_1 |
skiperr7: |
|
lc 7,r2 |
|
; test #8 - cache tag register forwarding |
lc cl2,r3 |
lc 5,r4 |
;lc cl2_6,r5 |
lc 0,r7 |
lc 15,r8 |
lc 0,r9 |
loop8: |
ldl r3,0,r6 |
stl r3,64,r6 |
ldl r3,64,r6 |
ldl r3,0,r5 |
add r7,r6,r7 |
add r9,r5,r9 |
addi r3,4,r3 |
subi r4,1,r4 |
cjuge r4,r0,loop8 |
cjne r9,r8,error8_1 |
cjeq r8,r7,skiperr8 |
error7_1: |
lc 0x8000,r2 |
cjeq r0,r0,error8_1 |
skiperr8: |
|
lc 8,r2 |
|
|
test_end_all: |
cjeq r0,r0,test_end_all |
|
|
section data |
align 64 |
cl1: |
DB 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 |
DB 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 |
DB 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 |
DB 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 |
DB 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 |
DB 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 |
DB 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 |
DB 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 |
cl2: |
DL 1 2 3 4 5 |
cl2_6: |
DL 0 |
section bss |
align 64 |
cl3: |
|
|
/trunk/native asm/flashled3.s
0,0 → 1,23
lc 0,r0 |
lc 159,r3 |
|
loop1: |
lc string,r1 |
lc 8,r2 |
loop2: |
ldb r1,0,r4 |
outb r3,r4 |
addi r1,1,r1 |
subi r2,1,r2 |
cjsgt r2,r0,loop2 |
cjeq r0,r0,loop1 |
|
section data |
string: |
DB 0xb 0xa 0xa 0xd 0xf 0x0 0x0 0xd |
DB 0 |
|
|
|
|
|
/trunk/native asm/calltest.s
0,0 → 1,14
lc 0,r0 |
lc 3,r3 |
lc 1,r4 |
loop1: |
call r0,outr2,r31 |
addi r4,1,r4 |
subi r3,1,r3 |
cjsge r3,r0,loop1 |
loopend: |
cjeq r0,r0,loopend |
|
outr2: |
and r4,r4,r2 |
ret r31 |
/trunk/src/assembler/ascpu2.c
0,0 → 1,688
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
|
|
typedef enum {enc_none,enc_reg,enc_rir,enc_cjmp,enc_nir,enc_store,enc_rnn,enc_in,enc_out} ENCODING; |
struct encentry { ENCODING enc;int opcode;char *name;}; //if name==NULL ==>end of list |
struct instr_reg { unsigned opcode:6; unsigned rA:5,rB:5,rC:5;unsigned _pad:11;}; |
struct instr_cjmp { unsigned opcode:6; unsigned rA:5,rB:5; signed offset:16;}; |
struct instr_rir { unsigned opcode:6; unsigned rA:5,con_0_4:5,rC:5; unsigned con_5_15:11;}; |
struct instr_store { unsigned opcode:6; unsigned rA:5,rB:5; signed offset:16;}; |
struct instr_io { unsigned opcode:6; unsigned rA:5,rB:5,rC:5;unsigned auxcode:6; unsigned _pad:5;}; |
|
typedef union {struct instr_reg reg; struct instr_cjmp cjmp; struct instr_rir rir; struct instr_store store; struct instr_io io; unsigned int code; } instruction; |
|
typedef enum {reloc_cjmp,reloc_li,reloc_lih,reloc_imm,reloc_store} RELOCTYPE; |
struct reloc {struct reloc *next;int offset; int section; RELOCTYPE type;}; |
struct label {char *name; int offset; int section; int resolved; struct reloc *reloc;}; |
struct label_array {int size; int count; struct label *labels;} labels[256]; |
int labelcount=0,labelsize=1024; |
|
int currentsection=0; |
instruction *program; |
int instrcount=0,programlength=1024; |
|
struct section { int length;int size; char *data; unsigned int addr; } sectn[3]; |
|
char *reallocz(char * addr, int old_size, int new_size) |
{ |
char * rtn; |
rtn=realloc(addr,new_size); |
if (old_size<new_size) memset(rtn+old_size,0,new_size-old_size); |
return rtn; |
} |
|
int findhash(char *name) |
{ |
int hash=0,i; |
for (i=0; name[i]!=0; i++) hash=hash+name[i]; |
return hash & 0xff; |
} |
|
int findlabel(char *name) |
{ |
int hash,i,found=0; |
hash=findhash(name); |
for(i=0;i<labels[hash].count;i++) |
{ |
if(strcmp(name,labels[hash].labels[i].name)==0) |
{ |
found=1; |
break; |
} |
} |
if (found) return i; |
else return -1; |
} |
|
int addlabel(char *name, int offset, int section,int resolved) |
{ |
char *szname; |
int hash,labelcount,i; |
hash=findhash(name); |
i=findlabel(name); |
if (i>=0) |
{ |
if (resolved) |
{ |
labels[hash].labels[i].offset=offset; |
labels[hash].labels[i].section=section; |
labels[hash].labels[i].resolved=1; |
} |
return i; |
} |
else |
{ |
if (labels[hash].count>=labels[hash].size) |
{ |
labels[hash].labels=reallocz(labels[hash].labels,labels[hash].size,labels[hash].size*2); |
labels[hash].size=labels[hash].size*2; |
} |
szname=malloc(strlen(name)+1); |
strcpy(szname,name); |
labelcount=labels[hash].count; |
labels[hash].labels[labelcount].name=szname; |
labels[hash].labels[labelcount].offset=offset; |
labels[hash].labels[labelcount].section=section; |
labels[hash].labels[labelcount].resolved=resolved; |
labels[hash].labels[labelcount].reloc=NULL; |
labels[hash].count++; |
return labelcount; |
} |
} |
|
void addreloc(char *labelname, int offset, int section, RELOCTYPE type) |
{ |
int i,hash; |
struct reloc *myreloc; |
hash=findhash(labelname); |
i=addlabel(labelname,0,0,0); |
myreloc=malloc(sizeof(struct reloc)); |
myreloc->next=labels[hash].labels[i].reloc; |
myreloc->offset=offset; |
myreloc->section=section; |
myreloc->type=type; |
labels[hash].labels[i].reloc=myreloc; |
|
} |
|
void apply_relocs() |
{ |
int i,hash; |
struct reloc *rel; |
instruction instr; |
unsigned short int sh_a; |
|
for (hash=0;hash<=255;hash++) |
{ |
for (i=0; i<labels[hash].count; i++) |
{ |
rel=labels[hash].labels[i].reloc; |
while (rel!=NULL) |
{ |
switch(rel->type) |
{ |
case reloc_cjmp: |
if (rel->section==0) |
{ |
if (labels[hash].labels[i].section==0) |
{ |
((short *) sectn[0].data)[(rel->offset+2)/2]=(labels[hash].labels[i].offset-rel->offset)/4; |
} |
} |
break; |
case reloc_li: |
if (rel->section==0) |
{ |
instr=((instruction *) sectn[0].data)[rel->offset/4]; |
sh_a=(sectn[labels[hash].labels[i].section].addr+labels[hash].labels[i].offset); |
// fprintf(stderr,"*** reloc lc %s, sh_a=%i\n",labels[hash].labels[i].name,sh_a); |
instr.rir.con_0_4=sh_a & 0x1f; |
instr.rir.con_5_15=sh_a >> 5; |
((instruction *) sectn[0].data)[rel->offset/4]=instr; |
} |
break; |
case reloc_lih: |
if (rel->section==0) |
{ |
instr=((instruction *) sectn[0].data)[rel->offset/4]; |
sh_a=(sectn[labels[hash].labels[i].section].addr+labels[hash].labels[i].offset) >> 16; |
instr.rir.con_0_4=sh_a & 0x1f; |
instr.rir.con_5_15=sh_a >> 5; |
((instruction *) sectn[0].data)[rel->offset/4]=instr; |
} |
break; |
case reloc_imm: |
if (rel->section==0) |
{ |
instr=((instruction *) sectn[0].data)[rel->offset/4]; |
sh_a=(sectn[labels[hash].labels[i].section].addr+labels[hash].labels[i].offset) >> 16; |
instr.store.offset=sh_a; |
((instruction *) sectn[0].data)[rel->offset/4]=instr; |
} |
break; |
case reloc_store: |
if (rel->section==0) |
{ |
instr=((instruction *) sectn[0].data)[rel->offset/4]; |
sh_a=(sectn[labels[hash].labels[i].section].addr+labels[hash].labels[i].offset) & 0xffff; |
//fprintf(stderr,"*** reloc lc %s, sh_a=%i\n",labels[hash].labels[i].name,sh_a); |
instr.store.offset=sh_a; |
((instruction *) sectn[0].data)[rel->offset/4]=instr; |
} |
break; |
|
} |
rel=rel->next; |
} |
} |
} |
} |
|
int main() |
{ |
int chr; |
int toplevel=1; |
int tokenchars=0; |
char token[256]; |
int tokencount=0; |
char tokens[16][256]; |
int i,a,b,c,d; |
signed short sh_a; |
int comma=0; |
int PC=0; |
int nexttoken=0; |
int error=0; |
int inquote=0; |
int incomment=0; |
int lineno=0; |
|
instruction instr; |
instruction extraInstr; |
int hasExtraInstr=0; |
|
static struct encentry instrset[]={ |
{enc_rir,0,"lih"}, |
{enc_rir,0,"lch"}, |
{enc_nir,1,"li"}, |
{enc_nir,1,"lc"}, |
{enc_reg,2,"and"}, |
{enc_rir,3,"andi"}, |
{enc_reg,4,"or"}, |
{enc_rir,5,"ori"}, |
{enc_reg,6,"xor"}, |
{enc_rir,7,"xori"}, |
{enc_reg,8,"add"}, |
{enc_rir,9,"addi"}, |
{enc_reg,10,"sub"}, |
{enc_rir,11,"subi"}, |
{enc_none,12,"nop"}, |
{enc_rir,13,"andi1"}, |
{ enc_reg, 14, "shl" }, |
{ enc_rir, 15, "shli" }, |
{ enc_reg, 16, "shr" }, |
{ enc_rir, 17, "shri" }, |
{ enc_reg, 18, "sar" }, |
{ enc_rir, 19, "sari" }, |
{ enc_in, 0, "inb" }, |
{enc_in,1,"inw"}, |
{enc_in,2,"inl"}, |
{enc_out,4,"outb"}, |
{enc_out,5,"outw"}, |
{enc_out,6,"outl"}, |
{enc_cjmp,32,"cjule"}, |
{enc_cjmp,32,"cjc"}, |
{enc_cjmp,33,"cjugt"}, |
{enc_cjmp,33,"cjnc"}, |
{enc_cjmp,34,"cjeq"}, |
{enc_cjmp,35,"cjne"}, |
{enc_cjmp,36,"cjult"}, |
{enc_cjmp,37,"cjuge"}, |
{enc_cjmp,38,"cjn"}, |
{enc_cjmp,39,"cjnn"}, |
{enc_cjmp,40,"cjslt"}, |
{enc_cjmp,41,"cjsge"}, |
{enc_cjmp,42,"cjsle"}, |
{enc_cjmp,43,"cjsgt"}, |
{enc_cjmp,44,"cjo"}, |
{enc_cjmp,45,"cjno"}, |
{enc_rir,46,"call"}, |
{enc_rnn,47,"ret"}, |
{enc_rir,56,"ldl"}, |
{enc_rir,57,"ldw"}, |
{enc_rir,58,"ldb"}, |
{enc_store,60,"stl"}, |
{enc_store,61,"stw"}, |
{enc_store,62,"stb"}, |
{enc_none,-1,NULL} |
}; |
|
//program=malloc(programlength*(sizeof(instruction))); |
for (i=0; i<=255; i++) |
{ |
labels[i].count=0; |
labels[i].size=16; |
labels[i].labels=malloc(16*(sizeof(struct label))); |
memset(labels[i].labels,0,16*(sizeof(struct label))); |
} |
|
for (i=0; i<=2; i++) |
{ |
sectn[i].length=0; |
sectn[i].addr=0; |
sectn[i].size=4096; |
sectn[i].data=malloc(4096); |
memset(sectn[i].data,0,4096); |
} |
|
while(1) |
{ |
chr=fgetc(stdin); |
if (chr==';') {incomment=1; continue; } |
if (incomment) goto handle_newline_eof; |
if (chr=='"') |
{ |
if (!inquote) {inquote=1; continue;} |
else { inquote=0; continue;} |
} |
if (inquote && (chr!='\n') && (chr!=EOF)) |
{ |
if (toplevel) {token[0]=chr;tokenchars=1;toplevel=0;} else {token[tokenchars]=chr;tokenchars++;} |
continue; |
} |
if ((chr>='a' && chr<='z')||(chr>='A' && chr<='Z')||(chr>='0' && chr<='9')||(chr=='_')) |
{ |
comma=0; |
if (toplevel) {token[0]=chr;tokenchars=1;toplevel=0;} else {token[tokenchars]=chr;tokenchars++;} |
} |
if (chr==' ' || chr=='\t') |
{if (toplevel) {} else |
{for(i=0;i<tokenchars;i++) tokens[tokencount][i]=token[i]; |
tokens[tokencount][tokenchars]=0; |
tokencount++; |
toplevel=1; |
} |
} |
if (chr==',' || chr==':') //single character tokens |
{if (toplevel) {tokens[tokencount][0]=chr;tokens[tokencount][1]=0;tokencount++;} else |
{for(i=0;i<tokenchars;i++) tokens[tokencount][i]=token[i]; |
tokens[tokencount][tokenchars]=0; |
tokencount++; |
tokens[tokencount][0]=chr;tokens[tokencount][1]=0;tokencount++; |
toplevel=1; |
} |
} |
/* if (chr==':') |
{if (toplevel) {tokens[tokencount][0]=':';tokens[tokencount][1]=0;tokencount++;} else |
{for(i=0;i<tokenchars;i++) tokens[tokencount][i]=token[i]; |
tokens[tokencount][tokenchars]=0; |
tokencount++; |
tokens[tokencount][0]=':';tokens[tokencount][1]=0;tokencount++; |
toplevel=1; |
} |
}*/ |
handle_newline_eof: |
if (chr=='\n' || chr==EOF) |
{ |
incomment=0; |
lineno++; |
if (toplevel) {} else |
{for(i=0;i<tokenchars;i++) tokens[tokencount][i]=token[i]; |
tokens[tokencount][tokenchars]=0; |
tokencount++; |
toplevel=1; |
} |
//for (i=0;i<tokencount;i++) printf ("t%i:%s\n",i,&tokens[i][0]); |
nexttoken=0; |
if (tokencount>=2 && !strcmp(tokens[1],":")) |
{addlabel(tokens[0],sectn[currentsection].length,currentsection,1); |
nexttoken=2; |
} |
//i=0; |
error=1; |
if (tokencount<=nexttoken) error=0; |
//printf("eRror %i\n",error); |
if (tokencount>nexttoken+1) |
{ |
if (!strcmp(tokens[nexttoken],"section")) |
{ |
if (!strcmp(tokens[nexttoken+1],"code")) {error=0;currentsection=0;} |
if (!strcmp(tokens[nexttoken+1],"data")) {error=0;currentsection=1;} |
if (!strcmp(tokens[nexttoken+1],"bss" )) {error=0;currentsection=2;} |
} |
|
if (!strcmp(tokens[nexttoken],"align")) |
{ |
if (sscanf(tokens[nexttoken+1],"0x%x",&a)==1) |
error=0; |
else if (sscanf(tokens[nexttoken+1],"%i",&a)==1) |
error=0; |
if (error==0) |
{ |
error=1; |
b=0xffffffff; |
for (i=0; (i<7) && (a!=1<<i); i++) |
{ |
b=b<<1; |
} |
if (i<7) |
{ |
if (((sectn[currentsection].length+(1<<i)-1) & b) > sectn[currentsection].size) |
{ |
sectn[currentsection].data=reallocz(sectn[currentsection].data,sectn[currentsection].size,sectn[currentsection].size*2); |
sectn[currentsection].size+=sectn[currentsection].size; |
} |
sectn[currentsection].length=(sectn[currentsection].length+(1<<i)-1) & b; |
error=0; |
} |
} |
|
} |
|
if (!strcmp(tokens[nexttoken],"DS")) |
{ |
for (i=0; i<strlen(tokens[nexttoken+1]); i++) |
{ |
//if (sscanf(tokens[i],"%i",&a)!=1) |
// sscanf(tokens[i],"0x%x",&a); |
a=tokens[nexttoken+1][i]; |
if (sectn[currentsection].length>=sectn[currentsection].size) |
{ |
sectn[currentsection].data=reallocz(sectn[currentsection].data,sectn[currentsection].size,sectn[currentsection].size*2); |
sectn[currentsection].size+=sectn[currentsection].size; |
} |
sectn[currentsection].data[sectn[currentsection].length]=a; |
sectn[currentsection].length++; |
} |
error=0; |
} //DS |
|
if (!strcmp(tokens[nexttoken],"DB")) |
{ |
for (i=nexttoken+1; i<tokencount; i++) |
{ |
if (sscanf(tokens[i],"0x%x",&a)!=1) |
sscanf(tokens[i],"%i",&a); |
if (sectn[currentsection].length>=sectn[currentsection].size) |
{ |
sectn[currentsection].data=reallocz(sectn[currentsection].data,sectn[currentsection].size,sectn[currentsection].size*2); |
sectn[currentsection].size+=sectn[currentsection].size; |
} |
sectn[currentsection].data[sectn[currentsection].length]=a; |
sectn[currentsection].length++; |
} |
error=0; |
} |
if (!strcmp(tokens[nexttoken],"DW")) |
{ |
for (i=nexttoken+1; i<tokencount; i++) |
{ |
if (sscanf(tokens[i],"0x%x",&a)!=1) |
sscanf(tokens[i],"%i",&a); |
if (sectn[currentsection].length+2>sectn[currentsection].size) |
{ |
sectn[currentsection].data=reallocz(sectn[currentsection].data,sectn[currentsection].size,sectn[currentsection].size*2); |
sectn[currentsection].size+=sectn[currentsection].size; |
} |
*((short int *) &(sectn[currentsection].data[sectn[currentsection].length]))=a; |
sectn[currentsection].length+=2; |
} |
error=0; |
} |
if (!strcmp(tokens[nexttoken],"DL")) |
{ |
for (i=nexttoken+1; i<tokencount; i++) |
{ |
if (sscanf(tokens[i],"0x%x",&a)!=1) |
sscanf(tokens[i],"%i",&a); |
if (sectn[currentsection].length+4>sectn[currentsection].size) |
{ |
sectn[currentsection].data=reallocz(sectn[currentsection].data,sectn[currentsection].size,sectn[currentsection].size*2); |
sectn[currentsection].size+=sectn[currentsection].size; |
} |
*((int *) &(sectn[currentsection].data[sectn[currentsection].length]))=a; |
sectn[currentsection].length+=4; |
|
} |
error=0; |
} |
} |
|
if ((tokencount>nexttoken) && (error==1)) |
{ |
for (i=0;;i++) |
{ |
if (instrset[i].name==NULL) break; |
if (strcmp(tokens[nexttoken],instrset[i].name)==0) break; |
} |
instr.code=0; |
error=0; |
hasExtraInstr=0; |
extraInstr.code=0; |
if (instrset[i].name==NULL) error=1; |
else |
switch (instrset[i].enc) |
{ |
case enc_none: instr.reg.opcode=instrset[i].opcode; break; |
case enc_reg: |
if (tokencount-nexttoken==6) |
{ |
instr.reg.opcode=instrset[i].opcode; |
if (sscanf(tokens[nexttoken+1],"r%d",&a)!=1) error=1; |
if (strcmp(tokens[nexttoken+2],",")) error=1; |
if (sscanf(tokens[nexttoken+3],"r%d",&b)!=1) error=1; |
if (strcmp(tokens[nexttoken+4],",")) error=1; |
if (sscanf(tokens[nexttoken+5],"r%d",&c)!=1) error=1; |
instr.reg.rA=a; |
instr.reg.rB=b; |
instr.reg.rC=c; |
|
} |
else error=1; |
break; |
case enc_rir: |
if (tokencount-nexttoken==6) |
{ |
instr.rir.opcode=instrset[i].opcode; |
if (sscanf(tokens[nexttoken+1],"r%d",&a)!=1) error=1; |
if (strcmp(tokens[nexttoken+2],",")) error=1; |
if (sscanf(tokens[nexttoken+3],"0x%x",&d)!=1) |
if (sscanf(tokens[nexttoken+3],"%d",&d)!=1) |
{ |
addreloc(tokens[nexttoken+3],sectn[0].length,0,reloc_imm); |
addreloc(tokens[nexttoken+3],sectn[0].length+4,0,reloc_li); |
d=0xbaadf00d; |
} |
if (strcmp(tokens[nexttoken+4],",")) error=1; |
if (sscanf(tokens[nexttoken+5],"r%d",&c)!=1) error=1; |
sh_a=(signed short) d; |
instr.rir.rA=a; |
instr.rir.rC=c; |
instr.rir.con_0_4=sh_a & 0x1f; |
instr.rir.con_5_15=sh_a >> 5; |
if (sh_a!=d) |
{ |
extraInstr.store.opcode=30; |
extraInstr.store.offset=d>>16; |
hasExtraInstr=1; |
} |
|
} |
else error=1; |
break; |
case enc_nir: |
if (tokencount-nexttoken==4) |
{ |
instr.rir.opcode=instrset[i].opcode; |
if (sscanf(tokens[nexttoken+1],"0x%x",&a)!=1) |
if (sscanf(tokens[nexttoken+1],"%d",&a)!=1) |
{//li |
addreloc(tokens[nexttoken+1],sectn[0].length+4,0,reloc_li); |
addreloc(tokens[nexttoken+1],sectn[0].length,0,reloc_imm); |
a=0xbaadf00d; |
//printf("reloc\n"); |
} |
if (strcmp(tokens[nexttoken+2],",")) error=1; |
if (sscanf(tokens[nexttoken+3],"r%d",&c)!=1) error=1; |
sh_a=(signed short) a; |
instr.rir.rA=0; |
instr.rir.rC=c; |
instr.rir.con_0_4=sh_a & 0x1f; |
instr.rir.con_5_15=sh_a >> 5; |
//printf("sh_a=%i,token=%s\n",sh_a,tokens[nexttoken+1]); |
if (sh_a!=a) |
{ |
hasExtraInstr=1; |
extraInstr.store.opcode=30; |
extraInstr.store.offset=a>>16; |
} |
} |
else error=1; |
break; |
|
case enc_cjmp: |
if (tokencount-nexttoken==6) |
{ |
instr.reg.opcode=instrset[i].opcode; |
if (sscanf(tokens[nexttoken+1],"r%d",&a)!=1) error=1; |
if (strcmp(tokens[nexttoken+2],",")) error=1; |
if (sscanf(tokens[nexttoken+3],"r%d",&b)!=1) error=1; |
if (strcmp(tokens[nexttoken+4],",")) error=1; |
//if (sscanf(tokens[nexttoken+5],"r%d",&c)!=1) error=1; |
instr.cjmp.rA=a; |
instr.cjmp.rB=b; |
if (error==0) addreloc(tokens[nexttoken+5],sectn[0].length,0,reloc_cjmp); |
|
} |
else error=1; |
break; |
|
case enc_store: |
if (tokencount-nexttoken==6) |
{ |
instr.rir.opcode=instrset[i].opcode; |
if (sscanf(tokens[nexttoken+1],"r%d",&a)!=1) error=1; |
if (strcmp(tokens[nexttoken+2],",")) error=1; |
if (sscanf(tokens[nexttoken+3],"0x%x",&d)!=1) |
if (sscanf(tokens[nexttoken+3],"%d",&d)!=1) |
{ |
addreloc(tokens[nexttoken+3],sectn[0].length+4,0,reloc_store); |
addreloc(tokens[nexttoken+3],sectn[0].length,0,reloc_imm); |
d=0xbaadf00d; |
} |
if (strcmp(tokens[nexttoken+4],",")) error=1; |
if (sscanf(tokens[nexttoken+5],"r%d",&c)!=1) error=1; |
sh_a=(signed short) d; |
instr.cjmp.rA=a; |
instr.cjmp.rB=c; |
instr.cjmp.offset=sh_a; |
if (sh_a!=d) |
{ |
hasExtraInstr=1; |
extraInstr.store.opcode=30; |
extraInstr.store.offset=d>>16; |
} |
|
} |
else error=1; |
break; |
|
case enc_rnn: |
if (tokencount-nexttoken==2) |
{ |
instr.rir.opcode=instrset[i].opcode; |
if (sscanf(tokens[nexttoken+1],"r%d",&a)!=1) error=1; |
instr.rir.rA=a; |
|
} |
else error=1; |
break; |
|
case enc_in: |
if (tokencount-nexttoken==4) |
{ |
instr.io.opcode=31; |
instr.io.auxcode=instrset[i].opcode; |
if (sscanf(tokens[nexttoken+1],"r%d",&a)!=1) error=1; |
if (strcmp(tokens[nexttoken+2],",")) error=1; |
if (sscanf(tokens[nexttoken+3],"r%d",&b)!=1) error=1; |
|
instr.io.rA=a; |
instr.io.rB=0; |
instr.io.rC=b; |
|
} |
else error=1; |
break; |
|
case enc_out: |
if (tokencount-nexttoken==4) |
{ |
instr.io.opcode=31; |
instr.io.auxcode=instrset[i].opcode; |
if (sscanf(tokens[nexttoken+1],"r%d",&a)!=1) error=1; |
if (strcmp(tokens[nexttoken+2],",")) error=1; |
if (sscanf(tokens[nexttoken+3],"r%d",&b)!=1) error=1; |
|
instr.io.rA=a; |
instr.io.rB=b; |
instr.io.rC=0; |
|
} |
else error=1; |
break; |
|
default: error=1; |
} |
// if (error==0) printf("hexcode %x,name %s\n",instr.code,instrset[i].name); |
if (error==0) |
{ |
// printf("hexcode %x,name %s\n",instr.code,instrset[i].name); |
if (hasExtraInstr) |
{ |
if (sectn[0].length+4>sectn[0].size) |
{ |
sectn[0].data=reallocz(sectn[0].data,sectn[0].size,2*sectn[0].size); |
sectn[0].size+=sectn[0].size; |
} |
((instruction * )sectn[0].data)[(sectn[0].length+3)/4]=extraInstr; |
PC+=4; |
sectn[0].length=(sectn[0].length+4+3) & 0xfffffffc; |
} |
if (sectn[0].length+4>sectn[0].size) |
{ |
sectn[0].data=reallocz(sectn[0].data,sectn[0].size,2*sectn[0].size); |
sectn[0].size+=sectn[0].size; |
} |
((instruction * )sectn[0].data)[(sectn[0].length+3)/4]=instr; |
PC+=4; |
sectn[0].length=(sectn[0].length+4+3) & 0xfffffffc; |
} |
|
} //else error=1; |
if (error) printf("error in line %i\n",lineno); |
tokencount=0; |
if (chr==EOF) |
{ |
//printf("EOF\n"); |
sectn[0].addr=0;//todo:origin |
for (i=1; i<=2; i++) |
sectn[i].addr=(sectn[i-1].addr+sectn[i-1].length+63) & 0xffffffc0; |
apply_relocs(); |
for (a=0; a<=1; a++) |
{ |
//printf("a=%i\n",a); |
for (i=0;i<((sectn[a].length+63)& 0xffffffc0)/4;i++) |
{ |
printf("%x\n",((unsigned int *) sectn[a].data)[i]); |
} |
} |
exit(0); |
|
} |
} |
|
} |
|
} |
/trunk/testmem6.hex
0,0 → 1,320
1 |
20001 |
1e |
5030001 |
45001 |
3e54001 |
28fc |
55949 |
100300c9 |
4090b |
fffc0125 |
1e |
5030001 |
45001 |
3e54001 |
600f8 |
629a3 |
55949 |
100300c9 |
4090b |
fffb0125 |
40022 |
1e |
90020001 |
fffe0022 |
24801 |
1e |
5030001 |
45001 |
3e54001 |
270001 |
818c2 |
2a3d |
55949 |
81209 |
709cb |
fffc01e5 |
100300c9 |
4090b |
fff70125 |
1e |
5030001 |
45001 |
3e54001 |
270001 |
818c2 |
60239 |
929a3 |
55949 |
81209 |
709cb |
fffb01e5 |
100300c9 |
4090b |
fff60125 |
40022 |
1e |
a0020001 |
fffe0022 |
25001 |
1e |
4830001 |
40001 |
50801 |
74001 |
84001 |
418c2 |
74001 |
6013a |
929a3 |
40909 |
50949 |
709cb |
fffb01e5 |
54149 |
80a0b |
fff70225 |
40022 |
10010001 |
22844 |
fffe0022 |
20801 |
1e |
4830001 |
40001 |
2050801 |
72001 |
84001 |
418c2 |
72001 |
60139 |
929a3 |
41109 |
2051149 |
709cb |
fffb01e5 |
8054149 |
80a0b |
fff70225 |
50022 |
20010001 |
e5f943 |
22844 |
fffd0022 |
21001 |
1e |
4830001 |
40001 |
2050801 |
4051940 |
71001 |
84001 |
4092001 |
4092240 |
80a4001 |
80a4280 |
418c2 |
71001 |
60138 |
929a3 |
42109 |
54948 |
709cb |
fffb01e5 |
55148 |
80a0b |
fff70225 |
50022 |
30010001 |
e5f943 |
22844 |
fffd0022 |
21801 |
1e |
4830001 |
1e |
4840001 |
450001 |
e7f801 |
6013a |
393e |
818c2 |
490001 |
a0801 |
b4001 |
d4001 |
c023a |
122a62 |
e5323 |
a0a89 |
d0b4b |
80a09 |
90a4b |
fff90365 |
a4289 |
b0acb |
fff502e5 |
313e |
40909 |
5094b |
ffeb0165 |
60022 |
ecfa83 |
40020305 |
fffe0022 |
fffd3b23 |
ffef0022 |
22001 |
1e |
4830001 |
1e |
4840001 |
450001 |
1e |
ffe7f801 |
60139 |
393d |
818c2 |
490001 |
20a0801 |
b4001 |
d2001 |
c0239 |
122a62 |
e5323 |
20a1289 |
d0b4b |
81209 |
9124b |
fff90365 |
80a4289 |
b0acb |
fff502e5 |
313d |
41109 |
5114b |
ffeb0165 |
60022 |
ecfa83 |
50020305 |
fffe0022 |
fffd3b23 |
ffef0022 |
22801 |
1e |
4830001 |
1e |
4840001 |
450001 |
1e |
ffe7f801 |
1e |
ffe7f9c0 |
60138 |
393c |
818c2 |
490001 |
20a0801 |
40a1a80 |
b4001 |
40e2001 |
40e2380 |
80f4001 |
80f43c0 |
d1001 |
c0238 |
122a62 |
e5323 |
a7288 |
d0b4b |
82209 |
9224b |
fff90365 |
a7a88 |
b0acb |
fff502e5 |
313c |
42109 |
5214b |
ffe60165 |
60022 |
ecfa83 |
60020305 |
fffe0022 |
fffd3b23 |
ffef0022 |
23001 |
1e |
4c30001 |
42801 |
1e |
4c5a001 |
70001 |
87801 |
600f8 |
317c |
60178 |
731c8 |
320c9 |
4090b |
fffa0125 |
33a22 |
70020001 |
130022 |
23801 |
1e |
4c30001 |
42801 |
70001 |
87801 |
90001 |
600f8 |
4030fc |
4600f8 |
500f8 |
731c8 |
92a48 |
320c9 |
4090b |
fff80125 |
fee84263 |
43a22 |
1e |
80020001 |
fee40022 |
24001 |
22 |
|
4030201 |
8070605 |
14131211 |
18171615 |
24232221 |
28272625 |
34333231 |
38373635 |
44434241 |
48474645 |
54535251 |
58575655 |
64636261 |
68676665 |
74737271 |
78777675 |
1 |
2 |
3 |
4 |
5 |
|
|
|
|
|
|
|
|
|
|
|
/trunk/arch.txt
0,0 → 1,102
imm is either 16 bit sign extended or full 32 bit with prefix instr(except andi1) |
there are 32 registers |
alu instructions have 6-bit opcode(lowest 6 bits), shared with conditional jumps and load/store and call |
2 opcodes reserved for future 64bitload&store (59 & 63) |
not shared with in/out |
no condition flags exist in this architecture so far, instead, use compare-and-jump |
opcode 32 is used for i/o and system instructions, using the other bits |
i/o instructions have additional opcode at bits 26:21, but this can be used for system |
instructions also. |
|
opcode 30 prefix imm |
|
opcode 0 |
lih reg1,imm,reg2 |
lch reg1,imm,reg2 //equivalent |
store imm into upper half of reg2, reg1's lower half into lower half of reg2 |
opcode 1 |
li imm,reg |
lc imm,reg |
store imm into reg |
opcode 2 |
and reg1,reg2,reg2 |
reg2=reg1®2 |
opcode 3 |
andi reg1,imm,reg2 |
reg2=reg1&imm |
opcode 4 |
or reg1,reg2,reg3 |
reg3=reg1|reg2 |
opcode 5 |
ori reg1,imm,reg |
reg2=reg1|imm |
opcode 6 |
xor reg1,reg2,reg3 |
reg3=reg1^reg2 |
opcode 7 |
xori reg1,imm,reg2 |
reg2=imm^reg1 |
opcode 8 |
add reg1,reg2,reg3 |
reg3=reg1+reg2 |
opcode 9 |
addi reg1,imm,reg2 |
reg2=reg1+imm |
opcode 10 |
sub reg1,reg2,reg3 |
reg3=reg1-reg2 |
opcode 11 |
subi reg1,imm,reg2 |
reg2=reg1-imm |
opcode 12 |
nop |
no operation |
opcode 13 |
andi1 reg1,imm,reg2 |
reg2=reg1 & imm(one extended) |
|
shl reg1,reg2,reg3 |
shli reg1,imm,reg2 |
shr reg1,reg2, |
reg3 |
shri reg1,imm,reg2 |
sar reg1,reg2,reg3 |
sari reg1,imm,reg2 |
|
|
inb r1,r2 |
inw r1,r2 |
inl r1,r2 |
|
outb r1,r2 |
outw r1,r2 |
outl r1,r2 |
|
conditional jumps |
cjule r1,r2, label |
cjc r1,r2, label |
cjugt r1,r2, label |
cjnc r1,r2, label |
cjeq r1,r2, label |
cjne r1,r2, label |
cjult r1,r2, label |
cjuge r1,r2, label |
cjn r1,r2, label |
cjnn r1,r2, label |
cjslt r1,r2, label |
cjsge r1,r2, label |
cjsle r1,r2, label |
cjsgt r1,r2, label |
cjo r1,r2, label |
cjno r1,r2, label |
call r1,imm,r2 |
call (r1+imm) return addr=r2 |
ret r1 |
|
ldl r1,imm/label,r2 |
ldw r1,imm/label,r2 |
ldb r1,imm/label,r2 |
|
stl r1,imm/label,r2 |
stw r1,imm/label,r2 |
stb r1,imm/label,r2 |