123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854 |
- `define YES
- `include "revision.v"
- module lfsre(
- input clk,
- output reg [16:0] lfsr);
- wire d0;
- xnor(d0,lfsr[16],lfsr[13]);
- always @(posedge clk) begin
- lfsr <= {lfsr[15:0],d0};
- end
- endmodule
- module oldram256x1s(
- input d,
- input we,
- input wclk,
- input [7:0] a,
- output o);
- wire sel0 = (a[7:6] == 0);
- wire o0;
- RAM64X1S r0(.O(o0), .A0(a[0]), .A1(a[1]), .A2(a[2]), .A3(a[3]), .A4(a[4]), .A5(a[5]), .D(d), .WCLK(wclk), .WE(sel0 & we));
- wire sel1 = (a[7:6] == 1);
- wire o1;
- RAM64X1S r1(.O(o1), .A0(a[0]), .A1(a[1]), .A2(a[2]), .A3(a[3]), .A4(a[4]), .A5(a[5]), .D(d), .WCLK(wclk), .WE(sel1 & we));
- wire sel2 = (a[7:6] == 2);
- wire o2;
- RAM64X1S r2(.O(o2), .A0(a[0]), .A1(a[1]), .A2(a[2]), .A3(a[3]), .A4(a[4]), .A5(a[5]), .D(d), .WCLK(wclk), .WE(sel2 & we));
- wire sel3 = (a[7:6] == 3);
- wire o3;
- RAM64X1S r3(.O(o3), .A0(a[0]), .A1(a[1]), .A2(a[2]), .A3(a[3]), .A4(a[4]), .A5(a[5]), .D(d), .WCLK(wclk), .WE(sel3 & we));
- assign o = (a[7] == 0) ? ((a[6] == 0) ? o0 : o1) : ((a[6] == 0) ? o2 : o3);
- endmodule
- module ring64(
- input clk,
- input i,
- output o);
- wire o0, o1, o2;
- SRL16E ring0( .CLK(clk), .CE(1), .D(i), .A0(1), .A1(1), .A2(1), .A3(1), .Q(o0));
- SRL16E ring1( .CLK(clk), .CE(1), .D(o0), .A0(1), .A1(1), .A2(1), .A3(1), .Q(o1));
- SRL16E ring2( .CLK(clk), .CE(1), .D(o1), .A0(1), .A1(1), .A2(1), .A3(1), .Q(o2));
- SRL16E ring3( .CLK(clk), .CE(1), .D(o2), .A0(1), .A1(1), .A2(1), .A3(1), .Q(o));
- endmodule
- module ram256x1s(
- input d,
- input we,
- input wclk,
- input [7:0] a,
- output o);
- wire [1:0] rsel = a[7:6];
- wire [3:0] oo;
- genvar i;
- generate
- for (i = 0; i < 4; i=i+1) begin : ramx
- RAM64X1S r0(.O(oo[i]), .A0(a[0]), .A1(a[1]), .A2(a[2]), .A3(a[3]), .A4(a[4]), .A5(a[5]), .D(d), .WCLK(wclk), .WE((rsel == i) & we));
- end
- endgenerate
- assign o = oo[rsel];
- endmodule
- module ram448x1s(
- input d,
- input we,
- input wclk,
- input [8:0] a,
- output o);
- wire [2:0] rsel = a[8:6];
- wire [7:0] oo;
- genvar i;
- generate
- for (i = 0; i < 7; i=i+1) begin : ramx
- RAM64X1S r0(.O(oo[i]), .A0(a[0]), .A1(a[1]), .A2(a[2]), .A3(a[3]), .A4(a[4]), .A5(a[5]), .D(d), .WCLK(wclk), .WE((rsel == i) & we));
- end
- endgenerate
- assign o = oo[rsel];
- endmodule
- module ram400x1s(
- input d,
- input we,
- input wclk,
- input [8:0] a,
- output o);
- wire [2:0] rsel = a[8:6];
- wire [6:0] oo;
- genvar i;
- generate
- for (i = 0; i < 6; i=i+1) begin : ramx
- RAM64X1S r0(.O(oo[i]), .A0(a[0]), .A1(a[1]), .A2(a[2]), .A3(a[3]), .A4(a[4]), .A5(a[5]), .D(d), .WCLK(wclk), .WE((rsel == i) & we));
- end
- endgenerate
- RAM16X1S r6(.O(oo[6]), .A0(a[0]), .A1(a[1]), .A2(a[2]), .A3(a[3]), .D(d), .WCLK(wclk), .WE((rsel == 6) & we));
- assign o = oo[rsel];
- endmodule
- module ram256x8s(
- input [7:0] d,
- input we,
- input wclk,
- input [7:0] a,
- output [7:0] o);
- genvar i;
- generate
- for (i = 0; i < 8; i=i+1) begin : ramx
- ram256x1s ramx(
- .d(d[i]),
- .we(we),
- .wclk(wclk),
- .a(a),
- .o(o[i]));
- end
- endgenerate
- endmodule
- module ram32x8s(
- input [7:0] d,
- input we,
- input wclk,
- input [4:0] a,
- output [7:0] o);
- genvar i;
- generate
- for (i = 0; i < 8; i=i+1) begin : ramx
- RAM32X1S r0(.O(o[i]), .A0(a[0]), .A1(a[1]), .A2(a[2]), .A3(a[3]), .A4(a[4]), .D(d[i]), .WCLK(wclk), .WE(we));
- end
- endgenerate
- endmodule
- module ram64x8s(
- input [7:0] d,
- input we,
- input wclk,
- input [5:0] a,
- output [7:0] o);
- genvar i;
- generate
- for (i = 0; i < 8; i=i+1) begin : ramx
- RAM64X1S r0(.O(o[i]), .A0(a[0]), .A1(a[1]), .A2(a[2]), .A3(a[3]), .A4(a[4]), .A5(a[5]), .D(d[i]), .WCLK(wclk), .WE(we));
- end
- endgenerate
- endmodule
- module mRAM32X1D(
- input D,
- input WE,
- input WCLK,
- input A0, // port A
- input A1,
- input A2,
- input A3,
- input A4,
- input DPRA0, // port B
- input DPRA1,
- input DPRA2,
- input DPRA3,
- input DPRA4,
- output DPO, // port A out
- output SPO); // port B out
- parameter INIT = 32'b0;
- wire hDPO;
- wire lDPO;
- wire hSPO;
- wire lSPO;
- RAM16X1D
- #( .INIT(INIT[15:0]) )
- lo(
- .D(D),
- .WE(WE & !A4),
- .WCLK(WCLK),
- .A0(A0),
- .A1(A1),
- .A2(A2),
- .A3(A3),
- .DPRA0(DPRA0),
- .DPRA1(DPRA1),
- .DPRA2(DPRA2),
- .DPRA3(DPRA3),
- .DPO(lDPO),
- .SPO(lSPO));
- RAM16X1D
- #( .INIT(INIT[31:16]) )
- hi(
- .D(D),
- .WE(WE & A4),
- .WCLK(WCLK),
- .A0(A0),
- .A1(A1),
- .A2(A2),
- .A3(A3),
- .DPRA0(DPRA0),
- .DPRA1(DPRA1),
- .DPRA2(DPRA2),
- .DPRA3(DPRA3),
- .DPO(hDPO),
- .SPO(hSPO));
- assign DPO = DPRA4 ? hDPO : lDPO;
- assign SPO = A4 ? hSPO : lSPO;
- endmodule
- module mRAM64X1D(
- input D,
- input WE,
- input WCLK,
- input A0, // port A
- input A1,
- input A2,
- input A3,
- input A4,
- input A5,
- input DPRA0, // port B
- input DPRA1,
- input DPRA2,
- input DPRA3,
- input DPRA4,
- input DPRA5,
- output DPO, // port A out
- output SPO); // port B out
- parameter INIT = 64'b0;
- wire hDPO;
- wire lDPO;
- wire hSPO;
- wire lSPO;
- mRAM32X1D
- #( .INIT(INIT[31:0]) )
- lo(
- .D(D),
- .WE(WE & !A5),
- .WCLK(WCLK),
- .A0(A0),
- .A1(A1),
- .A2(A2),
- .A3(A3),
- .A4(A4),
- .DPRA0(DPRA0),
- .DPRA1(DPRA1),
- .DPRA2(DPRA2),
- .DPRA3(DPRA3),
- .DPRA4(DPRA4),
- .DPO(lDPO),
- .SPO(lSPO));
- mRAM32X1D
- #( .INIT(INIT[63:32]) )
- hi(
- .D(D),
- .WE(WE & A5),
- .WCLK(WCLK),
- .A0(A0),
- .A1(A1),
- .A2(A2),
- .A3(A3),
- .A4(A4),
- .DPRA0(DPRA0),
- .DPRA1(DPRA1),
- .DPRA2(DPRA2),
- .DPRA3(DPRA3),
- .DPRA4(DPRA4),
- .DPO(hDPO),
- .SPO(hSPO));
- assign DPO = DPRA5 ? hDPO : lDPO;
- assign SPO = A5 ? hSPO : lSPO;
- endmodule
- module mRAM128X1D(
- input D,
- input WE,
- input WCLK,
- input A0, // port A
- input A1,
- input A2,
- input A3,
- input A4,
- input A5,
- input A6,
- input DPRA0, // port B
- input DPRA1,
- input DPRA2,
- input DPRA3,
- input DPRA4,
- input DPRA5,
- input DPRA6,
- output DPO, // port A out
- output SPO); // port B out
- parameter INIT = 128'b0;
- wire hDPO;
- wire lDPO;
- wire hSPO;
- wire lSPO;
- mRAM64X1D
- #( .INIT(INIT[63:0]) )
- lo(
- .D(D),
- .WE(WE & !A6),
- .WCLK(WCLK),
- .A0(A0),
- .A1(A1),
- .A2(A2),
- .A3(A3),
- .A4(A4),
- .A5(A5),
- .DPRA0(DPRA0),
- .DPRA1(DPRA1),
- .DPRA2(DPRA2),
- .DPRA3(DPRA3),
- .DPRA4(DPRA4),
- .DPRA5(DPRA5),
- .DPO(lDPO),
- .SPO(lSPO));
- mRAM64X1D
- #( .INIT(INIT[127:64]) )
- hi(
- .D(D),
- .WE(WE & A6),
- .WCLK(WCLK),
- .A0(A0),
- .A1(A1),
- .A2(A2),
- .A3(A3),
- .A4(A4),
- .A5(A5),
- .DPRA0(DPRA0),
- .DPRA1(DPRA1),
- .DPRA2(DPRA2),
- .DPRA3(DPRA3),
- .DPRA4(DPRA4),
- .DPRA5(DPRA5),
- .DPO(hDPO),
- .SPO(hSPO));
- assign DPO = DPRA6 ? hDPO : lDPO;
- assign SPO = A6 ? hSPO : lSPO;
- endmodule
- module mRAM256X1D(
- input D,
- input WE,
- input WCLK,
- input A0, // port A
- input A1,
- input A2,
- input A3,
- input A4,
- input A5,
- input A6,
- input A7,
- input DPRA0, // port B
- input DPRA1,
- input DPRA2,
- input DPRA3,
- input DPRA4,
- input DPRA5,
- input DPRA6,
- input DPRA7,
- output DPO, // port A out
- output SPO); // port B out
- wire hDPO;
- wire lDPO;
- wire hSPO;
- wire lSPO;
- mRAM128X1D
- lo(
- .D(D),
- .WE(WE & !A7),
- .WCLK(WCLK),
- .A0(A0),
- .A1(A1),
- .A2(A2),
- .A3(A3),
- .A4(A4),
- .A5(A5),
- .A6(A6),
- .DPRA0(DPRA0),
- .DPRA1(DPRA1),
- .DPRA2(DPRA2),
- .DPRA3(DPRA3),
- .DPRA4(DPRA4),
- .DPRA5(DPRA5),
- .DPRA6(DPRA6),
- .DPO(lDPO),
- .SPO(lSPO));
- mRAM128X1D
- hi(
- .D(D),
- .WE(WE & A7),
- .WCLK(WCLK),
- .A0(A0),
- .A1(A1),
- .A2(A2),
- .A3(A3),
- .A4(A4),
- .A5(A5),
- .A6(A6),
- .DPRA0(DPRA0),
- .DPRA1(DPRA1),
- .DPRA2(DPRA2),
- .DPRA3(DPRA3),
- .DPRA4(DPRA4),
- .DPRA5(DPRA5),
- .DPRA6(DPRA6),
- .DPO(hDPO),
- .SPO(hSPO));
- assign DPO = DPRA7 ? hDPO : lDPO;
- assign SPO = A7 ? hSPO : lSPO;
- endmodule
- module ram32x8d(
- input [7:0] ad,
- input wea,
- input wclk,
- input [4:0] a,
- input [4:0] b,
- output [7:0] ao,
- output [7:0] bo
- );
- genvar i;
- generate
- for (i = 0; i < 8; i=i+1) begin : ramx
- mRAM32X1D ramx(
- .D(ad[i]),
- .WE(wea),
- .WCLK(wclk),
- .A0(a[0]),
- .A1(a[1]),
- .A2(a[2]),
- .A3(a[3]),
- .A4(a[4]),
- .DPRA0(b[0]),
- .DPRA1(b[1]),
- .DPRA2(b[2]),
- .DPRA3(b[3]),
- .DPRA4(b[4]),
- .SPO(ao[i]),
- .DPO(bo[i]));
- end
- endgenerate
- endmodule
- module ram64x8d(
- input [7:0] ad,
- input wea,
- input wclk,
- input [5:0] a,
- input [5:0] b,
- output [7:0] ao,
- output [7:0] bo
- );
- genvar i;
- generate
- for (i = 0; i < 8; i=i+1) begin : ramx
- mRAM64X1D ramx(
- .D(ad[i]),
- .WE(wea),
- .WCLK(wclk),
- .A0(a[0]),
- .A1(a[1]),
- .A2(a[2]),
- .A3(a[3]),
- .A4(a[4]),
- .A5(a[5]),
- .DPRA0(b[0]),
- .DPRA1(b[1]),
- .DPRA2(b[2]),
- .DPRA3(b[3]),
- .DPRA4(b[4]),
- .DPRA5(b[5]),
- .SPO(ao[i]),
- .DPO(bo[i]));
- end
- endgenerate
- endmodule
- // Same but latched read port, for CPU
- module ram32x8rd(
- input wclk,
- input [15:0] ad,
- input wea,
- input [4:0] a,
- input [4:0] b,
- output reg [15:0] ao,
- output reg [15:0] bo
- );
- wire [15:0] _ao;
- wire [15:0] _bo;
- always @(posedge wclk)
- begin
- ao <= _ao;
- bo <= _bo;
- end
- genvar i;
- generate
- for (i = 0; i < 16; i=i+1) begin : ramx
- mRAM32X1D ramx(
- .D(ad[i]),
- .WE(wea),
- .WCLK(wclk),
- .A0(a[0]),
- .A1(a[1]),
- .A2(a[2]),
- .A3(a[3]),
- .A4(a[4]),
- .DPRA0(b[0]),
- .DPRA1(b[1]),
- .DPRA2(b[2]),
- .DPRA3(b[3]),
- .DPRA4(b[4]),
- .SPO(_ao[i]),
- .DPO(_bo[i]));
- end
- endgenerate
- endmodule
- module ram128x8rd(
- input wclk,
- input [15:0] ad,
- input wea,
- input [6:0] a,
- input [6:0] b,
- output reg [15:0] ao,
- output reg [15:0] bo
- );
- wire [15:0] _ao;
- wire [15:0] _bo;
- always @(posedge wclk)
- begin
- ao <= _ao;
- bo <= _bo;
- end
- genvar i;
- generate
- for (i = 0; i < 8; i=i+1) begin : ramx
- mRAM128X1D ramx(
- .D(ad[i]),
- .WE(wea),
- .WCLK(wclk),
- .A0(a[0]),
- .A1(a[1]),
- .A2(a[2]),
- .A3(a[3]),
- .A4(a[4]),
- .A5(a[5]),
- .A6(a[6]),
- .DPRA0(b[0]),
- .DPRA1(b[1]),
- .DPRA2(b[2]),
- .DPRA3(b[3]),
- .DPRA4(b[4]),
- .DPRA5(b[5]),
- .DPRA6(b[6]),
- .SPO(_ao[i]),
- .DPO(_bo[i]));
- end
- endgenerate
- endmodule
- module ram256x8rd(
- input wclk,
- input [7:0] ad,
- input wea,
- input [7:0] a,
- input [7:0] b,
- output reg [7:0] ao,
- output reg [7:0] bo
- );
- wire [7:0] _ao;
- wire [7:0] _bo;
- always @(posedge wclk)
- begin
- ao <= _ao;
- bo <= _bo;
- end
- genvar i;
- generate
- for (i = 0; i < 8; i=i+1) begin : ramx
- mRAM256X1D ramx(
- .D(ad[i]),
- .WE(wea),
- .WCLK(wclk),
- .A0(a[0]),
- .A1(a[1]),
- .A2(a[2]),
- .A3(a[3]),
- .A4(a[4]),
- .A5(a[5]),
- .A6(a[6]),
- .A7(a[7]),
- .DPRA0(b[0]),
- .DPRA1(b[1]),
- .DPRA2(b[2]),
- .DPRA3(b[3]),
- .DPRA4(b[4]),
- .DPRA5(b[5]),
- .DPRA6(b[6]),
- .DPRA7(b[7]),
- .SPO(_ao[i]),
- .DPO(_bo[i]));
- end
- endgenerate
- endmodule
- module ram448x9s(
- input [8:0] d,
- input we,
- input wclk,
- input [8:0] a,
- output [8:0] o);
- genvar i;
- generate
- for (i = 0; i < 9; i=i+1) begin : ramx
- ram448x1s ramx(
- .d(d[i]),
- .we(we),
- .wclk(wclk),
- .a(a),
- .o(o[i]));
- end
- endgenerate
- endmodule
- module ram400x9s(
- input [8:0] d,
- input we,
- input wclk,
- input [8:0] a,
- output [8:0] o);
- genvar i;
- generate
- for (i = 0; i < 9; i=i+1) begin : ramx
- ram400x1s ramx(
- .d(d[i]),
- .we(we),
- .wclk(wclk),
- .a(a),
- .o(o[i]));
- end
- endgenerate
- endmodule
- module ram400x8s(
- input [7:0] d,
- input we,
- input wclk,
- input [8:0] a,
- output [7:0] o);
- genvar i;
- generate
- for (i = 0; i < 8; i=i+1) begin : ramx
- ram400x1s ramx(
- .d(d[i]),
- .we(we),
- .wclk(wclk),
- .a(a),
- .o(o[i]));
- end
- endgenerate
- endmodule
- module ram400x7s(
- input [6:0] d,
- input we,
- input wclk,
- input [8:0] a,
- output [6:0] o);
- genvar i;
- generate
- for (i = 0; i < 7; i=i+1) begin : ramx
- ram400x1s ramx(
- .d(d[i]),
- .we(we),
- .wclk(wclk),
- .a(a),
- .o(o[i]));
- end
- endgenerate
- endmodule
- // SPI can be many things, so to be clear, this implementation:
- // MSB first
- // CPOL 0, leading edge when SCK rises
- // CPHA 0, sample on leading, setup on trailing
- module SPI_memory(
- input clk,
- input SCK, input MOSI, output MISO, input SSEL,
- output wire [15:0] raddr, // read address
- output reg [15:0] waddr, // write address
- output reg [7:0] data_w,
- input [7:0] data_r,
- output reg we,
- output reg re,
- output mem_clk
- );
- reg [15:0] paddr;
- reg [4:0] count;
- wire [4:0] _count = (count == 23) ? 16 : (count + 1);
- assign mem_clk = clk;
- // sync SCK to the FPGA clock using a 3-bits shift register
- reg [2:0] SCKr; always @(posedge clk) SCKr <= {SCKr[1:0], SCK};
- wire SCK_risingedge = (SCKr[2:1]==2'b01); // now we can detect SCK rising edges
- wire SCK_fallingedge = (SCKr[2:1]==2'b10); // and falling edges
- // same thing for SSEL
- reg [2:0] SSELr; always @(posedge clk) SSELr <= {SSELr[1:0], SSEL};
- wire SSEL_active = ~SSELr[1]; // SSEL is active low
- wire SSEL_startmessage = (SSELr[2:1]==2'b10); // message starts at falling edge
- wire SSEL_endmessage = (SSELr[2:1]==2'b01); // message stops at rising edge
- // and for MOSI
- reg [1:0] MOSIr; always @(posedge clk) MOSIr <= {MOSIr[0], MOSI};
- wire MOSI_data = MOSIr[1];
- assign raddr = (count[4] == 0) ? {paddr[14:0], MOSI} : paddr;
- always @(posedge clk)
- begin
- if (~SSEL_active) begin
- count <= 0;
- re <= 0;
- we <= 0;
- end else
- if (SCK_risingedge) begin
- if (count[4] == 0) begin
- we <= 0;
- paddr <= raddr;
- re <= (count == 15);
- end else begin
- data_w <= {data_w[6:0], MOSI_data};
- if (count == 23) begin
- we <= paddr[15];
- re <= !paddr[15];
- waddr <= paddr;
- paddr <= paddr + 1;
- end else begin
- we <= 0;
- re <= 0;
- end
- end
- count <= _count;
- end
- if (SCK_fallingedge) begin
- re <= 0;
- we <= 0;
- end
- end
- reg readbit;
- always @*
- begin
- case (count[2:0])
- 3'd0: readbit <= data_r[7];
- 3'd1: readbit <= data_r[6];
- 3'd2: readbit <= data_r[5];
- 3'd3: readbit <= data_r[4];
- 3'd4: readbit <= data_r[3];
- 3'd5: readbit <= data_r[2];
- 3'd6: readbit <= data_r[1];
- 3'd7: readbit <= data_r[0];
- endcase
- end
- assign MISO = readbit;
- endmodule
- // This is a Delta-Sigma Digital to Analog Converter
- `define MSBI 12 // Most significant Bit of DAC input, 12 means 13-bit
- module dac(DACout, DACin, Clk, Reset);
- output DACout; // This is the average output that feeds low pass filter
- reg DACout; // for optimum performance, ensure that this ff is in IOB
- input [`MSBI:0] DACin; // DAC input (excess 2**MSBI)
- input Clk;
- input Reset;
- reg [`MSBI+2:0] DeltaAdder; // Output of Delta adder
- reg [`MSBI+2:0] SigmaAdder; // Output of Sigma adder
- reg [`MSBI+2:0] SigmaLatch; // Latches output of Sigma adder
- reg [`MSBI+2:0] DeltaB; // B input of Delta adder
- always @(SigmaLatch) DeltaB = {SigmaLatch[`MSBI+2], SigmaLatch[`MSBI+2]} << (`MSBI+1);
- always @(DACin or DeltaB) DeltaAdder = DACin + DeltaB;
- always @(DeltaAdder or SigmaLatch) SigmaAdder = DeltaAdder + SigmaLatch;
- always @(posedge Clk or posedge Reset)
- begin
- if (Reset) begin
- SigmaLatch <= #1 1'b1 << (`MSBI+1);
- DACout <= #1 1'b0;
- end else begin
- SigmaLatch <= #1 SigmaAdder;
- DACout <= #1 SigmaLatch[`MSBI+2];
- end
- end
- endmodule
- module top(
- input clka,
- output [2:0] vga_red,
- output [2:0] vga_green,
- output [2:0] vga_blue,
- output vga_hsync_n,
- output vga_vsync_n,
- input SCK, // arduino 13
- input MOSI, // arduino 11
- inout MISO, // arduino 12
- input SSEL, // arduino 9
- inout AUX, // arduino 2
- output AUDIOL,
- output AUDIOR,
- output flashMOSI,
- input flashMISO,
- output flashSCK,
- output flashSSEL
- );
- wire mem_clk;
- wire [7:0] host_mem_data_wr;
- reg [7:0] mem_data_rd;
- reg [7:0] latched_mem_data_rd;
- wire [14:0] mem_w_addr; // Combined write address
- wire [14:0] mem_r_addr; // Combined read address
- wire [14:0] host_mem_w_addr;
- wire [14:0] host_mem_r_addr;
- wire host_mem_wr;
- wire mem_rd;
- wire vga_clk;
- ck_div #(.DIV_BY(2), .MULT_BY(4)) vga_ck_gen(.ck_in(clka), .ck_out(vga_clk));
- wire [15:0] j1_insn;
- wire [12:0] j1_insn_addr;
- wire [15:0] j1_mem_addr;
- wire [15:0] j1_mem_dout;
- wire j1_mem_wr;
- wire [7:0] j1insnl_read;
- wire [7:0] j1insnh_read;
- wire [7:0] mem_data_rd0;
- wire [7:0] mem_data_rd1;
- wire [7:0] mem_data_rd2;
- wire [7:0] mem_data_rd3;
- wire [7:0] mem_data_rd4;
- wire [7:0] mem_data_rd5;
- wire gdMISO;
- always @(posedge vga_clk)
- if (mem_rd)
- latched_mem_data_rd <= mem_data_rd;
- SPI_memory spi1(
- .clk(vga_clk),
- .SCK(SCK), .MOSI(MOSI), .MISO(gdMISO), .SSEL(SSEL),
- .raddr(host_mem_r_addr),
- .waddr(host_mem_w_addr),
- .data_w(host_mem_data_wr),
- .data_r(latched_mem_data_rd),
- .we(host_mem_wr),
- .re(mem_rd),
- .mem_clk(mem_clk));
- wire host_busy = host_mem_wr | mem_rd;
- wire mem_wr = host_busy ? host_mem_wr : j1_mem_wr;
- wire [7:0] mem_data_wr = host_busy ? host_mem_data_wr : j1_mem_dout;
- wire [14:0] mem_addr = host_busy ? (host_mem_wr ? host_mem_w_addr : host_mem_r_addr) : j1_mem_addr;
- assign mem_w_addr = host_busy ? host_mem_w_addr : j1_mem_addr;
- assign mem_r_addr = host_busy ? host_mem_r_addr : j1_mem_addr;
- reg signed [15:0] sample_l;
- reg signed [15:0] sample_r;
- reg [6:0] modvoice = 64;
- reg [14:0] bg_color;
- reg [7:0] pin2mode = 0;
- wire pin2f = (pin2mode == 8'h46);
- wire pin2j = (pin2mode == 8'h4A);
- wire flashsel = (AUX == 0) & pin2f;
- assign MISO = SSEL ? (flashsel ? flashMISO : 1'bz) : gdMISO;
- // assign MISO = SSEL ? (1'bz ) : gdMISO;
- // PULLUP MISO_pullup(.O(MISO));
- // IOBUF MISO_iobuf(
- // .I(gdMISO),
- // .IO(MISO),
- // .T(SSEL));
- // user-visible registers
- reg [7:0] frames;
- reg [8:0] scrollx;
- reg [8:0] scrolly;
- reg jkmode;
- wire [7:0] palette16l_read;
- wire [7:0] palette16h_read;
- wire [4:0] palette16_addr;
- wire [15:0] palette16_data;
- // 11'b00001xxxxx0: low
- wire palette16_wr = (mem_wr & (mem_w_addr[14:11] == 5) & (mem_w_addr[10:6] == 1));
- ram32x8d palette16l(
- .a(mem_addr[5:1]),
- .wclk(mem_clk),
- .wea((mem_w_addr[0] == 0) & palette16_wr),
- .ad(mem_data_wr),
- .ao(palette16l_read),
- .b(palette16_addr),
- .bo(palette16_data[7:0]));
- ram32x8d palette16h(
- .a(mem_addr[5:1]),
- .wclk(mem_clk),
- .wea((mem_w_addr[0] == 1) & palette16_wr),
- .ad(mem_data_wr),
- .ao(palette16h_read),
- .b(palette16_addr),
- .bo(palette16_data[15:8]));
- wire [7:0] palette4l_read;
- wire [7:0] palette4h_read;
- wire [4:0] palette4_addr;
- wire [15:0] palette4_data;
- // 11'b00010xxxxx0: low
- wire palette4_wr = (mem_wr & (mem_w_addr[14:11] == 5) & (mem_w_addr[10:6] == 2));
- ram32x8d palette4l(
- .a(mem_addr[5:1]),
- .wclk(mem_clk),
- .wea((mem_w_addr[0] == 0) & palette4_wr),
- .ad(mem_data_wr),
- .ao(palette4l_read),
- .b(palette4_addr),
- .bo(palette4_data[7:0]));
- ram32x8d palette4h(
- .a(mem_addr[5:1]),
- .wclk(mem_clk),
- .wea((mem_w_addr[0] == 1) & palette4_wr),
- .ad(mem_data_wr),
- .ao(palette4h_read),
- .b(palette4_addr),
- .bo(palette4_data[15:8]));
- // Generate CounterX and CounterY
- // A single line is 1040 clocks. Line pair is 2080 clocks.
- reg [10:0] CounterX;
- reg [9:0] CounterY;
- wire CounterXmaxed = (CounterX==1040);
- always @(posedge vga_clk)
- if(CounterXmaxed)
- CounterX <= 0;
- else
- CounterX <= CounterX + 1;
- wire lastline = (CounterY == 665);
- wire [9:0] _CounterY = lastline ? 0 : (CounterY + 1);
- always @(posedge vga_clk)
- if (CounterXmaxed) begin
- CounterY <= _CounterY;
- if (lastline)
- frames <= frames + 1;
- end
- reg [12:0] comp_workcnt; // Compositor work address
- reg comp_workcnt_lt_400;
- always @(posedge vga_clk)
- begin
- if (CounterXmaxed & (CounterY[0] == 0)) begin
- comp_workcnt <= 0;
- comp_workcnt_lt_400 <= 1;
- end else begin
- comp_workcnt <= comp_workcnt + 1;
- if (comp_workcnt == 399)
- comp_workcnt_lt_400 <= 0;
- end
- end
- // horizontal
- // Front porch 56
- // Sync 120
- // Back porch 64
- // vertical
- // Front porch 37 lines
- // Sync 6
- // Back porch 23
- // `define HSTART (53 + 120 + 61)
- `define HSTART 0
- reg vga_HS, vga_VS, vga_active;
- always @(posedge vga_clk)
- begin
- vga_HS <= ((800 + 61) <= CounterX) & (CounterX < (800 + 61 + 120));
- vga_VS <= (35 <= CounterY) & (CounterY < (35 + 6));
- vga_active = ((`HSTART + 1) <= CounterX) & (CounterX < (`HSTART + 1 + 800)) & ((35 + 6 + 21) < CounterY) & (CounterY <= (35 + 6 + 21 + 600));
- end
- wire [10:0] xx = (CounterX - `HSTART);
- wire [10:0] xx_1 = (CounterX - `HSTART + 1);
- wire [10:0] yy = (CounterY + 2 - (35 + 6 + 21 + 1)); // yy range 0-665
- wire [10:0] column = comp_workcnt + scrollx;
- wire [10:0] row = yy[10:1] + scrolly;
- wire [7:0] glyph;
- wire [11:0] picaddr = {row[8:3], column[8:3]};
- wire en_pic = (mem_addr[14:12] == 0);
- RAM_PICTURE picture(
- .dia(0),
- .doa(glyph),
- .wea(0),
- .ena(1),
- .clka(vga_clk),
- .addra(picaddr),
- .dib(mem_data_wr),
- .dob(mem_data_rd0),
- .web(mem_wr),
- .enb(en_pic),
- .clkb(mem_clk),
- .addrb(mem_addr)
- );
- reg [2:0] _column;
- always @(posedge vga_clk)
- _column = column;
- wire en_chr = (mem_addr[14:12] == 1);
- wire [1:0] charout;
- RAM_CHR chars(
- .dia(0), .doa(charout), .wea(0), .ena(1), .clka(vga_clk), .addra({glyph, row[2:0], _column[2], ~_column[1:0]}),
- .dib(mem_data_wr), .dob(mem_data_rd1), .web(mem_wr), .enb(en_chr), .clkb(mem_clk), .addrb(mem_addr));
- reg [7:0] _glyph;
- always @(posedge vga_clk)
- _glyph <= glyph;
- wire [4:0] bg_r;
- wire [4:0] bg_g;
- wire [4:0] bg_b;
- wire en_pal = (mem_addr[14:11] == 4'b0100);
- wire [15:0] char_matte;
- RAM_PAL charpalette(
- .DIA(mem_data_wr),
- .WEA(mem_wr),
- .ENA(en_pal),
- .CLKA(mem_clk),
- .ADDRA(mem_addr),
- .DOA(mem_data_rd2),
- .SSRA(0),
- .DIB(0),
- .WEB(0),
- .ENB(1),
- .CLKB(vga_clk),
- .ADDRB({_glyph, charout}),
- .DOB(char_matte),
- .SSRB(0)
- );
- // wire [4:0] bg_mix_r = bg_color[14:10] + char_matte[14:10];
- // wire [4:0] bg_mix_g = bg_color[9:5] + char_matte[9:5];
- // wire [4:0] bg_mix_b = bg_color[4:0] + char_matte[4:0];
- // wire [14:0] char_final = char_matte[15] ? {bg_mix_r, bg_mix_g, bg_mix_b} : char_matte[14:0];
- wire [14:0] char_final = char_matte[15] ? bg_color : char_matte[14:0];
- reg [7:0] mem_data_rd_reg;
- // Collision detection RAM is readable during vblank
- // writes coll_d to coll_w_addr during render
- wire coll_rd = (yy >= 600); // 1 means reading
- wire [7:0] coll_d;
- wire [7:0] coll_w_addr;
- wire coll_we;
- wire [7:0] coll_addr = coll_rd ? mem_r_addr[7:0] : coll_w_addr;
- wire [7:0] coll_o;
- ram256x8s coll(.o(coll_o), .a(coll_addr), .d(coll_d), .wclk(vga_clk), .we(~coll_rd & coll_we));
- wire [7:0] screenshot_rd;
- wire [7:0] voicefl_read;
- wire [7:0] voicefh_read;
- wire [7:0] voicela_read;
- wire [7:0] voicera_read;
- reg j1_reset = 0;
- reg spr_disable = 0;
- reg spr_page = 0;
- // Screenshot notes
- // three states, controlled by screenshot_primed, _done:
- // primed done composer.A
- // 0 0 screenshot disabled write(comp_write)
- // 1 0 screenshot primed write(comp_write)
- // 1 1 screenshot done read(mem_r_addr[9:1])
- reg [8:0] screenshot_yy; // 9 bits, 0-400
- reg screenshot_primed;
- reg screenshot_done;
- wire screenshot_reset;
- wire [8:0] public_yy = coll_rd ? 300 : yy[10:1];
- always @(posedge vga_clk)
- begin
- if (screenshot_reset)
- screenshot_done <= 0;
- else if (CounterXmaxed & screenshot_primed & !screenshot_done & (public_yy == screenshot_yy)) begin
- screenshot_done <= 1;
- end
- end
- always @(mem_data_rd_reg)
- begin
- casex (mem_r_addr[10:0])
- 11'h000: mem_data_rd_reg <= 8'h6d; // Gameduino ident
- 11'h001: mem_data_rd_reg <= `REVISION;
- 11'h002: mem_data_rd_reg <= frames;
- 11'h003: mem_data_rd_reg <= coll_rd; // called VBLANK, but really "is coll readable?"
- 11'h004: mem_data_rd_reg <= scrollx[7:0];
- 11'h005: mem_data_rd_reg <= scrollx[8];
- 11'h006: mem_data_rd_reg <= scrolly[7:0];
- 11'h007: mem_data_rd_reg <= scrolly[8];
- 11'h008: mem_data_rd_reg <= jkmode;
- 11'h009: mem_data_rd_reg <= j1_reset;
- 11'h00a: mem_data_rd_reg <= spr_disable;
- 11'h00b: mem_data_rd_reg <= spr_page;
- 11'h00c: mem_data_rd_reg <= pin2mode;
- 11'h00e: mem_data_rd_reg <= bg_color[7:0];
- 11'h00f: mem_data_rd_reg <= bg_color[14:8];
- 11'h010: mem_data_rd_reg <= sample_l[7:0];
- 11'h011: mem_data_rd_reg <= sample_l[15:8];
- 11'h012: mem_data_rd_reg <= sample_r[7:0];
- 11'h013: mem_data_rd_reg <= sample_r[15:8];
- 11'h014: mem_data_rd_reg <= modvoice;
- 11'h01e: mem_data_rd_reg <= public_yy[7:0];
- 11'h01f: mem_data_rd_reg <= {screenshot_done, 6'b000000, public_yy[8]};
- 11'b00001xxxxx0: mem_data_rd_reg <= palette16l_read;
- 11'b00001xxxxx1: mem_data_rd_reg <= palette16h_read;
- 11'b00010xxxxx0: mem_data_rd_reg <= palette4l_read;
- 11'b00010xxxxx1: mem_data_rd_reg <= palette4h_read;
- 11'b001xxxxxxxx:
- mem_data_rd_reg <= coll_rd ? coll_o : 8'hff;
- 11'b010xxxxxx00: mem_data_rd_reg <= voicefl_read;
- 11'b010xxxxxx01: mem_data_rd_reg <= voicefh_read;
- 11'b010xxxxxx10: mem_data_rd_reg <= voicela_read;
- 11'b010xxxxxx11: mem_data_rd_reg <= voicera_read;
- 11'b011xxxxxxx0: mem_data_rd_reg <= j1insnl_read;
- 11'b011xxxxxxx1: mem_data_rd_reg <= j1insnh_read;
- 11'b1xxxxxxxxxx: mem_data_rd_reg <= screenshot_rd;
- // default: mem_data_rd_reg <= 0;
- endcase
- end
- reg [17:0] soundcounter;
- always @(posedge vga_clk)
- soundcounter <= soundcounter + 1;
- wire [5:0] viN = soundcounter + 1;
- wire [5:0] vi = soundcounter;
- wire voice_wr = mem_wr & (mem_w_addr[14:11] == 5) & (mem_w_addr[10:8] == 3'b010);
- wire voicefl_wr = voice_wr & (mem_w_addr[1:0] == 2'b00);
- wire voicefh_wr = voice_wr & (mem_w_addr[1:0] == 2'b01);
- wire voicela_wr = voice_wr & (mem_w_addr[1:0] == 2'b10);
- wire voicera_wr = voice_wr & (mem_w_addr[1:0] == 2'b11);
- wire [7:0] voicela_data;
- wire [7:0] voicera_data;
- wire [7:0] voicefl_data;
- wire [7:0] voicefh_data;
- wire [5:0] voice_addr = mem_addr[7:2];
- ram64x8d voicefl(
- .a(voice_addr),
- .wclk(mem_clk),
- .wea(voicefl_wr),
- .ad(mem_data_wr),
- .ao(voicefl_read),
- .b(viN),
- .bo(voicefl_data));
- ram64x8d voicefh(
- .a(voice_addr),
- .wclk(mem_clk),
- .wea(voicefh_wr),
- .ad(mem_data_wr),
- .ao(voicefh_read),
- .b(viN),
- .bo(voicefh_data));
- ram64x8d voicela(
- .a(voice_addr),
- .wclk(mem_clk),
- .wea(voicela_wr),
- .ad(mem_data_wr),
- .ao(voicela_read),
- .b(viN),
- .bo(voicela_data));
- ram64x8d voicera(
- .a(voice_addr),
- .wclk(mem_clk),
- .wea(voicera_wr),
- .ad(mem_data_wr),
- .ao(voicera_read),
- .b(viN),
- .bo(voicera_data));
- assign screenshot_reset = mem_wr & (mem_w_addr[14:11] == 5) & (mem_w_addr[10:0] == 11'h01f);
- always @(posedge mem_clk)
- begin
- if (mem_wr & mem_w_addr[14:11] == 5)
- casex (mem_w_addr[10:0])
- 11'h004: scrollx[7:0] <= mem_data_wr;
- 11'h005: scrollx[8] <= mem_data_wr;
- 11'h006: scrolly[7:0] <= mem_data_wr;
- 11'h007: scrolly[8] <= mem_data_wr;
- 11'h008: jkmode <= mem_data_wr;
- 11'h009: j1_reset <= mem_data_wr;
- 11'h00a: spr_disable <= mem_data_wr;
- 11'h00b: spr_page <= mem_data_wr;
- 11'h00c: pin2mode <= mem_data_wr;
- 11'h00e: bg_color[7:0] <= mem_data_wr;
- 11'h00f: bg_color[14:8] <= mem_data_wr;
- 11'h010: sample_l[7:0] <= mem_data_wr;
- 11'h011: sample_l[15:8] <= mem_data_wr;
- 11'h012: sample_r[7:0] <= mem_data_wr;
- 11'h013: sample_r[15:8] <= mem_data_wr;
- 11'h014: modvoice <= mem_data_wr;
- 11'h01e: screenshot_yy[7:0] <= mem_data_wr;
- 11'h01f: begin screenshot_primed <= mem_data_wr[7];
- screenshot_yy[8] <= mem_data_wr; end
- endcase
- end
- /*
- 0000-0fff Picture
- 1000-1fff Character
- 2000-27ff Character
- 2800-2fff (Unused)
- 3000-37ff Sprite values
- 3800-3fff Sprite palette
- 4000-7fff Sprite image
- */
- always @*
- begin
- case (mem_addr[14:11]) // 2K pages
- 4'h0: mem_data_rd <= mem_data_rd0; // pic
- 4'h1: mem_data_rd <= mem_data_rd0;
- 4'h2: mem_data_rd <= mem_data_rd1; // chr
- 4'h3: mem_data_rd <= mem_data_rd1;
- 4'h4: mem_data_rd <= mem_data_rd2; // pal
- 4'h5: mem_data_rd <= mem_data_rd_reg;
- 4'h6: mem_data_rd <= mem_data_rd3; // sprval
- 4'h7: mem_data_rd <= mem_data_rd4; // sprpal
- 4'h8: mem_data_rd <= mem_data_rd5; // sprimg
- 4'h9: mem_data_rd <= mem_data_rd5; // sprimg
- 4'ha: mem_data_rd <= mem_data_rd5; // sprimg
- 4'hb: mem_data_rd <= mem_data_rd5; // sprimg
- 4'hc: mem_data_rd <= mem_data_rd5; // sprimg
- 4'hd: mem_data_rd <= mem_data_rd5; // sprimg
- 4'he: mem_data_rd <= mem_data_rd5; // sprimg
- 4'hf: mem_data_rd <= mem_data_rd5; // sprimg
- default: mem_data_rd <= 8'h97;
- endcase
- end
- // Sprite memory
- // Stage 1: scan for valid
- reg [8:0] s1_count;
- wire en_sprval = (mem_addr[14:11] == 4'b0110);
- wire [31:0] sprval_data;
- RAM_SPRVAL sprval(
- .DIA(mem_data_wr),
- .WEA(mem_wr),
- .ENA(en_sprval),
- .CLKA(mem_clk),
- .ADDRA(mem_addr),
- .DOA(mem_data_rd3),
- .SSRA(0),
- .DIB(0),
- .WEB(0),
- .ENB(1),
- .CLKB(vga_clk),
- .ADDRB({spr_page, s1_count[7:0]}),
- .DOB(sprval_data),
- .SSRB(0)
- );
- wire [9:0] sprpal_addr;
- wire [15:0] sprpal_data;
- wire en_sprpal = (mem_addr[14:11] == 4'b0111);
- RAM_SPRPAL sprpal(
- .DIA(mem_data_wr),
- .WEA(mem_wr),
- .ENA(en_sprpal),
- .CLKA(mem_clk),
- .ADDRA(mem_addr),
- .DOA(mem_data_rd4),
- .SSRA(0),
- .DIB(0),
- .WEB(0),
- .ENB(1),
- .CLKB(vga_clk),
- .ADDRB(sprpal_addr),
- .DOB(sprpal_data),
- .SSRB(0)
- );
- wire [13:0] sprimg_readaddr;
- wire [7:0] sprimg_data;
- wire en_sprimg = (mem_addr[14] == 1'b1);
- // ram16K_8_8 sprimg(
- RAM_SPRIMG sprimg(
- .dia(mem_data_wr),
- .wea(mem_wr),
- .ena(en_sprimg),
- .clka(mem_clk),
- .addra(mem_addr),
- .doa(mem_data_rd5),
- .ssra(0),
- .dib(0),
- .web(0),
- .enb(1),
- .clkb(vga_clk),
- .addrb(sprimg_readaddr),
- .dob(sprimg_data),
- .ssrb(0)
- );
- // Stage 1: scan for valid
- reg s1_consider; // Consider the sprval on the next cycle
- wire s2_room; // Does s2 fifo have room for one entry?
- always @(posedge vga_clk)
- begin
- if (comp_workcnt == 0) begin
- s1_count <= 0;
- s1_consider <= 0;
- end else
- if ((s1_count <= 255) & s2_room) begin
- s1_count <= s1_count + 1;
- s1_consider <= 1;
- end else begin
- s1_consider <= 0;
- end
- end
- wire [31:0] s1_out = sprval_data;
- wire [8:0] s1_y_offset = yy[9:1] - s1_out[24:16];
- wire s1_visible = (spr_disable == 0) & (s1_y_offset[8:4] == 0);
- wire s1_valid = s1_consider & s1_visible;
- reg [8:0] s1_id;
- always @(posedge vga_clk)
- s1_id <= s1_count;
- // Stage 2: fifo
- wire [4:0] s2_fullness;
- wire s3_read;
- wire [40:0] s2_out;
- fifo #(40) s2(.clk(vga_clk),
- .wr(s1_valid), .datain({s1_id, s1_out}),
- .rd(s3_read), .dataout(s2_out),
- .fullness(s2_fullness));
- assign s2_room = (s2_fullness < 14);
- wire s2_valid = s2_fullness != 0;
- // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- // [ image ] [ y ] [PAL] [ ROT ] [ x ]
- /* Stage 3: read sprimg
- consume s2_out on last cycle
- out: s3_valid, s3_pal, s3_out, s3_compaddr
- */
- reg [4:0] s3_state;
- reg [3:0] s3_pal;
- reg [31:0] s3_in;
- assign s3_read = (s3_state == 15);
- always @(posedge vga_clk)
- begin
- if (comp_workcnt < 403)
- s3_state <= 16;
- else if (s3_state == 16) begin
- if (s2_valid) begin
- s3_state <= 0;
- s3_in <= s2_out;
- end
- end else begin
- s3_state <= s3_state + 1;
- end
- s3_pal <= s2_out[15:12];
- end
- wire [3:0] s3_yoffset = yy[4:1] - s2_out[19:16];
- wire [3:0] s3_prev_state = (s3_state == 16) ? 0 : (s3_state + 1);
- wire [3:0] readx = (s2_out[9] ? s3_yoffset : s3_prev_state) ^ {4{s2_out[10]}};
- wire [3:0] ready = (s2_out[9] ? s3_prev_state : s3_yoffset) ^ {4{s2_out[11]}};
- assign sprimg_readaddr = {s2_out[30:25], ready, readx};
- wire [7:0] s3_out = sprimg_data;
- wire [8:0] s3_compaddr = s2_out[8:0] + s3_state;
- wire s3_valid = (s3_state != 16) & (s3_compaddr < 400);
- reg [8:0] s3_id;
- reg s3_jk;
- always @(posedge vga_clk)
- begin
- s3_id <= s2_out[40:32];
- s3_jk <= s2_out[31];
- end
- /* Stage 4: read sprpal
- out: s4_valid, s4_out, s4_compaddr
- */
- reg [15:0] sprpal4;
- reg [15:0] sprpal16;
- assign sprpal_addr = {s3_pal[1:0], s3_out};
- reg [8:0] s4_compaddr;
- reg s4_valid;
- reg [8:0] s4_id;
- reg s4_jk;
- wire [3:0] subfield4 = s3_pal[1] ? s3_out[7:4] : s3_out[3:0];
- wire [1:0] subfield2 = s3_pal[2] ? (s3_pal[1] ? s3_out[7:6] : s3_out[5:4]) : (s3_pal[1] ? s3_out[3:2] : s3_out[1:0]);
- assign palette4_addr = {s3_pal[0], subfield2};
- assign palette16_addr = {s3_pal[0], subfield4};
- always @(posedge vga_clk)
- begin
- s4_compaddr <= s3_compaddr;
- s4_valid <= s3_valid;
- s4_id <= s3_id;
- s4_jk <= s3_jk;
- sprpal4 <= palette4_data;
- sprpal16 <= palette16_data;
- end
- wire [15:0] s4_out = s3_pal[3] ? sprpal4 : ((s3_pal[3:2] == 0) ? sprpal_data : sprpal16);
- // Common signals for collision and composite
- wire sprite_write = s4_valid & !s4_out[15]; // transparency
- // Collision detect
- // Have 400x9 occupancy buffer. If NEW overwrites a fragment OLD
- // (and their groups differ) write OLD to coll[NEW].
- // Reset coll to FF at start of frame.
- // Reset occ to FF at start of line, since sprites drawn 0->ff,
- // ff is impossible and means empty.
- wire coll_scrub = (yy == 0) & (comp_workcnt < 256);
- wire [8:0] occ_addr = comp_workcnt_lt_400 ? comp_workcnt : s4_compaddr;
- wire [8:0] occ_d = comp_workcnt_lt_400 ? 9'hff : {s4_jk, s4_id[7:0]};
- wire [8:0] oldocc;
- wire occ_w = comp_workcnt_lt_400 | sprite_write;
- ram400x9s occ(.o(oldocc), .a(occ_addr), .d(occ_d), .wclk(vga_clk), .we(occ_w));
- assign coll_d = coll_scrub ? 8'hff : oldocc[7:0];
- assign coll_w_addr = coll_scrub ? comp_workcnt : s4_id[7:0];
- // old contents 0xff, never write
- // jkmode=1 and JK's differ, allow write
- wire overwriting = (oldocc[7:0] != 8'hff);
- wire jkpass = (jkmode == 0) | (oldocc[8] ^ s4_jk);
- assign coll_we = coll_scrub | ((403 <= comp_workcnt) & sprite_write & overwriting & jkpass);
- // Composite
- wire comp_read = yy[1]; // which block is reading
- wire [8:0] comp_scanout = xx[9:1];
- wire [8:0] comp_write = (comp_workcnt < 403) ? (comp_workcnt - 3) : s4_compaddr;
- wire comp_part1 = (3 <= comp_workcnt) & (comp_workcnt < 403);
- `ifdef NELLY
- wire [14:0] comp_out0;
- wire [14:0] comp_out1;
- RAMB16_S18_S18 composer(
- .DIPA(0),
- .DIA(comp_part1 ? char_final : s4_out),
- .WEA(comp_read == 1 & (comp_part1 | sprite_write)),
- .ENA(1),
- .CLKA(vga_clk),
- .ADDRA({1'b0, (comp_read == 0) ? comp_scanout : comp_write[8:0]}),
- .DOA(comp_out0),
- .SSRA(0),
- .DIPB(0),
- .DIB(comp_part1 ? char_final : s4_out),
- .WEB(comp_read == 0 & (comp_part1 | sprite_write)),
- .ENB(1),
- .CLKB(vga_clk),
- .ADDRB({1'b1, (comp_read == 1) ? comp_scanout : comp_write[8:0]}),
- .DOB(comp_out1),
- .SSRB(0)
- );
- wire [14:0] comp_out = comp_read ? comp_out1 : comp_out0;
- `else
- wire ss = screenshot_primed & screenshot_done; // screenshot readout mode
- wire [15:0] screenshot_rdHL;
- wire [14:0] comp_out;
- // Port A is the write, or read when screenshot is ready
- // Port B is scanout
- RAMB16_S18_S18
- composer(
- .DIPA(0),
- .DIA(comp_part1 ? char_final : s4_out),
- .WEA(!ss & (comp_part1 | sprite_write)),
- .ENA(1),
- .CLKA(vga_clk),
- .ADDRA(ss ? {screenshot_yy[0], mem_r_addr[9:1]} : {comp_read, comp_write[8:0]}),
- .DOA(screenshot_rdHL),
- .SSRA(0),
- .DIPB(0),
- .DIB(0),
- .WEB(0),
- .ENB(1),
- .CLKB(vga_clk),
- .ADDRB({!comp_read, comp_scanout}),
- .DOB(comp_out),
- .SSRB(0)
- );
- assign screenshot_rd = mem_r_addr[0] ? screenshot_rdHL[15:8] : screenshot_rdHL[7:0];
- `endif
- assign {bg_r,bg_g,bg_b} = comp_out;
- // Figure out from above signals when composite completes
- // by detecting pipeline idle
- wire composite_complete = (comp_workcnt > 403) & (s1_count == 256) & !s1_consider & !s2_valid & (s3_state == 16) & !s4_valid;
- // Signal generation
- wire [16:0] lfsr;
- lfsre lfsr0(
- .clk(vga_clk),
- .lfsr(lfsr));
- wire [1:0] dith;
- // 0 2
- // 3 1
- assign dith = {(xx[0]^yy[0]), yy[0]};
- wire [5:0] dith_r = (bg_r + dith);
- wire [5:0] dith_g = (bg_g + dith);
- wire [5:0] dith_b = (bg_b + dith);
- wire [2:0] f_r = {3{dith_r[5]}} | dith_r[4:2];
- wire [2:0] f_g = {3{dith_g[5]}} | dith_g[4:2];
- wire [2:0] f_b = {3{dith_b[5]}} | dith_b[4:2];
- wire [2:0] ccc = { charout[1], charout[0], charout[0] };
- assign vga_red = vga_active ? f_r : 0;
- assign vga_green = vga_active ? f_g : 0;
- assign vga_blue = vga_active ? f_b : 0;
- assign vga_hsync_n = ~vga_HS;
- assign vga_vsync_n = ~vga_VS;
- /*
- An 18-bit counter, multiplied by the frequency gives a single bit
- pulse that advances the voice's wave counter.
- Frequency of 4 means 1Hz, 16385 means 4095.75Hz.
- 18-bit counter increments every 1/(2**18), or 262144 Hz.
- */
- `define MASTERFREQ (1 << 22)
- reg [27:0] d;
- wire [27:0] dInc = d[27] ? (`MASTERFREQ) : (`MASTERFREQ - 50000000);
- wire [27:0] dN = d + dInc;
- reg [16:0] soundmaster; // This increments at MASTERFREQ Hz
- always @(posedge vga_clk)
- begin
- d = dN;
- // clock B tick whenever d[27] is zero
- if (dN[27] == 0) begin
- soundmaster <= soundmaster + 1;
- end
- end
- wire [6:0] hsin;
- wire [6:0] wavecounter;
- wire [6:0] note = wavecounter[6:0];
- `ifdef YES
- RAM64X1S #(.INIT(64'b0000000000110101100010001111010010010111100010001101011000000000) /* 0 */
- ) sin0(.O(hsin[0]), .A0(note[0]), .A1(note[1]), .A2(note[2]), .A3(note[3]), .A4(note[4]), .A5(note[5]), .D(0), .WCLK(vga_clk), .WE(0));
- RAM64X1S #(.INIT(64'b0101010101101100011100010101001111100101010001110001101101010101) /* 1 */
- ) sin1(.O(hsin[1]), .A0(note[0]), .A1(note[1]), .A2(note[2]), .A3(note[3]), .A4(note[4]), .A5(note[5]), .D(0), .WCLK(vga_clk), .WE(0));
- RAM64X1S #(.INIT(64'b0110011001001001010101001100111111111001100101010100100100110011) /* 2 */
- ) sin2(.O(hsin[2]), .A0(note[0]), .A1(note[1]), .A2(note[2]), .A3(note[3]), .A4(note[4]), .A5(note[5]), .D(0), .WCLK(vga_clk), .WE(0));
- RAM64X1S #(.INIT(64'b0010110100100100110011000011111111111110000110011001001001011010) /* 3 */
- ) sin3(.O(hsin[3]), .A0(note[0]), .A1(note[1]), .A2(note[2]), .A3(note[3]), .A4(note[4]), .A5(note[5]), .D(0), .WCLK(vga_clk), .WE(0));
- RAM64X1S #(.INIT(64'b0001110011100011110000111111111111111111111000011110001110011100) /* 4 */
- ) sin4(.O(hsin[4]), .A0(note[0]), .A1(note[1]), .A2(note[2]), .A3(note[3]), .A4(note[4]), .A5(note[5]), .D(0), .WCLK(vga_clk), .WE(0));
- RAM64X1S #(.INIT(64'b0000001111100000001111111111111111111111111111100000001111100000) /* 5 */
- ) sin5(.O(hsin[5]), .A0(note[0]), .A1(note[1]), .A2(note[2]), .A3(note[3]), .A4(note[4]), .A5(note[5]), .D(0), .WCLK(vga_clk), .WE(0));
- RAM64X1S #(.INIT(64'b0000000000011111111111111111111111111111111111111111110000000000) /* 6 */
- ) sin6(.O(hsin[6]), .A0(note[0]), .A1(note[1]), .A2(note[2]), .A3(note[3]), .A4(note[4]), .A5(note[5]), .D(0), .WCLK(vga_clk), .WE(0));
- `else
- ROM64X1 #(.INIT(64'b0000000000110101100010001111010010010111100010001101011000000000) /* 0 */) sin0(.O(hsin[0]), .A0(note[0]), .A1(note[1]), .A2(note[2]), .A3(note[3]), .A4(note[4]), .A5(note[5]));
- ROM64X1 #(.INIT(64'b0101010101101100011100010101001111100101010001110001101101010101) /* 1 */) sin1(.O(hsin[1]), .A0(note[0]), .A1(note[1]), .A2(note[2]), .A3(note[3]), .A4(note[4]), .A5(note[5]));
- ROM64X1 #(.INIT(64'b0110011001001001010101001100111111111001100101010100100100110011) /* 2 */) sin2(.O(hsin[2]), .A0(note[0]), .A1(note[1]), .A2(note[2]), .A3(note[3]), .A4(note[4]), .A5(note[5]));
- ROM64X1 #(.INIT(64'b0010110100100100110011000011111111111110000110011001001001011010) /* 3 */) sin3(.O(hsin[3]), .A0(note[0]), .A1(note[1]), .A2(note[2]), .A3(note[3]), .A4(note[4]), .A5(note[5]));
- ROM64X1 #(.INIT(64'b0001110011100011110000111111111111111111111000011110001110011100) /* 4 */) sin4(.O(hsin[4]), .A0(note[0]), .A1(note[1]), .A2(note[2]), .A3(note[3]), .A4(note[4]), .A5(note[5]));
- ROM64X1 #(.INIT(64'b0000001111100000001111111111111111111111111111100000001111100000) /* 5 */) sin5(.O(hsin[5]), .A0(note[0]), .A1(note[1]), .A2(note[2]), .A3(note[3]), .A4(note[4]), .A5(note[5]));
- ROM64X1 #(.INIT(64'b0000000000011111111111111111111111111111111111111111110000000000) /* 6 */) sin6(.O(hsin[6]), .A0(note[0]), .A1(note[1]), .A2(note[2]), .A3(note[3]), .A4(note[4]), .A5(note[5]));
- `endif
- wire signed [7:0] sin = note[6] ? (8'h00 - hsin) : hsin;
- wire voiceshape = voicefh_data[7];
- wire [14:0] voicefreq = {voicefh_data[6:0], voicefl_data};
- wire [35:0] derived = {1'b0, soundmaster} * voicefreq;
- wire highfreq = voicefreq[14];
- wire newpulse = highfreq ? derived[18] : derived[17]; // pulse is a square wave frequency 64*f
- wire oldpulse;
- wire [6:0] nextwavecounter = voiceshape ? lfsr : (wavecounter + (highfreq ? 2 : 1));
- wire [6:0] _wavecounter = (newpulse != oldpulse) ? nextwavecounter : wavecounter;
- `ifdef NELLY
- ram64x8s voicestate(
- .a(viN),
- .we(1),
- .wclk(vga_clk),
- .d({_wavecounter, newpulse}),
- .o({wavecounter, oldpulse}));
- `else
- wire [8:0] vsi = {_wavecounter, newpulse};
- wire [8:0] vso;
- ring64 vs0(.clk(vga_clk), .i(vsi[0]), .o(vso[0]));
- ring64 vs1(.clk(vga_clk), .i(vsi[1]), .o(vso[1]));
- ring64 vs2(.clk(vga_clk), .i(vsi[2]), .o(vso[2]));
- ring64 vs3(.clk(vga_clk), .i(vsi[3]), .o(vso[3]));
- ring64 vs4(.clk(vga_clk), .i(vsi[4]), .o(vso[4]));
- ring64 vs5(.clk(vga_clk), .i(vsi[5]), .o(vso[5]));
- ring64 vs6(.clk(vga_clk), .i(vsi[6]), .o(vso[6]));
- ring64 vs7(.clk(vga_clk), .i(vsi[7]), .o(vso[7]));
- assign wavecounter = vso[7:1];
- assign oldpulse = vso[0];
- `endif
- wire signed [8:0] lamp = voicela_data;
- wire signed [8:0] ramp = voicera_data;
- reg signed [35:0] lmodulated;
- reg signed [35:0] rmodulated;
- always @(posedge vga_clk)
- begin
- lmodulated = lamp * sin;
- rmodulated = ramp * sin;
- end
- // Have lmodulated and rmodulated
- reg signed [15:0] lacc;
- reg signed [15:0] racc;
- wire signed [15:0] lsum = lacc + lmodulated[15:0];
- wire signed [15:0] rsum = racc + rmodulated[15:0];
- wire signed [31:0] lprod = lacc * lmodulated;
- wire signed [31:0] rprod = racc * rmodulated;
- wire zeroacc = (vi == 63);
- wire [15:0] _lacc = zeroacc ? sample_l : ((vi == modvoice) ? lprod[30:15] : lsum);
- wire [15:0] _racc = zeroacc ? sample_r : ((vi == modvoice) ? rprod[30:15] : rsum);
- reg signed [12:0] lvalue;
- reg signed [12:0] rvalue;
- always @(posedge vga_clk)
- begin
- if (vi == 63) begin
- lvalue <= lsum[15:3] /* + sample_l + 32768 */;
- rvalue <= rsum[15:3] /* + sample_r + 32768 */;
- end
- lacc <= _lacc;
- racc <= _racc;
- end
- wire signed [7:0] dither = soundcounter;
- // wire [15:0] dither = {soundcounter[0],
- // soundcounter[1],
- // soundcounter[2],
- // soundcounter[3],
- // soundcounter[4],
- // soundcounter[5],
- // soundcounter[6],
- // soundcounter[7],
- // soundcounter[8],
- // soundcounter[9],
- // soundcounter[10],
- // soundcounter[11],
- // soundcounter[12],
- // soundcounter[13],
- // soundcounter[14],
- // soundcounter[15]
- // };
- `ifdef NELLY
- wire lau_out = lvalue >= dither;
- wire rau_out = rvalue >= dither;
- assign AUDIOL = lau_out;
- assign AUDIOR = rau_out;
- `else
- wire [12:0] ulvalue = lvalue ^ 4096;
- wire [12:0] urvalue = rvalue ^ 4096;
- dac ldac(AUDIOL, ulvalue, vga_clk, 0);
- dac rdac(AUDIOR, urvalue, vga_clk, 0);
- `endif
- reg [2:0] busyhh;
- always @(posedge vga_clk) busyhh = { busyhh[1:0], host_busy };
- // J1 Peripherals
- reg [7:0] icap_i; // ICAP in
- reg icap_write;
- reg icap_ce;
- reg icap_clk;
- wire [7:0] icap_o; // ICAP out
- wire icap_busy;
- reg j1_p2_dir = 1; // pin defaults to input
- reg j1_p2_o = 1;
- ICAP_SPARTAN3A ICAP_SPARTAN3A_inst (
- .O(icap_o),
- .BUSY(icap_busy),
- .I(icap_i),
- .WRITE(icap_write),
- .CE(icap_ce),
- .CLK(icap_clk));
- reg dna_read;
- reg dna_shift;
- reg dna_clk;
- wire dna_dout;
- DNA_PORT dna(
- .DOUT(dna_dout),
- .DIN(0),
- .READ(dna_read),
- .SHIFT(dna_shift),
- .CLK(dna_clk));
- wire j1_wr;
- reg [8:0] YYLINE;
- wire [9:0] yyline = (CounterY + 4 - (35 + 6 + 21 + 1));
- always @(posedge vga_clk)
- begin
- // if (xx == 400)
- if (composite_complete)
- YYLINE = yyline[9:1];
- end
- reg [15:0] freqhz = 8000;
- reg [7:0] freqtick;
- reg [26:0] freqd;
- wire [26:0] freqdN = freqd + freqhz - (freqd[26] ? 0 : 50000000);
- always @(posedge vga_clk)
- begin
- freqd = freqdN;
- if (freqd[26] == 0)
- freqtick = freqtick + 1;
- end
- reg [15:0] local_j1_read;
- always @*
- begin
- case ({j1_mem_addr[4:1], 1'b0})
- 5'h00: local_j1_read <= YYLINE;
- 5'h02: local_j1_read <= icap_o;
- 5'h0c: local_j1_read <= freqtick;
- 5'h0e: local_j1_read <= AUX;
- 5'h12: local_j1_read <= lfsr;
- 5'h14: local_j1_read <= soundcounter;
- 5'h16: local_j1_read <= flashMISO;
- 5'h18: local_j1_read <= dna_dout;
- // default: local_j1_read <= 16'hffff;
- endcase
- end
- wire [0:7] j1_mem_dout_be = j1_mem_dout;
- reg j1_flashMOSI;
- reg j1_flashSCK;
- reg j1_flashSSEL;
- always @(posedge vga_clk)
- begin
- if (j1_wr & (j1_mem_addr[15] == 1))
- case ({j1_mem_addr[4:1], 1'b0})
- // 5'h06: icap_i <= j1_mem_dout;
- // 5'h08: icap_write <= j1_mem_dout;
- // 5'h0a: icap_ce <= j1_mem_dout;
- // 5'h0c: icap_clk <= j1_mem_dout;
- 5'h06: {icap_write,icap_ce,icap_clk,icap_i} <= j1_mem_dout;
- 5'h08: {dna_read, dna_shift, dna_clk} <= j1_mem_dout;
- 5'h0a: freqhz <= j1_mem_dout;
- 5'h0e: j1_p2_o <= j1_mem_dout;
- 5'h10: j1_p2_dir <= j1_mem_dout;
- 5'h18: j1_flashMOSI <= j1_mem_dout;
- 5'h1a: j1_flashSCK <= j1_mem_dout;
- 5'h1c: j1_flashSSEL <= j1_mem_dout;
- endcase
- end
- assign j1_mem_wr = j1_wr & (j1_mem_addr[15] == 0);
- j0 j(.sys_clk_i(vga_clk),
- .sys_rst_i(j1_reset),
- .insn(j1_insn),
- .insn_addr(j1_insn_addr),
- .mem_wr(j1_wr),
- .mem_addr(j1_mem_addr),
- .mem_dout(j1_mem_dout),
- .mem_din(j1_mem_addr[15] ? local_j1_read : mem_data_rd),
- .pause(host_busy | (busyhh != 0))
- );
- // 0x2b00: j1 insn RAM
- wire jinsn_wr = (mem_wr & (mem_w_addr[14:8] == 6'h2b));
- RAM_CODEL jinsnl(.b(j1_insn_addr), .bo(j1_insn[7:0]),
- .a(mem_addr[7:1]),
- .wclk(vga_clk),
- .wea((mem_w_addr[0] == 0) & jinsn_wr),
- .ad(mem_data_wr),
- .ao(j1insnl_read));
- RAM_CODEH jinsnh(.b(j1_insn_addr), .bo(j1_insn[15:8]),
- .a(mem_addr[7:1]),
- .wclk(vga_clk),
- .wea((mem_w_addr[0] == 1) & jinsn_wr),
- .ad(mem_data_wr),
- .ao(j1insnh_read));
- assign flashMOSI = pin2j ? j1_flashMOSI : MOSI;
- assign flashSCK = pin2j ? j1_flashSCK : SCK;
- assign flashSSEL = pin2f ? AUX : (pin2j ? j1_flashSSEL : 1);
- assign AUX = (pin2j & (j1_p2_dir == 0)) ? j1_p2_o : 1'bz;
- endmodule // top
|