📄 blitter.v
字号:
chs=CHB; if(bltcon0[9]) bltnext=BLT_NB_3; else bltnext=BLT_NB_4; end BLT_NB_3://normal blitter operation cycle 3 (always dma, skipped otherwise) begin acn={2'b10,lwt,1'b1}; scn=5'b00001; chs=CHC; bltnext=BLT_NB_4; end BLT_NB_4://normal blitter operation cycle 4 begin if(bltcon0[8] && bbusyd)//DMA (only if not first cycle) acn={2'b10,lwtd,1'b1}; else//internal acn=4'b0x00; scn={3'b000,~bbusyd,1'b1};//if first (dummy) cycle, set blitter zero flag chs=CHD; bltnext=BLT_NB_1; end default://unknown state, go back to reset state begin //-----IDRZB scn=5'bxxxx1; //-----RBMA acn=4'b0xxx; chs=2'bxx; bltnext=BLT_DONE; end endcase end//--------------------------------------------------------------------------------------endmodule//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//Blitter barrel shifter//This module can shift 0-15 positions/bits to the right (normal mode) or to the left//(descending mode). Inputs are two words, <new> and <old>.//For example, when shifting <new> to the right,//the bits to the left are filled with <old>. The bits of <new> that //are shifted out are discarded. module bltshift( input desc, //select descending mode (shift to the left) input [3:0]sh, //shift value (0 to 15) input [15:0]new, //barrel shifter data in input [15:0]old, //barrel shifter data in output reg [15:0]out //barrel shifter data out);//local signalswire [30:0]bshiftin; //barrel shifter inputwire [3:0]bsh; //barrel shift value//cross multiplexer feeding barrelshifterassign bshiftin[30:0]=(desc)?{new[15:0],old[15:1]}:{old[14:0],new[15:0]};//shift value generator for barrel shifterassign bsh[3:0]=(desc)?(~sh[3:0]):sh[3:0];//actual barrel shifteralways @(bsh or bshiftin) case(bsh[3:0]) 0: out[15:0]=bshiftin[15:0]; 1: out[15:0]=bshiftin[16:1]; 2: out[15:0]=bshiftin[17:2]; 3: out[15:0]=bshiftin[18:3]; 4: out[15:0]=bshiftin[19:4]; 5: out[15:0]=bshiftin[20:5]; 6: out[15:0]=bshiftin[21:6]; 7: out[15:0]=bshiftin[22:7]; 8: out[15:0]=bshiftin[23:8]; 9: out[15:0]=bshiftin[24:9]; 10: out[15:0]=bshiftin[25:10]; 11: out[15:0]=bshiftin[26:11]; 12: out[15:0]=bshiftin[27:12]; 13: out[15:0]=bshiftin[28:13]; 14: out[15:0]=bshiftin[29:14]; 15: out[15:0]=bshiftin[30:15]; endcaseendmodule//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//Blitter minterm function generator//The minterm function generator takes <ain>,<bin> and <cin> //and checks every logic combination against the LF control byte.//If a combination is marked as 1 in the LF byte, the ouput will//also be 1, else the output is 0.module bltminterm( input [7:0]lf, //LF control byte input [15:0]ain, //A channel in input [15:0]bin, //B channel in input [15:0]cin, //C channel in output [15:0]out //function generator output);reg [15:0]mt0; //minterm 0reg [15:0]mt1; //minterm 1reg [15:0]mt2; //minterm 2reg [15:0]mt3; //minterm 3reg [15:0]mt4; //minterm 4reg [15:0]mt5; //minterm 5reg [15:0]mt6; //minterm 6reg [15:0]mt7; //minterm 7//Minterm generator for each bit. The code inside the loop //describes one bit. The loop is 'unrolled' by the //synthesizer to cover all 16 bits in the word.integer j;always @(ain or bin or cin or lf) for(j=15;j>=0;j=j-1) begin mt0[j]=(~ain[j])&(~bin[j])&(~cin[j])&lf[0]; mt1[j]=(~ain[j])&(~bin[j])&( cin[j])&lf[1]; mt2[j]=(~ain[j])&( bin[j])&(~cin[j])&lf[2]; mt3[j]=(~ain[j])&( bin[j])&( cin[j])&lf[3]; mt4[j]=( ain[j])&(~bin[j])&(~cin[j])&lf[4]; mt5[j]=( ain[j])&(~bin[j])&( cin[j])&lf[5]; mt6[j]=( ain[j])&( bin[j])&(~cin[j])&lf[6]; mt7[j]=( ain[j])&( bin[j])&( cin[j])&lf[7]; end//Generate function generator output by or-ing all//minterms together.assign out=mt0|mt1|mt2|mt3|mt4|mt5|mt6|mt7;endmodule //--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//Blitter fill logic//The fill logic module has 2 modes, inclusive fill and exclusive fill.//Both share the same xor operation but in inclusive fill mode,//the output of the xor-filler is or-ed with the input data. module bltfill( input ife, //inclusive fill enable input efe, //exclusive fill enable input fci, //fill carry input output fco, //fill carry output input [15:0]in, //data in output reg [15:0]out //data out);//local signalsreg [15:0]carry;//generate all fill carry'sinteger j;always @(fci or in[0])//least significant bit carry[0]=fci^in[0]; always @(in or carry)//rest of bits for(j=1;j<=15;j=j+1) carry[j]=carry[j-1]^in[j];//fill carry outputassign fco=carry[15];//fill data outputalways @(ife or efe or carry or in) if(efe)//exclusive fill out[15:0]=carry[15:0]; else if(ife)//inclusive fill out[15:0]=carry[15:0]|in[15:0]; else//bypass, no filling out[15:0]=in[15:0];endmodule//--------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------//Blitter address generator//This module generates the addresses for blitter DMA//It has 4 21bit pointer registers, 4 16bit modulo //registers and an ALU that can add and subtract//alu function codes bits [3:2]://00 = bypass (no operation)//01 = bypass (no operation)//10 = add modulo //11 = subtract modulo //alu function codes bits [1:0]://00 = bypass (no operation)//01 = bypass (no operation)//10 = add 2 (next word)//11 = subtract 2 (previous word)////when modb=1, address pointer selection remains unchanged but modulo selection is as follows://chs[1:0] modb=0 modb=1//2'b00 A B//2'b01 B B//2'b10 C C//2'b11 D Cmodule bltaddress( input clk, //bus clock input reset, //reset input enable, //cycle enable input input modb, //always select modulo B or C (dependening of chs[1]) input [1:0]chs, //channel select input [3:0]alu, //ALU function select output signout, //sign output (used for line mode) input [15:0]datain, //bus data in input [8:1]regaddressin, //register address input output reg [20:1]addressout //generated address out);//register names and addressesparameter BLTAMOD=9'h064;parameter BLTBMOD=9'h062;parameter BLTCMOD=9'h060;parameter BLTDMOD=9'h066;parameter BLTAPTH=9'h050;parameter BLTAPTL=9'h052;parameter BLTBPTH=9'h04c;parameter BLTBPTL=9'h04e;parameter BLTCPTH=9'h048;parameter BLTCPTL=9'h04a;parameter BLTDPTH=9'h054;parameter BLTDPTL=9'h056;//local signalsreg [15:1]bltamod; //blitter modulo for source Areg [15:1]bltbmod; //blitter modulo for source Breg [15:1]bltcmod; //blitter modulo for source Creg [15:1]bltdmod; //blitter modulo for destination Dreg [20:1]bltapt; //blitter pointer Areg [20:1]bltbpt; //blitter pointer Breg [20:1]bltcpt; //blitter pointer Creg [20:1]bltdpt; //blitter pointer Dreg [20:1]newpt; //new pointer reg [15:1]modulo; //modulo//--------------------------------------------------------------------------------------//writing of bltamod from busalways @(posedge clk) if(reset) bltamod[15:1]<=0; else if (regaddressin[8:1]==BLTAMOD[8:1]) bltamod[15:1]<=datain[15:1];//writing of bltbmod from busalways @(posedge clk) if(reset) bltbmod[15:1]<=0; else if (regaddressin[8:1]==BLTBMOD[8:1]) bltbmod[15:1]<=datain[15:1];//writing of bltcmod from busalways @(posedge clk) if(reset) bltcmod[15:1]<=0; else if (regaddressin[8:1]==BLTCMOD[8:1]) bltcmod[15:1]<=datain[15:1];//writing of bltdmod from busalways @(posedge clk) if(reset) bltdmod[15:1]<=0; else if (regaddressin[8:1]==BLTDMOD[8:1]) bltdmod[15:1]<=datain[15:1];//--------------------------------------------------------------------------------------//pointer bank input multiplexerwire [20:1]ptin;assign ptin[20:1]=(enable)?newpt[20:1]:{datain[4:0],datain[15:1]};//writing of blitter pointer Aalways @(posedge clk) if((enable && (chs[1:0]==2'b00)) || (regaddressin[8:1]==BLTAPTH[8:1])) bltapt[20:16]<=ptin[20:16];always @(posedge clk) if((enable && (chs[1:0]==2'b00)) || (regaddressin[8:1]==BLTAPTL[8:1])) bltapt[15:1]<=ptin[15:1];//writing of blitter pointer Balways @(posedge clk) if((enable && (chs[1:0]==2'b01)) || (regaddressin[8:1]==BLTBPTH[8:1])) bltbpt[20:16]<=ptin[20:16];always @(posedge clk) if((enable && (chs[1:0]==2'b01)) || (regaddressin[8:1]==BLTBPTL[8:1])) bltbpt[15:1]<=ptin[15:1];//writing of blitter pointer Calways @(posedge clk) if((enable && (chs[1:0]==2'b10)) || (regaddressin[8:1]==BLTCPTH[8:1])) bltcpt[20:16]<=ptin[20:16];always @(posedge clk) if((enable && (chs[1:0]==2'b10)) || (regaddressin[8:1]==BLTCPTL[8:1])) bltcpt[15:1]<=ptin[15:1];//writing of blitter pointer Dalways @(posedge clk) if((enable && (chs[1:0]==2'b11)) || (regaddressin[8:1]==BLTDPTH[8:1])) bltdpt[20:16]<=ptin[20:16];always @(posedge clk) if((enable && (chs[1:0]==2'b11)) || (regaddressin[8:1]==BLTDPTL[8:1])) bltdpt[15:1]<=ptin[15:1];//--------------------------------------------------------------------------------------//address output multiplexeralways @(chs or bltapt or bltbpt or bltcpt or bltdpt) case(chs[1:0]) 2'b00://channel A addressout[20:1]=bltapt; 2'b01://channel B addressout[20:1]=bltbpt; 2'b10://channel C addressout[20:1]=bltcpt; 2'b11://channel D addressout[20:1]=bltdpt; endcase //--------------------------------------------------------------------------------------//modulo multiplexerwire [1:0]msel;assign msel[1:0]=(modb)?{chs[1],~chs[1]}:chs[1:0];always @(msel or bltamod or bltbmod or bltcmod or bltdmod) case(msel[1:0]) 2'b00://channel A modulo[15:1]=bltamod[15:1]; 2'b01://channel B modulo[15:1]=bltbmod[15:1]; 2'b10://channel C modulo[15:1]=bltcmod[15:1]; 2'b11://channel D modulo[15:1]=bltdmod[15:1]; endcase//--------------------------------------------------------------------------------------//ALU//The ALU calculates a new address pointer based on the value of modulo//and the selected ALU operationreg [20:1]npt;//first adder/subtracteralways @(alu or addressout) case(alu[1:0]) 2'b10: npt[20:1]=addressout[20:1]+20'h1; // + 1 2'b11: npt[20:1]=addressout[20:1]-20'h1; // - 1 default: npt[20:1]=addressout[20:1]; // bypass endcase//second adder/subtracteralways @(alu or npt or modulo) case(alu[3:2]) 2'b10: newpt[20:1]=npt[20:1]+{modulo[15],modulo[15],modulo[15],modulo[15],modulo[15],modulo[15:1]}; // + modulo 2'b11: newpt[20:1]=npt[20:1]-{modulo[15],modulo[15],modulo[15],modulo[15],modulo[15],modulo[15:1]}; // - modulo default: newpt[20:1]=npt[20:1]; // bypass endcase//sign outputassign signout=newpt[15];endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -