URL
https://opencores.org/ocsvn/suslik/suslik/trunk
Subversion Repositories suslik
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 4 to Rev 5
- ↔ Reverse comparison
Rev 4 → Rev 5
/suslik/branches/tlb/License.txt
0,0 → 1,14
Copyright (c) 2016, Goran Dakov |
|
All rights reserved. |
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: |
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. |
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. |
|
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. |
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
/suslik/branches/tlb/rtl/License.txt
0,0 → 1,14
Copyright (c) 2016, Goran Dakov |
|
All rights reserved. |
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: |
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. |
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. |
|
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. |
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
/suslik/branches/tlb/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 |
/suslik/branches/tlb/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 |
/suslik/branches/tlb/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 |
/suslik/branches/tlb/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 |
|
|
/suslik/branches/tlb/native asm/License.txt
0,0 → 1,14
Copyright (c) 2016, Goran Dakov |
|
All rights reserved. |
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: |
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. |
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. |
|
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. |
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
/suslik/branches/tlb/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 |
/suslik/branches/tlb/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: |
|
|
/suslik/branches/tlb/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 |
|
|
|
|
|
/suslik/branches/tlb/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 |
/suslik/branches/tlb/src/assembler/License.txt
0,0 → 1,14
Copyright (c) 2016, Goran Dakov |
|
All rights reserved. |
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: |
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. |
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. |
|
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. |
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
/suslik/branches/tlb/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); |
|
} |
} |
|
} |
|
} |
/suslik/branches/tlb/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 |
|
|
|
|
|
|
|
|
|
|
|
/suslik/branches/tlb/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 |