OpenCores
URL https://opencores.org/ocsvn/suslik/suslik/trunk

Subversion Repositories suslik

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /suslik/trunk
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/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
/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
/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
/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
 
 
/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
/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:
 
 
/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
 
 
 
 
 
/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
/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);
}
}
}
 
}
/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
 
 
 
 
 
 
 
 
 
 
 
/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&reg2
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.