From ff2e78f45d60992ad9b63c3b595c029f98b10713 Mon Sep 17 00:00:00 2001 From: Stephan Date: Sun, 15 Mar 2026 11:49:21 +0100 Subject: [PATCH 1/6] add inter fpga link to frontend All a GSE/Calibration/High Speed Streaming interface to the spi frontend module. --- altera/frontend.v | 88 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 7 deletions(-) diff --git a/altera/frontend.v b/altera/frontend.v index de480180..28dfd0bf 100644 --- a/altera/frontend.v +++ b/altera/frontend.v @@ -9,6 +9,13 @@ module frontend input spi_mosi, output spi_miso, +`ifdef AX_PORT + input sclk, + input ARxC, ARxD, + output ATxC, ATxD, + output [W-2:0] states, strobes, +`endif + output we, output wp, output [W-3:0] wa, @@ -93,14 +100,79 @@ module frontend else {re_core, rd_core} <= {re, rd}; + wire s_we, s_wp; + wire [W-3:0] s_wa; + wire [W-1:0] s_wd; + spi_slave arm (.mclk(mclk), .ssel(spi_ssel), .sclk(spi_sck), .mosi(spi_mosi), .miso(spi_miso), - .we(we), .wp(wp), .wa(wa), .wd(wd), + .we(s_we), .wp(s_wp), .wa(s_wa), .wd(s_wd), .re(re_fend|re_fifo|re_core), .rd(rd_fend|rd_fifo|rd_core), .rreset(spi_reset), .roverflow(spi_overflow), .afull(spi_afull), .rdefault(spi_default) ); +`ifndef AX_PORT + assign {we, wp, wa, wd} = {s_we, s_wp, s_wa, s_wd}; + wire ax_clock_reset = 0; + wire ax_read_fifo = 0; + wire ax_ff_enable = 0; + wire ax_afull = 0; +`else + + // inter FPGA serial link as GSE/calib/test/HSS interface + + wire a_we, a_wp; + wire [W-3:0] a_wa; + wire [W-1:0] a_wd; + + reg r_we, r_wp; + reg [W-3:0] r_wa; + reg [W-1:0] r_wd; + + assign {we, wp, wa, wd} = {r_we, r_wp, r_wa, r_wd}; + + ser_slave_rx srx + (.mclk(mclk), .ser_clk(ARxC), + .TX(ARxD), + .we(a_we), .wp(a_wp), .wa(a_wa), .wd(a_wd), + .states(states), .strobes(strobes), + .lost_sync(stats[2]) ); + + always @(posedge mclk) + begin + if (s_we) + {r_wp, r_wa, r_wd} <= {s_wp, s_wa, s_wd}; + else if (a_we) + {r_wp, r_wa, r_wd} <= {a_wp, a_wa, a_wd}; + r_we <= s_we | a_we; + end + + wire ax_disable; + + wire ax_clock_reset = strobes[3] & ~ax_disable; + wire ax_read_fifo = strobes[12] & ~ax_disable; + wire ax_rb_reset = strobes[13]; + wire ax_fifo_reset = strobes[14]; + + wire ax_ff_enable = states[12] & ~ax_disable; + wire ax_rb_disable = states[13]; + wire ax_fifo_full = states[14]; + + wire ATxCh; + assign ATxC = sclk; + + ser_slave_tx #(.AF(6)) stx + (.mclk(mclk), .ser_clk(sclk), + .freset(ax_fifo_reset), .rreset(ax_rb_reset), + .fifo_full(ax_fifo_full), + .rb_disable(ax_rb_disable), + .RXp({ATxCh,ATxD}), + .re(re_fend|re_core), .rd(rd_fend|rd_core), + .fifoe(ax_ff_enable & re_fifo), .fifo(rd_fifo), + .fifof(ax_afull) ); +`endif // !`ifndef AX_PORT + // master config and status parameter RFIFO_ADDR = 0; @@ -155,7 +227,8 @@ module frontend // 16 strobes to set things straight. reset_reg master_rsts(mclk, ww[MRSTS_ADDR], wp, wd, resets); - wire rfifo = ww[RFIFO_ADDR] & ~wp; + wire rfifo = ww[RFIFO_ADDR] & ~wp | ax_read_fifo; + wire afull = ax_ff_enable ? ax_afull : spi_afull; parameter WHK_ADDR = 'h 10; parameter RHKS_ADDR = 'h 10; @@ -192,7 +265,7 @@ module frontend packetfifo hkfifo(.mclk(mclk), .reset(fifo_reset[0]), - .afull(spi_afull), + .afull(afull), .push(ww[WHK_ADDR] & wp), .data(wd), .full(hkfifo_full), @@ -215,7 +288,7 @@ module frontend packetfifo f1(.mclk(mclk), .reset(fifo_reset[1]), - .afull(spi_afull), + .afull(afull), .push(fifo_push[1]), .data(fifo1), .full(fifo_full[1]), @@ -238,7 +311,7 @@ module frontend packetfifo f2(.mclk(mclk), .reset(fifo_reset[2]), - .afull(spi_afull), + .afull(afull), .push(fifo_push[2]), .data(fifo2), .full(fifo_full[2]), @@ -261,7 +334,7 @@ module frontend packetfifo f3(.mclk(mclk), .reset(fifo_reset[3]), - .afull(spi_afull), + .afull(afull), .push(fifo_push[3]), .data(fifo3), .full(fifo_full[3]), @@ -287,12 +360,13 @@ module frontend assign fifo_disable = confs[8]; assign fend_disable = confs[9]; assign core_disable = confs[10]; + assign ax_disable = confs[11]; assign lstats[0] = errsum; assign lstats[7:4] = {fifo_full, hkfifo_full}; assign lstats[15:8] = {packet, empty}; - assign clock_reset = resets[3]; + assign clock_reset = resets[3] | ax_clock_reset; assign fifo_reset = resets[7:4]; assign spi_reset = resets[8]; assign mconf_reset = resets[9]; From f0500402fdb7beceb4bb4d503cb45a7c84f09354 Mon Sep 17 00:00:00 2001 From: Stephan Date: Mon, 16 Mar 2026 08:17:17 +0100 Subject: [PATCH 2/6] frontend: properly wire up lost_sync --- altera/frontend.v | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/altera/frontend.v b/altera/frontend.v index 28dfd0bf..4ff20f67 100644 --- a/altera/frontend.v +++ b/altera/frontend.v @@ -118,6 +118,7 @@ module frontend wire ax_read_fifo = 0; wire ax_ff_enable = 0; wire ax_afull = 0; + tri0 lost_sync; `else // inter FPGA serial link as GSE/calib/test/HSS interface @@ -131,13 +132,13 @@ module frontend reg [W-1:0] r_wd; assign {we, wp, wa, wd} = {r_we, r_wp, r_wa, r_wd}; - + wire lost_sync; ser_slave_rx srx (.mclk(mclk), .ser_clk(ARxC), .TX(ARxD), .we(a_we), .wp(a_wp), .wa(a_wa), .wd(a_wd), .states(states), .strobes(strobes), - .lost_sync(stats[2]) ); + .lost_sync(lost_sync) ); always @(posedge mclk) begin @@ -162,6 +163,8 @@ module frontend wire ATxCh; assign ATxC = sclk; + wire ax_afull; + ser_slave_tx #(.AF(6)) stx (.mclk(mclk), .ser_clk(sclk), .freset(ax_fifo_reset), .rreset(ax_rb_reset), @@ -363,6 +366,7 @@ module frontend assign ax_disable = confs[11]; assign lstats[0] = errsum; + assign lstats[2] = lost_sync; assign lstats[7:4] = {fifo_full, hkfifo_full}; assign lstats[15:8] = {packet, empty}; @@ -372,6 +376,7 @@ module frontend assign mconf_reset = resets[9]; assign lerrors[0] = spi_overflow; + assign lerrors[2] = lost_sync; assign lerrors[7:4] = {fifo_full, hkfifo_full}; assign lerrors[15:8] = {packet, empty}; From 14a3bc4b9e5d895de8ace2e3930e2aa9eb50e870 Mon Sep 17 00:00:00 2001 From: Stephan Date: Mon, 16 Mar 2026 08:19:52 +0100 Subject: [PATCH 3/6] stis: provide individual fifo outputs for thhor --- dorn/altera/stis_ana_core.v | 59 +++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/dorn/altera/stis_ana_core.v b/dorn/altera/stis_ana_core.v index 250a63a6..29e378b9 100644 --- a/dorn/altera/stis_ana_core.v +++ b/dorn/altera/stis_ana_core.v @@ -616,7 +616,7 @@ module stis_ana_core endmodule // stis_ana_core module stis_slice - #(parameter MCLK=16, I=0, ND=4, WH=6) + #(parameter MCLK=16, I=0, ND=4, WH=6, FO=1) ( input mclk, @@ -629,9 +629,23 @@ module stis_slice output reg fifo_e, output reg [15:0] fifo, + output reg hk_fifo_e, + output reg ev_fifo_e, + output reg [2:0] sa_fifo_e, + output reg [15:0] hk_fifo, + output reg[191:0] ev_fifo, + output reg [47:0] sa_fifo, input afull, +`ifdef THHOR + input hk_afull, + input ev_afull, + input sa_afull, + input [2:0] fifo_nonblock, +`endif input [15:0] ev_psize, input [11:0] ev_word_sel, + output reg event_valid, + input [2:0] ff_enable, ff_read, ff_reset, input [2:0] rri, rbi, @@ -640,7 +654,8 @@ module stis_slice input enable, resync, req_hk, input clock_reset, dorn_reset, - + output reg [31:0] clock, + `ifdef WITH_DORN_L4 output incr, output [WH+3:0] hist, @@ -657,10 +672,17 @@ module stis_slice input gtrigger, output trigger, - output SCLK, nCS, DIN, + output [FO-1:0] SCLK, nCS, DIN, input [ND-1:0] DOUT ); +`ifndef THHOR + wire hk_afull = 0; + wire ev_afull = 0; + wire sa_afull = 0; + wire [2:0] fifo_nonblock = 0; +`endif + parameter HK_MAGIC = 16'h 5710; parameter SA_MAGIC = 16'h 5714; parameter EV_MAGIC = 16'h 5718; @@ -671,7 +693,6 @@ module stis_slice parameter WC = 2; parameter NR = 26; - reg [31:0] clock; always @(posedge mclk) if (clock_reset) clock <= 0; @@ -709,7 +730,7 @@ module stis_slice wire hk_fifo_full; - dorn_core #(.DCLK(MCLK), .FO(1), .ND(ND), .NE(32), .WH(WH)) dorn + dorn_core #(.DCLK(MCLK), .FO(FO), .ND(ND), .NE(32), .WH(WH)) dorn (.dclk(mclk), .enable(enable & ~resync), .req_hk(req_hk & ~hk_fifo_full), .l2_reset(dorn_reset), @@ -737,8 +758,6 @@ module stis_slice parameter [15:0] HK_SIZE = 8*ND; wire [15:0] hk_magic = HK_MAGIC + I; - reg [15:0] hk_fifo; - reg hk_fifo_e; always @(posedge mclk) begin if (req_hk & ~hk_fifo_full) @@ -759,27 +778,25 @@ module stis_slice .we(1'b0), .psize(HK_SIZE), .hmask(16'hffff), .hval(hk_magic), .match(64'b0) ); - assign hk_fifo_full = ff_full[0]; + assign hk_fifo_full = ff_full[0] & ~fifo_nonblock[0] | hk_afull; wire [15:0] ev_magic = EV_MAGIC + I; wire ev_fifo_full; - reg [191:0] ev_fifo; - reg ev_fifo_e; reg [11:1] evv; reg [31:0] ev_last_clock; reg [31:0] ev_dtime; reg [14-WC-WD:0] ev_lost; + wire ev_fifo_busy = |{ev_fifo_full, ev_fifo_e, evv}; always @(posedge mclk) begin - // BUG: `ev_fifo_e` is insufficient for sparse events - if (valid & ~ev_fifo_full & ~ev_fifo_e) + if (valid & ~ev_fifo_busy) {ev_fifo_e, evv} <= ev_word_sel; else {ev_fifo_e, evv} <= {evv, 1'b0}; - // BUG: garbles the previous event when `ev_fifo_e` - if (valid) + event_valid <= valid & ~ev_fifo_busy; + if (valid & ~ev_fifo_busy) ev_fifo <= { pha[34:3], a[NR-17:NR-24], b[NR-17:NR-24], b[NR-1:NR-16], @@ -794,10 +811,10 @@ module stis_slice ev_fifo <= {16'b0, ev_fifo[191:16]}; if (valid) - if ((ev_fifo_e | ev_fifo_full) & ~&ev_lost) - ev_lost <= ev_lost + 1; - else + if (~ev_fifo_busy) ev_lost <= 0; + else if (~&ev_lost) + ev_lost <= ev_lost + 1; // everything but pha[] becomes valid some clocks before valid. ev_dtime <= filter_clock - ev_last_clock; @@ -811,7 +828,7 @@ module stis_slice packetfifo fev (.mclk(mclk), .reset(ff_reset[1]), .afull(afull), .push(ev_fifo_e), .data(ev_fifo[15:0]), - .full(ev_fifo_full), + .full(ff_full[1]), .halffull(ff_half[1]), .empty(ff_empty[1]), .packet(ff_packet[1]), .re(ree[2]), .rd(rdd[2]), .rre(ff_enable[1]), .rr(ff_read[1]), @@ -819,11 +836,9 @@ module stis_slice .we(1'b0), .psize(ev_psize), .hmask(16'hffff), .hval(ev_magic), .match(64'b0) ); - assign ff_full[1] = ev_fifo_full; + assign ev_fifo_full = ff_full[1] & ~fifo_nonblock[1] | ev_afull; wire [15:0] sa_magic = SA_MAGIC + I; - reg [47:0] sa_fifo; - reg [2:0] sa_fifo_e; wire [15:0] sa_chdata = {sa_addr[3:0], sa_data}; always @(posedge mclk) begin @@ -865,7 +880,7 @@ module stis_slice .we(1'b0), .psize(SA_SIZE), .hmask(16'hffff), .hval(sa_magic), .match(64'b0) ); - assign sa_busy = ff_half[2]; + assign sa_busy = ff_half[2] & ~fifo_nonblock[2] | sa_afull; endmodule // stis_slice From f5590f42603db54d86feab8850aaa29a121e9efc Mon Sep 17 00:00:00 2001 From: Stephan Date: Mon, 16 Mar 2026 08:20:21 +0100 Subject: [PATCH 4/6] stis: provide individual fifo outputs for thhor, log --- .gitignore | 2 + dorn/altera/nmahepam.gold | 34 +-- dorn/altera/thhor_core.v | 500 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 519 insertions(+), 17 deletions(-) create mode 100644 dorn/altera/thhor_core.v diff --git a/.gitignore b/.gitignore index 61947970..ad5acf9d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ db/ incremental_db/ *.vvp +vcd +*~ diff --git a/dorn/altera/nmahepam.gold b/dorn/altera/nmahepam.gold index 856306e2..1f108f34 100644 --- a/dorn/altera/nmahepam.gold +++ b/dorn/altera/nmahepam.gold @@ -1,21 +1,21 @@ Compiling VVP ... ... VVP file version 12.0 (stable) Compile cleanup... - ... 6269 functors (net_fun pool=524288 bytes) - 1466 logic + ... 6326 functors (net_fun pool=524288 bytes) + 1503 logic 0 bufif 5 resolv - 2572 signals - ... 5867 filters (net_fil pool=786432 bytes) - ... 34184 opcodes (835584 bytes) - ... 5269 nets - ... 6269 vvp_nets (1048544 bytes) + 2574 signals + ... 5924 filters (net_fil pool=786432 bytes) + ... 34194 opcodes (835584 bytes) + ... 5295 nets + ... 6326 vvp_nets (1048544 bytes) ... 71 arrays (415 words) ... 82 memories 82 logic (30000 words) 0 real (0 words) - ... 980 scopes - ... 0.052337 seconds, 24848.0/16776.0/5328.0 KBytes size/rss/shared + ... 981 scopes + ... 0.129428 seconds, 24988.0/17200.0/5596.0 KBytes size/rss/shared Running ... ...execute EndOfCompile callbacks ...propagate initialization events @@ -2371,7 +2371,7 @@ FE[0]: event timestamp 15 L1 SAMPLE: slot 1 ch_det 21 idx 3 adc 415 FE[0]: event Δ-time x spi frame: sent 8000, received 0000 -FE[0]: event lost 0 ch 0 det 1 +FE[0]: event lost X ch 0 det 1 FE[0]: event a 14048 spi frame: sent 8000, received 0000 FE[0]: event b -6626 @@ -2404,7 +2404,7 @@ L1 SAMPLE: slot 10 ch_det 2 idx 5 adc 514 spi frame: sent 8000, received xxxx FE[0]: event b -8 L1 SAMPLE: slot 11 ch_det 3 idx 5 adc 517 -spi frame: sent 8000, received 8001 +spi frame: sent 8000, received XxX1 L1 SAMPLE: slot 12 ch_det 9 idx 5 adc 547 L1 SAMPLE: slot 13 ch_det 10 idx 5 adc 504 L1 SAMPLE: slot 14 ch_det 11 idx 5 adc 348 @@ -2495,7 +2495,7 @@ L1 SAMPLE: slot 1 ch_det 21 idx 8 adc 450 FE[1]: event timestamp 15 spi frame: sent 8000, received 000e FE[1]: event Δ-time x -FE[1]: event lost 1 ch 1 det 1 +FE[1]: event lost X ch 1 det 1 L1 SAMPLE: slot 9 ch_det 1 idx 9 adc 866 L1 SAMPLE: slot 10 ch_det 2 idx 9 adc 514 FE[1]: event a 14679 @@ -2764,7 +2764,7 @@ FS[0]: sample[0010] 498 L2 sum: slot 12 ch_det 9 A -14947 B 1030 age 17 FS[0]: sample[0110] 557 FS[0]: sample[1010] 501 -spi frame: sent 8000, received 8015 +spi frame: sent 8000, received XxX5 FS[0]: sample[1110] 498 L2 sum: slot 12 ch_det 9 A -11896 B -112 age 16 spi frame: sent 8000, received 3957 @@ -6193,16 +6193,16 @@ spi frame: sent 8000, received 0000 spi frame: sent 8000, received 0000 spi frame: sent 8000, received 0000 spi frame: sent 8000, received 0000 -nmahepam.v:462: $finish called at 2404598250 (1ps) +nmahepam.v:463: $finish called at 2404598250 (1ps) ...execute Postsim callbacks - ... 47.5244 seconds, 25820.0/18084.0/5580.0 KBytes size/rss/shared + ... 144.964 seconds, 26884.0/19560.0/5752.0 KBytes size/rss/shared Event counts: 2139391 time steps (pool=113) 9329988 thread schedule events - 155825391 assign events + 155979390 assign events ...assign(vec4) pool=9362 ...assign(vec8) pool=204 ...assign(real) pool=256 ...assign(word) pool=128 ...assign(word/r) pool=204 - 5411650 other events (pool=4096) + 5425314 other events (pool=4096) diff --git a/dorn/altera/thhor_core.v b/dorn/altera/thhor_core.v new file mode 100644 index 00000000..b0d60ffe --- /dev/null +++ b/dorn/altera/thhor_core.v @@ -0,0 +1,500 @@ + +module thhor_core + #(parameter MCLK=32, ND=4, FO=4) + ( + input mclk, + + + input we, wp, + input [13:0] wa, + input [15:0] wd, + output re, + output [15:0] rd, + + input [15:0] confs, + input [15:0] resets, + input [14:0] ax_strobes, ax_states, + + output [31:0] clock, + output stick, + + output [3:1] fifo_e, + output [15:0] fifo1, fifo2, fifo3, + input [3:1] afull, + output [15:0] ev_psize, + + output [ND*3:0] counter_hit, + + output [FO-1:0] SCLK, nCS, DIN, + input [ND-1:0] DOUT + ); + + parameter DORN_ADDR = 14'h 2000; + parameter MISC_ADDR = 14'h 0080+DORN_ADDR; + + reg [14:0] strobes; + + wire dorn_reset = strobes[8]; + wire req_hk = strobes[4]; + wire clock_reset = strobes[3]; + wire resync = strobes[2]; + + wire [14:0] spi_strobes = { 6'b0, + resets[2], + resets[15:12], + resets[3:0] }; + + wire ax_disable = confs[11]; + wire enable_s = ax_states[0] & ~ax_disable | confs[0]; + wire full_events = ~confs[1]; + + assign ev_psize = full_events ? 11 : 7; + + reg [15:0] ww; // mostly unused + always @(posedge mclk) + if (we & wa[13:4] == MISC_ADDR[13:4]) + ww <= 1 << wa[3:0]; + else + ww <= 0; + + wire enable_c; + reg enable; + always @(posedge mclk) + begin + if (ax_disable) + if (ww[11] & wp) + strobes <= wd[14:0]; + else + strobes <= spi_strobes; + else + if (ww[11] & wp) + strobes <= ax_strobes | wd[14:0]; + else + strobes <= ax_strobes | spi_strobes; + + enable <= enable_s; + end + + // the ports of stis_slice are wider than needed here + wire [2:0] sa_fifo_e; + assign fifo_e[3] = sa_fifo_e[0]; + wire [47:0] sa_fifo; + assign fifo3 = sa_fifo[15:0]; + wire [191:0] ev_fifo; + assign fifo2 = ev_fifo[15:0]; + wire [11:0] ev_word_sel; + wire event_valid; + + stis_slice #(.MCLK(MCLK), .ND(ND), .FO(FO)) stis + (.mclk(mclk), + .conf_we(we), .conf_wp(wp), .conf_wa(wa), .conf_wd(wd), + .conf_re(re), .conf_rd(rd), + .hk_fifo_e(fifo_e[1]), .ev_fifo_e(fifo_e[2]), .sa_fifo_e(sa_fifo_e), + .hk_fifo(fifo1), .ev_fifo(ev_fifo), .sa_fifo(sa_fifo), + .hk_afull(afull[1]), .ev_afull(afull[2]), .sa_afull(afull[3]), + .ev_psize(ev_psize), .ev_word_sel(ev_word_sel), .event_valid(event_valid), + .ff_enable(3'b 000), .ff_read(3'b 000), .ff_reset(3'b 111), + .rri(3'b 000), .rro(), .rbi(3'b 111), + .enable(enable), .resync(resync), .req_hk(req_hk), + .clock_reset(clock_reset), .dorn_reset(dorn_reset), + .counter_hit(counter_hit), .stick(stick), .clock(clock), + .gtrigger(1'b0), + .SCLK(SCLK), .nCS(nCS), .DIN(DIN), .DOUT(DOUT) ); + +endmodule // thhor_core + +`ifdef SIMULATION + `timescale 1ns/1ps + + `ifdef THHOR_TEST + `define THHOR_JIG + `endif + + `ifdef THHOR_JIG + +module thhor_jig + #(parameter SLICES=1, ND=4) + ( + // Quarz + output reg mclk, + + output [14:0] strobes, states, + + output we, wp, + output [13:0] wa, + output [15:0] wd, + + input re, + input [15:0] rd, + + input fifoe, + input [15:0] fifo, + + // ADC + input [SLICES-1:0] SCLK, nCS, DIN, + output [ND*SLICES-1:0] DOUT + ); + + always + begin + # 15.625 mclk = 0; + # 15.625 mclk = 1; + end + + always @(posedge xclk) + mclk = mclk !== 1; + + parameter WD = $clog2(ND); + + reg [11:0] shape[0:511]; + initial $readmemh("sallen-key-pulse.hex", shape); + + reg [2:0] pulse_a; + reg [2:0] pulse_s[0:15]; + task pulse; + input [1:0] sl; + input [5:0] ch; + input [2:0] a; + integer c,d; + begin + c = ch[WD+1:WD]; + d = {sl, ch[WD-1:0]}; + pulse_a = a; + pulse_s[d][c] = pulse_s[d][c] !== 1; + end + endtask + + genvar i, j; + generate + for (i=0; i send_strobes; + @(posedge mclk) a_strobes <= 0; + end + endtask + task set; + input [3:0] n; + begin + @(posedge mclk) a_states <= a_states | (1< send_states; + end + endtask + task clear; + input [3:0] n; + begin + @(posedge mclk) a_states <= a_states & ~(1< send_states; + end + endtask + task strobe_m; + input [14:0] n; + begin + @(posedge mclk) a_strobes <= n; + #1 -> send_strobes; + @(posedge mclk) a_strobes <= 0; + end + endtask + task set_m; + input [14:0] n; + begin + @(posedge mclk) a_states <= a_states | n; + #1 -> send_states; + end + endtask + task clear_m; + input [14:0] n; + begin + @(posedge mclk) a_states <= a_states & ~n; + #1 -> send_states; + end + endtask + task cmdw; + begin + @(posedge mclk); + while (awb) @(posedge mclk); + end + endtask + task cmdp; + input [13:0] a; + input [15:0] d; + begin + cmdw; + awe <= 1; + awp <= 1; + awd <= d; + awa <= a; + #1 -> send_command; + @(posedge mclk) awe <=0; + end + endtask + task cmd; + input [13:0] a; + begin + cmdw; + awe <= 1; + awp <= 0; + awd <= 'bx; + awa <= a; + #1 -> send_command; + @(posedge mclk) awe <=0; + end + endtask + + + always @(posedge mclk) + if (re) + $display("MRX RE: %16b", rd); + + assign afull = 0; + wire [15:0] ev_psize = a_states[8] ? 7 : 11; + + wire [15:0] ffifo; + stis_split #(.WH(WH)) split + (.mclk(mclk), .push(fifoe), .data(fifo), + .ev_psize(ev_psize), + .hk_e(hk_e), .ev_e(ev_e), .sa_e(sa_e), .hi_e(hi_e), + .q(ffifo) ); + + task l1_thres; + input [1:0] sl; + input [5:0] ch; + input [11:0] t; + begin + cmdp({1'b1, sl, 5'b 000_01, ch}, t); + end + endtask + + task w_l2; + input [1:0] sl; + input [5:0] ch; + input [3:1] i; + input [11:0] a, b; + begin + cmdp({1'b1, sl, 1'h 1, ch, i, 1'b0}, a); + cmdp({1'b1, sl, 1'h 1, ch, i, 1'b1}, b); + end + endtask + + task w_l3; + input [1:0] sl; + input [5:0] ch; + input [15:0] p0; + input [15:0] p1; // ignored + input [15:0] p2; + input [15:0] p3; + begin + cmdp({1'b1, sl, 3'b 001, ch, 2'd0}, p0); + cmdp({1'b1, sl, 3'b 001, ch, 2'd1}, p2); + cmdp({1'b1, sl, 3'b 001, ch, 2'd2}, p3); + cmdp({1'b1, sl, 3'b 001, ch, 2'd3}, 0); + end + endtask + + task w_l4; + input [1:0] sl; + input [3:0] xt; + input [7:0] cwin; + input [1:0] res; + input [8:0] bin0; + begin + cmdp({1'b1, sl, 11'd 12}, {4'b0, xt, cwin}); + cmdp({1'b1, sl, 11'd 13}, {5'b0, res, bin0}); + end + endtask + + task l1_conf; + integer ch, sl; + begin + for (sl=0; sl>WH, 1, 0); + jig.cmdp('h800, 1); + #10000 jig.pulse('b 00_00_01, 0); + #20000 jig.pulse('b 00_01_11, 0); + #4000 jig.pulse('b 00_10_10, 0); + #50000 jig.pulse('b 00_00_01, 3); + #1000 jig.pulse('b 00_01_11, 1); + #20000 jig.pulse('b 00_10_10, 1); + #100000 jig.strobe_m('b 000_0000_1111_0000); + #100000 jig.r_sram('h300>>WH, 1, 0); + #500000 $finish; + end + +endmodule // stis_ana_core_test + +`endif // `ifdef THHOR_CORE_TEST + +`endif // `ifdef SIMULATION From 60aae89495f05eedb48c9c1468e4c8d4dd92f79f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20I=2E=20B=C3=B6ttcher?= Date: Mon, 16 Mar 2026 22:23:47 +0100 Subject: [PATCH 5/6] move net decls before use iverilog v13 is becoming picky about that. parameter use before decl requires a patch. --- altera/adc128s102.v | 2 +- dorn/altera/dorn.v | 11 +++++------ irena/altera/ms5540c.v | 2 +- nm64/altera/nmcounter.v | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/altera/adc128s102.v b/altera/adc128s102.v index 12c37109..ab90ee96 100644 --- a/altera/adc128s102.v +++ b/altera/adc128s102.v @@ -260,6 +260,7 @@ module adc128s102 // this keeps the input value independent of // delay simulation variations. reg [11:0] ain; + reg [2:0] mux; always @(negedge SCLK) begin if (bitc==3) @@ -278,7 +279,6 @@ module adc128s102 end reg [11:0] sr; - reg [2:0] mux; reg dout; always @(negedge sclk) if (~nCS) diff --git a/dorn/altera/dorn.v b/dorn/altera/dorn.v index 6d246dd9..55c5d127 100644 --- a/dorn/altera/dorn.v +++ b/dorn/altera/dorn.v @@ -618,12 +618,12 @@ module dorn_l1 reg [ND:1] sel; reg [ND:0] ssel; wire [ND:0] ssel1 = 1; + reg doutf, adc_triggered, adc_reading, adc_valid; reg pd, pt; reg [WP-1:0] pptr_w, pptr_rr; wire [WP-1:0] pptr_r = pptr_rr - (doutf|pt); reg [1:0] din_sr; - reg doutf, adc_triggered, adc_reading, adc_valid; reg [2:0] ch_next, ch_reading, ch_valid; reg reqq_hk, starting_hk, doing_hk, hk_reading, hk_valid; reg [4:0] startup_c; @@ -882,6 +882,10 @@ module dorn_l2 dorn_multiply #(.A(NB), .B(NX-1)) m(.a(ff_sample), .b(ff_coeff), .q(qprod)); + reg sstick; + reg f_start, f_nextch, f_next, f_read, f_prod1, f_prod2, f_add, f_summed, e_last, f_lt; + wire f_busy = |{f_start,f_nextch,f_next,f_read,f_add,f_summed,filter_ready,filter_done}; + memDxAre #(.A(WM), .D(NB)) smem (.clk(dclk), .we(p_we & data_e), .wa({p_ptr[WE-1:0], w_addr}), .wd(data), @@ -916,11 +920,6 @@ module dorn_l2 reg htrig; reg [NK-1:0] l2clock, f_clock, fd_clock; - reg sstick; - reg f_start, f_nextch, f_next, f_read, f_prod1, f_prod2, f_add, f_summed, e_last, f_lt; - wire f_busy = |{f_start,f_nextch,f_next,f_read,f_add,f_summed,filter_ready,filter_done}; - - always @(posedge dclk) begin sstick <= stick; diff --git a/irena/altera/ms5540c.v b/irena/altera/ms5540c.v index 82ee5dd7..ec33e473 100644 --- a/irena/altera/ms5540c.v +++ b/irena/altera/ms5540c.v @@ -253,6 +253,7 @@ module ms5540c_sim(MCLK, SCLK, Din, Dout); parameter CONV_TIME = 3; // really about 1150 MCLK cycles integer converting; + reg [15:0] result; always @(posedge MCLK) if (converting) begin @@ -265,7 +266,6 @@ module ms5540c_sim(MCLK, SCLK, Din, Dout); converting <= converting - 1; end - reg [15:0] result; always @(negedge SCLK) begin if (in_sr[2:0] == 'b111) diff --git a/nm64/altera/nmcounter.v b/nm64/altera/nmcounter.v index c4df4f36..1e2699c5 100644 --- a/nm64/altera/nmcounter.v +++ b/nm64/altera/nmcounter.v @@ -185,9 +185,9 @@ module nm_counters reg [A-1:0] wa, pa; reg [A:0] a; reg [D-1:0] id; + reg re, pe, we, ie, ze, pz, wz, se, pss, send, send1; wire [D-1:0] rd; wire [D-1:0] wd = wz ? 0 : id+1; - reg re, pe, we, ie, ze, pz, wz, se, pss, send, send1; reg send_head; reg [2:0] send_clock; reg [15:0] clockh; From 9bbfeb3316098af16370c10355c94ed7ec06f5ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20I=2E=20B=C3=B6ttcher?= Date: Wed, 25 Mar 2026 20:13:30 +0100 Subject: [PATCH 6/6] spi_slave_timeout: support 1024 cycle long timeout --- altera/spi_slave.v | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/altera/spi_slave.v b/altera/spi_slave.v index c1aa4cc5..83a2e070 100644 --- a/altera/spi_slave.v +++ b/altera/spi_slave.v @@ -219,12 +219,20 @@ module spi_slave endmodule // spi_slave -module spi_timeout(mclk, sclk, timeout, ssel); +module spi_timeout + ( + input mclk, sclk, + output timeout, + input ssel + ); - input mclk, sclk; - output timeout; - input ssel; - parameter TIMEOUT = 128; // 1..128 +`ifndef SPI_TIMEOUT_1024 + parameter TIMEOUT=128; +`else + parameter TIMEOUT=1024; +`endif + parameter N = $clog2(TIMEOUT); + parameter M = 1 << N; // frame timeout after 128 mclk cycles without sclk @@ -246,14 +254,14 @@ module spi_timeout(mclk, sclk, timeout, ssel); always @(negedge mclk) sclkn <= {sclk2,sclkn[1]}; - reg [7:0] timeout_counter; - wire timeout = timeout_counter[7]; + reg [N:0] timeout_counter; + assign timeout = timeout_counter[N]; always @(posedge mclk) // if (sclkp != sclkn[1] || sclkn[1] != sclk2) // metastability? if (ssel) - timeout_counter <= 128; + timeout_counter <= M; else if (sclkp != sclkn[1] || sclkp != sclkn[2]) - timeout_counter <= 128-TIMEOUT; + timeout_counter <= M-TIMEOUT; else if(~timeout) timeout_counter <= timeout_counter+1;