From 07f02d3cb847cef4d22aaacd39a4f754801287c2 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Tue, 13 Aug 2024 11:15:40 -0700 Subject: [PATCH 01/75] localbus.vh: convert to non-blocking stimulus .. and fuss a little with timing. Tested, and can work with uspas_llrf. --- localbus/localbus.vh | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/localbus/localbus.vh b/localbus/localbus.vh index 5519ba222..aae1099e5 100644 --- a/localbus/localbus.vh +++ b/localbus/localbus.vh @@ -16,11 +16,13 @@ task lb_write_task ( ); begin @ (posedge lb_clk); - lb_addr = addr; - lb_wdata = data; - lb_write = 1'b1; + lb_addr <= addr; + lb_wdata <= data; + lb_write <= 1'b1; + @ (posedge lb_clk); + lb_write <= 1'b0; + lb_wdata <= {32{1'bx}}; @ (posedge lb_clk); - lb_write = 1'b0; end endtask @@ -30,15 +32,15 @@ task lb_read_task ( ); begin @ (posedge lb_clk); - lb_addr = addr; - lb_read = 1'b1; - // repeat (4 + LB_READ_DELAY) @ (posedge lb_clk); // badger timing - repeat (0 + LB_READ_DELAY) @ (posedge lb_clk); - lb_rvalid = 1'b1; + lb_addr <= addr; + lb_read <= 1'b1; + repeat (1 + LB_READ_DELAY) @ (posedge lb_clk); + lb_rvalid <= 1'b1; + @ (posedge lb_clk); data = lb_rdata; // $display("time: %g Read ack: ADDR 0x%x DATA 0x%x", $time, addr, lb_rdata); + lb_read <= 1'b0; + lb_rvalid <= 1'b0; @ (posedge lb_clk); - lb_read = 1'b0; - lb_rvalid = 1'b0; end endtask From 53e596d1952388dff46092c17282385d81f596ed Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Tue, 13 Aug 2024 21:52:45 -0700 Subject: [PATCH 02/75] newad: Constrain local bus address comparisons to their actual width --- build-tools/newad.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/build-tools/newad.py b/build-tools/newad.py index 03048749c..0139b9bae 100755 --- a/build-tools/newad.py +++ b/build-tools/newad.py @@ -69,7 +69,7 @@ def add_to_global_map(name, base_addr, sign, aw, dw, description): def generate_addresses( - fd, names, base, low_res=False, gen_mirror=False, plot_map=False + fd, names, base, low_res=False, gen_mirror=False, plot_map=False, lb_width=24 ): """ Generate addresses with increasing bitwidth @@ -113,10 +113,13 @@ def generate_addresses( ) mirror_clk_prefix = "lb" # TODO: This is a hack if fd: + # Note the historical, buggy definition of lb_width as one less than + # the actual address bus bit-width. + mirror_pattern = (mirror_base & (2**(lb_width+1)-1)) >> mirror_bit_len s = ( "`define MIRROR_WIDTH %d\n" "`define ADDR_HIT_MIRROR (%s_addr[`LB_HI:`MIRROR_WIDTH]==%d)\n" - % (mirror_bit_len, mirror_clk_prefix, mirror_base >> mirror_bit_len) + % (mirror_bit_len, mirror_clk_prefix, mirror_pattern) ) fd.write(s) sign = gch[k][2] @@ -146,6 +149,9 @@ def generate_addresses( "`define ADDR_HIT_%s (%s_addr%s[`LB_HI:%d]==%d) " "// %s bitwidth: %d, base_addr: %d\n" ) + # Note the historical, buggy definition of lb_width as one less than + # the actual address bus bit-width. + addr_pattern = (next_addr & (2**(lb_width+1)-1)) >> bitwidth fd.write( s % ( @@ -153,7 +159,7 @@ def generate_addresses( gch[k][4], gch[k][5], bitwidth, - next_addr >> bitwidth, + addr_pattern, gch[k][1], bitwidth, next_addr, @@ -179,7 +185,7 @@ def generate_addresses( def address_allocation( - fd, hierarchy, names, address, low_res=False, gen_mirror=False, plot_map=False + fd, hierarchy, names, address, low_res=False, gen_mirror=False, plot_map=False, lb_width=24 ): """ NOTE: The whole hierarchy thing is currently being bypassed @@ -194,7 +200,7 @@ def address_allocation( (b) generate addresses for signals outside the hierarchy (out_mod) """ if hierarchy == len(g_hierarchy): - return generate_addresses(fd, names, address, low_res, gen_mirror, plot_map) + return generate_addresses(fd, names, address, low_res, gen_mirror, plot_map, lb_width) h = g_hierarchy[hierarchy] in_mod, out_mod = [], [] if type(h) is list: @@ -209,15 +215,16 @@ def address_allocation( low_res, gen_mirror, plot_map, + lb_width, ) out_mod = [n for n in names if prefix not in n] else: for n in names: (in_mod if h in n else out_mod).append(n) address = address_allocation( - fd, hierarchy + 1, in_mod, address, low_res, gen_mirror, plot_map + fd, hierarchy + 1, in_mod, address, low_res, gen_mirror, plot_map, lb_width ) - return generate_addresses(fd, out_mod, address, low_res, gen_mirror, plot_map) + return generate_addresses(fd, out_mod, address, low_res, gen_mirror, plot_map, lb_width) from parser import Parser @@ -276,7 +283,7 @@ def write_address_header( addr_bufs = StringIO() addr_bufs.write("`define LB_HI %d\n" % lb_width) address_allocation( - addr_bufs, 0, sorted(gch.keys()), base_addr, low_res, gen_mirror, plot_map + addr_bufs, 0, sorted(gch.keys()), base_addr, low_res, gen_mirror, plot_map, lb_width ) with open(output_file, "w") as fd: fd.write(addr_bufs.getvalue()) @@ -363,7 +370,7 @@ def main(argv): "--lb_width", type=int, default=10, - help="Set the address width of the local bus from which the generated registers are decoded", + help="One less than the address width of the local bus (from which the generated registers are decoded)", ) parser.add_argument( "-b", From f51014a9a3e018a87e3e58a5b2c51b9b7f267561 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Wed, 14 Aug 2024 13:18:03 -0700 Subject: [PATCH 03/75] localbus.vh: add LB_ADW parameterization and start with lb_addr and lb_wdata uninitialized --- localbus/localbus.vh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/localbus/localbus.vh b/localbus/localbus.vh index aae1099e5..c3e3c3013 100644 --- a/localbus/localbus.vh +++ b/localbus/localbus.vh @@ -2,16 +2,17 @@ // see (Memory gateway timing)[]bedrock/badger/doc/mem_gateway.svg] // requires defining: +// localparam LB_ADW = 18; // localparam LB_READ_DELAY = 3; reg lb_write=0, lb_read=0, lb_prefill=0; -reg [17:0] lb_addr=0; -reg [31:0] lb_wdata=0; +reg [LB_ADW-1:0] lb_addr; +reg [31:0] lb_wdata; wire [31:0] lb_rdata; reg lb_rvalid=0; task lb_write_task ( - input [23:0] addr, + input [LB_ADW-1:0] addr, input [31:0] data ); begin @@ -21,13 +22,14 @@ task lb_write_task ( lb_write <= 1'b1; @ (posedge lb_clk); lb_write <= 1'b0; + lb_addr <= {LB_ADW{1'bx}}; lb_wdata <= {32{1'bx}}; @ (posedge lb_clk); end endtask task lb_read_task ( - input [17:0] addr, + input [LB_ADW-1:0] addr, output [31:0] data ); begin From 317c9dc0536c409464f114d63d40187c06810e7b Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Thu, 15 Aug 2024 16:28:06 -0700 Subject: [PATCH 04/75] picorv32.v: adjust timescale to be consistent with all other synthesizable code here Helps get time axis correct for some Verilator simulations No known effect anywhere in Bedrock --- soc/picorv32/gateware/picorv32.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soc/picorv32/gateware/picorv32.v b/soc/picorv32/gateware/picorv32.v index 9206bf4a0..4b569ba5f 100644 --- a/soc/picorv32/gateware/picorv32.v +++ b/soc/picorv32/gateware/picorv32.v @@ -23,7 +23,7 @@ /* verilator lint_off CASEOVERLAP */ /* verilator lint_off CASEINCOMPLETE */ -`timescale 1 ns / 1 ps +`timescale 1 ns / 1 ns // `default_nettype none // `define DEBUGNETS // `define DEBUGREGS From 759c4e89af90958a41b803605f5a75f77144f621 Mon Sep 17 00:00:00 2001 From: sdmurthy Date: Fri, 16 Aug 2024 16:18:18 -0700 Subject: [PATCH 05/75] marble.c: Truely unfreeze SI570 DCO --- board_support/marble_soc/firmware/marble.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board_support/marble_soc/firmware/marble.c b/board_support/marble_soc/firmware/marble.c index c1e1cc949..cca81cb9c 100644 --- a/board_support/marble_soc/firmware/marble.c +++ b/board_support/marble_soc/firmware/marble.c @@ -192,7 +192,7 @@ bool set_si570_info(si570_info_t *info, marble_init_byte_t *p_data) { regmap++; } // Unfreeze DCO - ret &= i2c_write_regs(info->i2c_addr, 137, ®_unfreeze_dco, 1); + ret &= i2c_write_regs(info->i2c_addr, 137, ®_unfreeze_dco, 0); // Assert NewFreq bit ret &= i2c_write_regs(info->i2c_addr, 135, ®_newfreq, 1); return ret; From 61cafae1af04763daf124fe8b6eb9dfe37b17bac Mon Sep 17 00:00:00 2001 From: sdmurthy Date: Fri, 16 Aug 2024 17:21:33 -0700 Subject: [PATCH 06/75] marble.c: Revert to original unfreeze i2c command --- board_support/marble_soc/firmware/marble.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board_support/marble_soc/firmware/marble.c b/board_support/marble_soc/firmware/marble.c index cca81cb9c..c1e1cc949 100644 --- a/board_support/marble_soc/firmware/marble.c +++ b/board_support/marble_soc/firmware/marble.c @@ -192,7 +192,7 @@ bool set_si570_info(si570_info_t *info, marble_init_byte_t *p_data) { regmap++; } // Unfreeze DCO - ret &= i2c_write_regs(info->i2c_addr, 137, ®_unfreeze_dco, 0); + ret &= i2c_write_regs(info->i2c_addr, 137, ®_unfreeze_dco, 1); // Assert NewFreq bit ret &= i2c_write_regs(info->i2c_addr, 135, ®_newfreq, 1); return ret; From d3573397001d1a510e12a1459ae3843cf7505e3c Mon Sep 17 00:00:00 2001 From: Qiang Du Date: Fri, 16 Aug 2024 18:19:52 -0700 Subject: [PATCH 07/75] Include >10ms wait in si570 new freq setting --- board_support/marble_soc/firmware/marble.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/board_support/marble_soc/firmware/marble.c b/board_support/marble_soc/firmware/marble.c index c1e1cc949..21695143c 100644 --- a/board_support/marble_soc/firmware/marble.c +++ b/board_support/marble_soc/firmware/marble.c @@ -2,6 +2,7 @@ #include "i2c_soft.h" #include "sfr.h" #include "xadc.h" +#include "timer.h" #include "localbus.h" #include "settings.h" #include "print.h" @@ -193,6 +194,13 @@ bool set_si570_info(si570_info_t *info, marble_init_byte_t *p_data) { } // Unfreeze DCO ret &= i2c_write_regs(info->i2c_addr, 137, ®_unfreeze_dco, 1); + + // The process of freezing and unfreezing the DCO will + // cause the output clock to momentarily stop and start at + // any arbitrary point during a clock cycle. This process + // can take up to 10 ms. + DELAY_MS(20); + // Assert NewFreq bit ret &= i2c_write_regs(info->i2c_addr, 135, ®_newfreq, 1); return ret; From 4c3b156ab9217f74bbd6081e3dce5a61267be219 Mon Sep 17 00:00:00 2001 From: Qiang Du Date: Mon, 19 Aug 2024 21:31:08 -0700 Subject: [PATCH 08/75] board_support/marble_soc/firmware/marble.c: move si570 20ms waiting after assertion of NewFreq bit. board_support/zest_soc/firmware/zest.c: Fix comment typo, cleanup. --- board_support/marble_soc/firmware/marble.c | 6 +++--- board_support/zest_soc/firmware/zest.c | 19 ++----------------- board_support/zest_soc/firmware/zest.h | 3 +-- 3 files changed, 6 insertions(+), 22 deletions(-) diff --git a/board_support/marble_soc/firmware/marble.c b/board_support/marble_soc/firmware/marble.c index 21695143c..4ffe0d55d 100644 --- a/board_support/marble_soc/firmware/marble.c +++ b/board_support/marble_soc/firmware/marble.c @@ -195,14 +195,14 @@ bool set_si570_info(si570_info_t *info, marble_init_byte_t *p_data) { // Unfreeze DCO ret &= i2c_write_regs(info->i2c_addr, 137, ®_unfreeze_dco, 1); + // Assert NewFreq bit + ret &= i2c_write_regs(info->i2c_addr, 135, ®_newfreq, 1); + // The process of freezing and unfreezing the DCO will // cause the output clock to momentarily stop and start at // any arbitrary point during a clock cycle. This process // can take up to 10 ms. DELAY_MS(20); - - // Assert NewFreq bit - ret &= i2c_write_regs(info->i2c_addr, 135, ®_newfreq, 1); return ret; } diff --git a/board_support/zest_soc/firmware/zest.c b/board_support/zest_soc/firmware/zest.c index a8056cf79..daf60b33e 100644 --- a/board_support/zest_soc/firmware/zest.c +++ b/board_support/zest_soc/firmware/zest.c @@ -232,7 +232,7 @@ bool check_ad9781_bist(void) { SET_SFR1(g_base_sfr, SFR_OUT_REG1, SFR_OUT_BIT_DAC1_ENABLE, 0); pass &= run_ad9781_bist(bitres_exp, 0); - // test case 2: PRBS on dac0, zero on dac1 + // test case 2: PRBS on dac1, zero on dac0 SET_SFR1(g_base_sfr, SFR_OUT_REG1, SFR_OUT_BIT_DAC0_ENABLE, 0); SET_SFR1(g_base_sfr, SFR_OUT_REG1, SFR_OUT_BIT_DAC1_ENABLE, 1); pass &= run_ad9781_bist(0, bitres_exp); @@ -782,26 +782,11 @@ void test_adc_pn9(uint8_t len) { write_zest_reg(ZEST_DEV_AD9653_BOTH, 0x14, 0x07); // two's comp } -bool init_zest_dbg(uint32_t base, zest_init_t *init_data) { +bool init_zest_dbg(uint32_t base) { bool pass=true; // uint32_t fcnt; select_zest_addr(base); - // zest_init_data_t *p_ad9653_data = &(init_data->ad9653_data); - // printf("Reset BUFR 0: "); - // reset_zest_bufr(0); - // printf("Reset BUFR 1: "); - // reset_zest_bufr(1); - // printf("ZEST ADC init : "); - // write_zest_regs(ZEST_DEV_AD9653_BOTH, p_ad9653_data->regmap, p_ad9653_data->len); - - // test_adc_pn9(8); - // check_adc_prbs9(); - // align_ad9781(12); - // uint32_t *fcnt_exp = init_data->fcnt_exp; - // check_zest_freq(0, fcnt_exp[0]); - // fcnt = read_zest_fcnt(0); - // print_udec_fix(fcnt*125, FCNT_WIDTH, 3); check_ad9781_bist(); return pass; } diff --git a/board_support/zest_soc/firmware/zest.h b/board_support/zest_soc/firmware/zest.h index 14fbe777e..e7ce1bac9 100644 --- a/board_support/zest_soc/firmware/zest.h +++ b/board_support/zest_soc/firmware/zest.h @@ -282,9 +282,8 @@ bool check_ad9781_bist(void); /***************************************************************************//** * @brief Test function. * @param base - base address - * @param zest_init_data - pointer to init register data. * @return pass - true if all validation passes *******************************************************************************/ -bool init_zest_dbg(uint32_t base, zest_init_t *init_data); +bool init_zest_dbg(uint32_t base); #endif From 687c75100ded331ee0584c1ed7671f031ad4f441 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Tue, 20 Aug 2024 15:19:23 -0700 Subject: [PATCH 09/75] dsp/digaree/detune_coeff_calc.py: adapt to SciPy 1.13 and higher They removed scipy.signal.bspline This version switches to scipy.interpolate.BSpline Still tested as working with scipy at least s old as SciPy 1.6.0 --- dsp/digaree/detune_coeff_calc.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/dsp/digaree/detune_coeff_calc.py b/dsp/digaree/detune_coeff_calc.py index d52a47164..dcf5ba286 100644 --- a/dsp/digaree/detune_coeff_calc.py +++ b/dsp/digaree/detune_coeff_calc.py @@ -1,6 +1,6 @@ import numpy as np from numpy import sqrt, arctan2, exp, mean, std, pi, zeros, hstack, vstack, arange, diff, linalg -from scipy import signal +from scipy.interpolate import BSpline from matplotlib import pyplot @@ -196,16 +196,24 @@ class detune_pulse(digaree_coeff): """ Cardinal B-spline https://en.wikipedia.org/wiki/B-spline Same as the output of a second-order CIC interpolator + Bespoke wrapper as drop-in for the old scipy.signal.bspline, + which was removed in SciPy 1.13. """ + def bspline(self, x, n): + knots = np.arange(-(n+1)/2, (n+3)/2) + out = BSpline.basis_element(knots)(x) + out[(x < knots[0]) | (x > knots[-1])] = 0.0 + return out + def create_basist(self, block=15, n=10): npt = (n-1)*block+1 basist = zeros([npt, n]) x = arange(npt)/float(block) for jx in range(n): - basist[:, jx] = signal.bspline(x-jx, 2) + basist[:, jx] = self.bspline(x-jx, 2) # end-effects, it's important that the sum is flat - basist[:, 0] += signal.bspline(x+1, 2) - basist[:, n-1] += signal.bspline(x-n, 2) + basist[:, 0] += self.bspline(x+1, 2) + basist[:, n-1] += self.bspline(x-n, 2) return basist # basist is n*m, where n=len(cav)-1, m is number of time-dependent bases From 0828286201d266fd10f3b36737d3d5dcc16002f7 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Tue, 20 Aug 2024 17:46:23 -0700 Subject: [PATCH 10/75] wfm_tb.v: only generate test pattern when waveform is counting Otherwise results depend on software-defined arrival time of WFM_CFG_BYTE_TRIG Caused breakage when moving from gcc 12.2.0 to 13.2.0 --- soc/picorv32/test/wfm/wfm_tb.v | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/soc/picorv32/test/wfm/wfm_tb.v b/soc/picorv32/test/wfm/wfm_tb.v index ee2daedd8..0cb4d73de 100644 --- a/soc/picorv32/test/wfm/wfm_tb.v +++ b/soc/picorv32/test/wfm/wfm_tb.v @@ -93,7 +93,7 @@ module wfm_tb; // N_CH=2, CH1: 16'hdead, CH0: 16'beaf reg [31:0] adc_out_data= {16'hdead, 16'hbeaf}; always @(posedge dsp_clk) begin - adc_out_data <= ~adc_out_data; + if (dut.counting) adc_out_data <= ~adc_out_data; end // -------------------------------------------------------------- // wfm_pack module @@ -123,8 +123,8 @@ module wfm_tb; // Read CH1 and check data // wfm.c: SET_REG8(config_addr + WFM_CFG_BYTE_CHAN_SEL, 1); always @(posedge mem_clk) if (mem_read_stb) begin - if (v_addr % 2 == 0) pass &= (v_rdata == ~16'hdead); - if (v_addr % 2 == 1) pass &= (v_rdata == 16'hdead); + if (v_addr % 2 == 0) pass &= (v_rdata == 16'hdead); + if (v_addr % 2 == 1) pass &= (v_rdata == ~16'hdead); $display("Time: %g ns: addr: 0x%x, data : 0x%x %s\n", $time, v_addr, v_rdata, pass ? "PASS":"FAIL"); end endmodule From e917542b759644e05ce73b95419d347ff81754ce Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Tue, 20 Aug 2024 18:05:16 -0700 Subject: [PATCH 11/75] udp_model.c: give gcc-14.2 one less thing to complain about Interchange order of arguments to calloc() --- badger/tests/udp_model.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/badger/tests/udp_model.c b/badger/tests/udp_model.c index 41b1fa89f..a3cb26a3d 100644 --- a/badger/tests/udp_model.c +++ b/badger/tests/udp_model.c @@ -110,7 +110,7 @@ void udp_receiver(int *in_octet, int *in_valid, int *in_count, int thinking) struct udp_state *udp_setup_r(unsigned short udp_port_, int badger_client_) { - struct udp_state *ust = US_P calloc(sizeof (struct udp_state), 1); + struct udp_state *ust = US_P calloc(1, sizeof (struct udp_state)); ust->sleepctr=0; ust->sleepmax=10; fprintf(stderr, "udp_receiver initializing UDP port %u. Interface mode: ", udp_port_); @@ -121,8 +121,8 @@ struct udp_state *udp_setup_r(unsigned short udp_port_, int badger_client_) } ust->badger_client = badger_client_; /* following could be combined by making second argument to calloc a 2? */ - struct pbuf *inbuf = ust->inbuf = PBUF_P calloc(sizeof(struct pbuf), 1); - struct pbuf *outbuf = ust->outbuf = PBUF_P calloc(sizeof(struct pbuf), 1); + struct pbuf *inbuf = ust->inbuf = PBUF_P calloc(1, sizeof(struct pbuf)); + struct pbuf *outbuf = ust->outbuf = PBUF_P calloc(1, sizeof(struct pbuf)); if (!inbuf || !outbuf) { perror("calloc"); exit(1); From 7c1a46b17eb7c24af1177a3b6cdc039085c34c52 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Fri, 23 Aug 2024 08:02:47 -0700 Subject: [PATCH 12/75] reverse_json.py: more flexible recognition of parameters --- build-tools/reverse_json.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/build-tools/reverse_json.py b/build-tools/reverse_json.py index e4c15e012..f3bf2db4d 100644 --- a/build-tools/reverse_json.py +++ b/build-tools/reverse_json.py @@ -14,6 +14,7 @@ addr_found = {} name_found = {} fail = 0 +verbose = False # can we have a command-line switch to control this? # Bugs: # brittle to variations in Verilog code formatting @@ -117,7 +118,8 @@ def memorize(g): alias = None m1a = re.search(r";\s*//\s*alias:\s*(\w+)", line) if m1a: - # stderr.write('INFO: alias "%s"\n' % m1a.group(1)) + if verbose: + stderr.write('INFO: alias "%s"\n' % m1a.group(1)) alias = m1a.group(1) tbank = m1.group(2) if bank_state == "=armed=": @@ -131,7 +133,8 @@ def memorize(g): if "default" in line and ": reg_bank_" in line: m1 = re.search(r"default:\s*reg_bank_(\w)\s*<=\s*32'h", line) if m1: - # stderr.write('INFO: default %s\n' % line) + if verbose: + stderr.write('INFO: default %s\n' % line) tbank = m1.group(1) if bank_state != tbank: stderr.write(ehead + ' bank %s assignment found in bank %s stanza\n' % (tbank, bank_state)) @@ -149,11 +152,21 @@ def memorize(g): if m2: memorize(m2.group) if any(x in line for x in ["parameter", "localparam"]): - m3 = re.search(r"\b(?:parameter|localparam)\s+(\w+)\s*=\s*(\d+);", line) + # This logic can handle parameter as a statement, or in the header of a module. + # It does get tripped up by the _last_ parameter of a module, + # that doesn't have a trailing comma. + m3 = re.search(r"\b(?:parameter|localparam)\s+(\w+)\s*=\s*(\d+)[;,]", line) if m3: p, v = m3.group(1), int(m3.group(2)) param_db[p] = v - # stderr.write('INFO: found parameter "%s" with value %d\n' % (p, v)) + if verbose: + stderr.write('INFO: found parameter "%s" with value %d\n' % (p, v)) + m3 = re.search(r"\b(?:parameter|localparam)\s+integer\s+(\w+)\s*=\s*(\d+)[;,]", line) + if m3: + p, v = m3.group(1), int(m3.group(2)) + param_db[p] = v + if verbose: + stderr.write('INFO: found parameter "%s" with value %d\n' % (p, v)) if "endcase" in line: bank_state = None if "case" in line and "addr" in line: From 8ff9ed68ae823845f0fa3237f086ed753b74d5c1 Mon Sep 17 00:00:00 2001 From: Qiang Du Date: Fri, 23 Aug 2024 09:49:53 -0700 Subject: [PATCH 13/75] Add litex tag 2023.08 in litex_meta.sh --- build-tools/litex_meta.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-tools/litex_meta.sh b/build-tools/litex_meta.sh index bbe4ec452..f5ba9feac 100644 --- a/build-tools/litex_meta.sh +++ b/build-tools/litex_meta.sh @@ -27,5 +27,5 @@ echo "d77081080f0c5109adc92d2730145228cb19633de7f2ff50ca3a4ec0cb341532 litex_se # Now that we're quite sure we have the litex_setup we want, # go ahead and run it. -python3 litex_setup.py init install --config standard +python3 litex_setup.py --init --update --tag 2023.08 --install --config standard echo "DONE" From 9b63f2c68db00e4ef560b7a056cb14714f382ae4 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Sat, 24 Aug 2024 13:31:31 -0700 Subject: [PATCH 14/75] Slight reformatting of some python source to pass flake8 E124 E128 --- build-tools/build_rom.py | 12 ++--- build-tools/tblint.py | 2 +- peripheral_drivers/i2cbridge/assem.py | 18 +++++--- projects/test_marble_family/logpath.py | 6 ++- projects/trigger_capture/capture.py | 2 +- projects/trigger_capture/data_pipe.py | 51 +++++++++++----------- projects/trigger_capture/firmware/build.py | 5 ++- projects/trigger_capture/marble.py | 3 +- projects/trigger_capture/targets/marble.py | 3 +- tox.ini | 2 +- 10 files changed, 57 insertions(+), 47 deletions(-) diff --git a/build-tools/build_rom.py b/build-tools/build_rom.py index 5805803ae..595a6b8da 100644 --- a/build-tools/build_rom.py +++ b/build-tools/build_rom.py @@ -96,7 +96,8 @@ def verilog_rom(a, suffix="", prefix=""): '''\t%i'h%3.3x: dxx <= 16'h%4.4x;''' % (max_addr_size+1, ix, a[ix]) for ix in range(len(a)) ]) - outputMessage = ("// 16k x 16 ROM machine generated by python verilog_rom()", + outputMessage = ( + "// 16k x 16 ROM machine generated by python verilog_rom()", "module {}config_romx{}(".format(prefix, suffix), "\tinput clk,", "\tinput [" + str(max_addr_size) + ":0] address,", @@ -109,8 +110,7 @@ def verilog_rom(a, suffix="", prefix=""): "\tdefault: dxx <= 0;", "endcase", "endmodule", - "" - ) + "") return '\n'.join(outputMessage) @@ -126,13 +126,13 @@ def c_rom(a, suffix="", prefix=""): d_list = ["0x%4.4x" % d for d in a] d_list2 = [", ".join(d_list[ix*8:ix*8+8]) for ix in range((len(a)+7)//8)] config_data = " " + ",\n ".join(d_list2) - outputMessage = ("// 16k x 16 ROM machine generated by python c_rom()", + outputMessage = ( + "// 16k x 16 ROM machine generated by python c_rom()", "static uint16_t config_romx[] = {", config_data, "};", "#define CONFIG_ROM_SIZE (%s)" % (2**max_addr_size), - "" - ) + "") return '\n'.join(outputMessage) diff --git a/build-tools/tblint.py b/build-tools/tblint.py index 8fb61ed05..4e993e718 100644 --- a/build-tools/tblint.py +++ b/build-tools/tblint.py @@ -252,7 +252,7 @@ def testMatch(argv): def doLint(argv): USAGE = ("python3 {0} filename\n" + - " Use python3 {0} --selftest to run regex syntax tests").format(argv[0]) + " Use python3 {0} --selftest to run regex syntax tests").format(argv[0]) if len(argv) < 2: print(USAGE) print(SYNTAX_RULES) diff --git a/peripheral_drivers/i2cbridge/assem.py b/peripheral_drivers/i2cbridge/assem.py index 8333ad80a..0f1df6501 100644 --- a/peripheral_drivers/i2cbridge/assem.py +++ b/peripheral_drivers/i2cbridge/assem.py @@ -211,21 +211,24 @@ def _get_next_instruction(cls, prog_iter): try: data.append(next(prog_iter)) except StopIteration: - raise I2C_Assembler_Exception("Corrupted program detected. " + + raise I2C_Assembler_Exception( + "Corrupted program detected. " + "Program terminates before read (rd) instruction is completed") elif op_code == cls.o_wr: for n in range(n_code): try: data.append(next(prog_iter)) except StopIteration: - raise I2C_Assembler_Exception("Corrupted program detected. " + + raise I2C_Assembler_Exception( + "Corrupted program detected. " + "Program terminates before write (wr) instruction is completed") elif op_code == cls.o_wx: for n in range(n_code): try: data.append(next(prog_iter)) except StopIteration: - raise I2C_Assembler_Exception("Corrupted program detected. " + + raise I2C_Assembler_Exception( + "Corrupted program detected. " + "Program terminates before write-multi (wx) instruction is completed") # All other op_code values have no data return (op_code, n_code, data) @@ -249,7 +252,8 @@ def prnt(*args, **kwargs): while rval is not None: op_code, n_code, data = rval if loop_end: # Should not be any code after a backwards jump - raise I2C_Assembler_Exception(f"Instruction [{op_code:03b}:{n_code:05b}] " + + raise I2C_Assembler_Exception( + f"Instruction [{op_code:03b}:{n_code:05b}] " + f"at address {pc} is unreachable.") if op_code == self.o_oo: if n_code == self.n_oo_bf: # buffer_flip @@ -279,14 +283,16 @@ def prnt(*args, **kwargs): if backwards_jumped: prnt(f" After a backwards jump (srx_after_jump = {srx_after_jump})") if not srx_after_jump: - raise I2C_Assembler_Exception(f"Program address 0x{pc:03x}: Must use set_resx() after " + + raise I2C_Assembler_Exception( + f"Program address 0x{pc:03x}: Must use set_resx() after " + "a backwards jump before any read operations for consistent address of results.") pc = iprog.tell() prnt(f"pc = {pc:03x}") rval = self._get_next_instruction(iprog) if has_read and not has_buffer_flip: if not self._advanced_mode: - raise I2C_Assembler_Exception("Program has read operation but no buffer flip found." + + raise I2C_Assembler_Exception( + "Program has read operation but no buffer flip found." + " Result buffer is unreadable. Use 'advanced mode' to suppress this exception.") prnt("Program good") return diff --git a/projects/test_marble_family/logpath.py b/projects/test_marble_family/logpath.py index bf15fb654..86ffbaad4 100644 --- a/projects/test_marble_family/logpath.py +++ b/projects/test_marble_family/logpath.py @@ -52,10 +52,12 @@ def main(args): import argparse parser = argparse.ArgumentParser(description="Marble test data log file path exporter") parser.add_argument("serial_number", help="Marble board serial number") - parser.add_argument('-b', '--base', default=None, + parser.add_argument( + '-b', '--base', default=None, help="Base logfile directory (attempts to use $MARBLE_LOGPATH by default)") parser.add_argument('-v', '--version', default=None, help="Marble board version (e.g. 1.2, 1.3, 1.4, 1.4.1, etc)") - parser.add_argument('-a', '--absolute', default=False, action="store_true", + parser.add_argument( + '-a', '--absolute', default=False, action="store_true", help="Return an absolute path instead of a relative one.") args = parser.parse_args() import sys diff --git a/projects/trigger_capture/capture.py b/projects/trigger_capture/capture.py index 129d9db4a..e0e30cd26 100644 --- a/projects/trigger_capture/capture.py +++ b/projects/trigger_capture/capture.py @@ -15,7 +15,7 @@ def trigger_hardware(n_points, cap_ip, cap_port, - csr_csv = None): + csr_csv = None): wb = RemoteClient(csr_csv=csr_csv) wb.open() diff --git a/projects/trigger_capture/data_pipe.py b/projects/trigger_capture/data_pipe.py index 04d1d6fd0..e167d67f8 100644 --- a/projects/trigger_capture/data_pipe.py +++ b/projects/trigger_capture/data_pipe.py @@ -37,7 +37,8 @@ def udp_fragmenter_description(dw): class UDPFragmenterPacketizer(Packetizer): def __init__(self, dw=8): - Packetizer.__init__(self, + Packetizer.__init__( + self, udp_fragmenter_description(dw), eth_udp_user_description(dw), fragmenter_header) @@ -82,10 +83,10 @@ def __init__(self, dw=8): counter_ce = Signal() self.sync += \ If(counter_reset, - counter.eq(0) - ).Elif(counter_ce, - counter.eq(counter + ww) - ) + counter.eq(0) + ).Elif(counter_ce, + counter.eq(counter + ww) + ) bytes_in_fragment = Signal(16, reset=0) self.submodules.fsm = fsm = FSM(reset_state="IDLE") @@ -96,7 +97,7 @@ def __init__(self, dw=8): sink.connect(packetizer.sink, omit={"length"}), # TODO source.length.eq(sink.length) - ).Else( + ).Else( sink.ready.eq(0), source.length.eq(UDP_FRAG_MTU + 8), counter_reset.eq(1), @@ -107,8 +108,8 @@ def __init__(self, dw=8): NextValue(bytes_in_fragment, UDP_FRAG_MTU), NextState("FRAGMENTED_PACKET_SEND") ) + ) ) - ) fsm.act("FRAGMENTED_PACKET_SEND", sink.connect(packetizer.sink, omit={"length"}), @@ -116,7 +117,7 @@ def __init__(self, dw=8): source.length.eq(bytes_in_fragment + 8), If(sink.valid & packetizer.sink.ready, counter_ce.eq(1) - ), + ), If(counter == (bytes_in_fragment - ww), NextValue(fragment_offset, fragment_offset + (bytes_in_fragment >> 3)), @@ -124,11 +125,11 @@ def __init__(self, dw=8): If(((fragment_offset << 3) + counter + ww) == sink.length, NextValue(fragment_offset, 0), NextState("IDLE") - ).Else( + ).Else( counter_ce.eq(0), NextState("NEXT_FRAGMENT")) + ) ) - ) fsm.act("NEXT_FRAGMENT", counter_ce.eq(0), @@ -139,14 +140,14 @@ def __init__(self, dw=8): counter_reset.eq(1), If((sink.length - (fragment_offset << 3)) > UDP_FRAG_MTU, NextValue(bytes_in_fragment, UDP_FRAG_MTU), - ).Else( + ).Else( NextValue(bytes_in_fragment, sink.length - (fragment_offset << 3)), NextValue(mf, 0), ), NextValue(fragment_id, fragment_id + 1), NextState("FRAGMENTED_PACKET_SEND") - ) + ) class Counter(Module): @@ -206,7 +207,7 @@ def __init__(self, ddr_wr_port, ddr_rd_port, udp_port, adc_source, adc_dw): If(adc_source.valid, adc_data.eq(Cat(adc_data[adc_dw:], adc_source.data)), word_count.eq(word_count + 1) - ), + ), word_count_d.eq(word_count), ] @@ -221,16 +222,16 @@ def __init__(self, ddr_wr_port, ddr_rd_port, udp_port, adc_source, adc_dw): If(self.fifo_load.re & self.fifo_load.storage, fifo_counter.eq(0), load_fifo.eq(1) - ), + ), If(load_fifo & adc_source.valid, self.fifo_full.status.eq(0), self.fifo_error.status.eq(~dram_fifo.dram_fifo.ctrl.writable), fifo_counter.eq(fifo_counter + 1) - ), + ), If((fifo_counter == fifo_size - 1) & adc_source.valid, load_fifo.eq(0), self.fifo_full.status.eq(1) - ), + ), ] # fifo --> stride converter @@ -244,9 +245,9 @@ def __init__(self, ddr_wr_port, ddr_rd_port, udp_port, adc_source, adc_dw): self.sync += [ If(dram_fifo.source.valid & dram_fifo.source.ready, receive_count.eq(receive_count + 1) - ).Elif(read_from_dram_fifo == 0, - receive_count.eq(0) - ) + ).Elif(read_from_dram_fifo == 0, + receive_count.eq(0) + ) ] # --> udp fragmenter --> self.submodules.udp_fragmenter = udp_fragmenter = UDPFragmenter(udp_port.dw) @@ -315,16 +316,16 @@ def __init__(self, ddr_wr_port, ddr_rd_port, udp_port): If(self.fifo_load.re & self.fifo_load.storage, fifo_counter.eq(0), load_fifo.eq(1) - ), + ), If(load_fifo & adcs.source.valid, self.fifo_full.status.eq(0), self.fifo_error.status.eq(~dram_fifo.dram_fifo.ctrl.writable), fifo_counter.eq(fifo_counter + 1) - ), + ), If((fifo_counter == fifo_size - 1) & adcs.source.valid, load_fifo.eq(0), self.fifo_full.status.eq(1) - ), + ), ] self.comb += [ @@ -344,9 +345,9 @@ def __init__(self, ddr_wr_port, ddr_rd_port, udp_port): self.sync += [ If(dram_fifo.source.valid & dram_fifo.source.ready, receive_count.eq(receive_count + 1) - ).Elif(read_from_dram_fifo == 0, - receive_count.eq(0) - ) + ).Elif(read_from_dram_fifo == 0, + receive_count.eq(0) + ) ] # --> udp fragmenter --> self.submodules.udp_fragmenter = udp_fragmenter = UDPFragmenter(udp_port.dw) diff --git a/projects/trigger_capture/firmware/build.py b/projects/trigger_capture/firmware/build.py index 161cf9bc4..0131f1498 100755 --- a/projects/trigger_capture/firmware/build.py +++ b/projects/trigger_capture/firmware/build.py @@ -26,8 +26,9 @@ def main(): # Compile app build_path = args.build_path if os.path.isabs(args.build_path) else os.path.join("..", args.build_path) print(args.app_dir_path) - os.system(f"export BUILD_DIR={build_path} && export APP_DIR={args.app_dir_path} &&" + - "{'export WITH_CXX=1 &&' if args.with_cxx else ''} cd build && make") + os.system( + f"export BUILD_DIR={build_path} && export APP_DIR={args.app_dir_path} &&" + + "{'export WITH_CXX=1 &&' if args.with_cxx else ''} cd build && make") # Copy demo.bin os.system("cp build/app.bin ./") diff --git a/projects/trigger_capture/marble.py b/projects/trigger_capture/marble.py index 3d0a77864..8d36dd687 100644 --- a/projects/trigger_capture/marble.py +++ b/projects/trigger_capture/marble.py @@ -66,8 +66,7 @@ def add_zest(self): self.platform.lookup_request("ZEST_CLK_TO_FPGA", 1, loose=True).p, self.platform.lookup_request("ZEST_ADC_DCO", 0, loose=True).p, self.platform.lookup_request("ZEST_ADC_DCO", 1, loose=True).p, - self.platform.lookup_request("ZEST_DAC_DCO", loose=True).p - ) + self.platform.lookup_request("ZEST_DAC_DCO", loose=True).p) # self.dsp_clk_out = Signal() # self.clk_div_out = Signal(2) diff --git a/projects/trigger_capture/targets/marble.py b/projects/trigger_capture/targets/marble.py index 11ca96ca3..397b36b36 100644 --- a/projects/trigger_capture/targets/marble.py +++ b/projects/trigger_capture/targets/marble.py @@ -102,7 +102,8 @@ def __init__( platform = marble.Platform() # SoCCore ---------------------------------------------------------------------------------- - SoCCore.__init__(self, platform, sys_clk_freq, + SoCCore.__init__( + self, platform, sys_clk_freq, ident = "LiteX SoC on Marble", **kwargs) diff --git a/tox.ini b/tox.ini index 0a22e8f3b..75250160d 100644 --- a/tox.ini +++ b/tox.ini @@ -1,3 +1,3 @@ [flake8] -ignore=E402,E226,W503,W504,E124,E128,E221,E241,E251 +ignore=E402,E226,W503,W504,E221,E241,E251 max-line-length=120 From cf6c0fdd6b82e2e93159835290f6440c2b75af61 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Wed, 28 Aug 2024 13:48:15 -0700 Subject: [PATCH 15/75] Move TinyEVG.html to its proper location in serial_io/EVG_EVR --- {dsp => serial_io/EVG_EVR}/TinyEVG.html | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {dsp => serial_io/EVG_EVR}/TinyEVG.html (100%) diff --git a/dsp/TinyEVG.html b/serial_io/EVG_EVR/TinyEVG.html similarity index 100% rename from dsp/TinyEVG.html rename to serial_io/EVG_EVR/TinyEVG.html From d8a1d1149676059144bf03062aa5ddb12def8966 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Fri, 30 Aug 2024 09:17:59 -0700 Subject: [PATCH 16/75] marble.c and marble.h: don't use raw Unicode in C source Represent Unicode MICRO SIGN with the standard ASCII C string "\u00b5" --- board_support/marble_soc/firmware/marble.c | 14 ++++++++------ board_support/marble_soc/firmware/marble.h | 6 +++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/board_support/marble_soc/firmware/marble.c b/board_support/marble_soc/firmware/marble.c index 4ffe0d55d..2b61e225f 100644 --- a/board_support/marble_soc/firmware/marble.c +++ b/board_support/marble_soc/firmware/marble.c @@ -113,15 +113,15 @@ void get_qsfp_info(qsfp_info_t *qsfp_param) { qsfp_param->voltage = (int16_t)(buf[0] << 8 | buf[1]) / 10; // mV marble_i2c_read(qsfp_param->i2c_addr, 42, buf, 8); for (i=0; i < 4; i++) { - qsfp_param->bias_current[i] = (int16_t)(buf[2*i] << 8 | buf[2*i+1]) * 2; // µA + qsfp_param->bias_current[i] = (int16_t)(buf[2*i] << 8 | buf[2*i+1]) * 2; // microA } marble_i2c_read(qsfp_param->i2c_addr, 50, buf, 8); for (i=0; i < 4; i++) { - qsfp_param->tx_power[i] = (int16_t)(buf[2*i] << 8 | buf[2*i+1]) / 10; // µW + qsfp_param->tx_power[i] = (int16_t)(buf[2*i] << 8 | buf[2*i+1]) / 10; // microW } marble_i2c_read(qsfp_param->i2c_addr, 34, buf, 8); for (i=0; i < 4; i++) { - qsfp_param->rx_power[i] = (int16_t)(buf[2*i] << 8 | buf[2*i+1]) / 10; // µW + qsfp_param->rx_power[i] = (int16_t)(buf[2*i] << 8 | buf[2*i+1]) / 10; // microW } } @@ -283,6 +283,8 @@ void print_marble_status(void) { printf(" %s: I0 : %#12X\n",__func__, pca9555[i].i0_val); printf(" %s: I1 : %#12X\n",__func__, pca9555[i].i1_val); } +// MICRO SIGN https://en.wikipedia.org/wiki/%CE%9C#Character_encodings +#define MICRO "\u00b5" for (unsigned i=0; i<2; i++) { if (qsfp[i].module_present) { printf(" %s: QSFP%1u Vendor : %.16s\n", __func__, i+1, qsfp[i].vendor_name); @@ -292,11 +294,11 @@ void print_marble_status(void) { printf(" %s: QSFP%1u Temp : %8d C\n", __func__, i+1, qsfp[i].temperature); printf(" %s: QSFP%1u Volt : %8d mV\n", __func__, i+1, qsfp[i].voltage); for (unsigned j=0; j < 4; j++) { - printf(" %s: QSFP%1u TxBias %u: %8d µA\n", __func__, + printf(" %s: QSFP%1u TxBias %u: %8d " MICRO "A\n", __func__, i+1, j, qsfp[i].bias_current[j]); - printf(" %s: QSFP%1u TxPwr %u: %8d µW\n", __func__, + printf(" %s: QSFP%1u TxPwr %u: %8d " MICRO "W\n", __func__, i+1, j, qsfp[i].tx_power[j]); - printf(" %s: QSFP%1u RxPwr %d: %8u µW\n", __func__, + printf(" %s: QSFP%1u RxPwr %d: %8u " MICRO "W\n", __func__, i+1, j, qsfp[i].rx_power[j]); } } diff --git a/board_support/marble_soc/firmware/marble.h b/board_support/marble_soc/firmware/marble.h index fce2be748..3c37e5d3b 100644 --- a/board_support/marble_soc/firmware/marble.h +++ b/board_support/marble_soc/firmware/marble.h @@ -106,11 +106,11 @@ typedef struct qsfp_info_t { int16_t temperature; /** Internally measured voltage, LSB 0.1 mV. Page 00h Byte 26-27 */ uint16_t voltage; - /** Tx bias current, LSB 2 µA, Page 00h Byte 42-49 */ + /** Tx bias current, LSB 2 microA, Page 00h Byte 42-49 */ uint16_t bias_current[4]; - /** Rx power, LSB 0.1 µW, Page 00h Byte 34-41 */ + /** Rx power, LSB 0.1 microW, Page 00h Byte 34-41 */ uint16_t rx_power[4]; - /** Tx power, LSB 0.1 µW, Page 00h Byte 50-57 */ + /** Tx power, LSB 0.1 microW, Page 00h Byte 50-57 */ uint16_t tx_power[4]; /** Page 00h Byte 148-163 */ unsigned char vendor_name[16]; From 0689723606282cd12cc09951352d2e928ec8d027 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Fri, 30 Aug 2024 13:35:59 -0700 Subject: [PATCH 17/75] picorv32 bootloader.S: add "q" option to bypass boot delay --- soc/picorv32/common/bootloader.S | 3 +++ 1 file changed, 3 insertions(+) diff --git a/soc/picorv32/common/bootloader.S b/soc/picorv32/common/bootloader.S index 65a48fb64..f2eda7028 100644 --- a/soc/picorv32/common/bootloader.S +++ b/soc/picorv32/common/bootloader.S @@ -4,6 +4,7 @@ #---------------------------- # send: "ok\n" # receive: "g" Wait max. BOOTLOADER_DELAY cycles, then jump into user app +# (or receive "q" and jump without delay to user app) # send: "o\n" # receive: N = number of bytes to write to mem # receive: ... Receive data and write it to mem starting at _startup_adr @@ -39,12 +40,14 @@ start_bootloader: # Wait for start character li t0, 'g' # the start char. to wait for + li t4, 'q' # the abort char., also to wait for li t1, 0 # t1 = 0, timeout counter li t2, BOOTLOADER_DELAY# t2 max. timeout count wait_loop: bgeu t1, t2, finished # if( t1 > max. timeout ) goto finished addi t1, t1, 1 # t1++ lw t3, 0x08(gp) # Get character from UART into t3 + beq t3, t4, finished # skip the timeout bne t3, t0, wait_loop # check t3 != 'g' # When we are here, we have received 'g' and not timed out From 58893b3f358ca9cdfcd7b36f1856831941257976 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Fri, 30 Aug 2024 18:11:45 -0700 Subject: [PATCH 18/75] cmoc: recover a possibly working cryomodule_badger_tb --- cmoc/Makefile | 9 ++++++++- cmoc/cryomodule_badger.v | 6 ++++-- cmoc/cryomodule_badger_tb.v | 5 +++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/cmoc/Makefile b/cmoc/Makefile index 09aed6662..072bb162c 100644 --- a/cmoc/Makefile +++ b/cmoc/Makefile @@ -1,6 +1,7 @@ include ../dir_list.mk vpath %.v $(RTSIM_DIR) $(DSP_DIR) $(DSP_DIR)/hosted $(BADGER_DIR) +vpath %.c ../badger/tests .PHONY: all all: targets @@ -56,7 +57,12 @@ $(AUTOGEN_DIR)/config_romx.v: VFLAGS_DEP += -y $(BADGER_DIR) -cryomodule_badger_tb.v: $(RTEFI_V) $(AUTOGEN_DIR)/config_romx.v cordicg_b22.v cryomodule_auto +VFLAGS_cryomodule_badger_tb = -m ./tap-vpi + +cryomodule_badger_tb: $(RTEFI_V) $(AUTOGEN_DIR)/config_romx.v cordicg_b22.v cryomodule_auto tap-vpi.vpi + +CFLAGS_tap-vpi.o = $(VPI_CFLAGS) -D_POSIX_C_SOURCE=200809L +tap-vpi.vpi: ethernet_model.o tap_alloc.o crc32.o CLEAN += $(RTEFI_CLEAN) @@ -82,6 +88,7 @@ endif # endif CLEAN += $(TGT_) $(CHK_) *.bit *.in *.vcd +CLEAN += *.o tap-vpi.vpi CLEAN += fdbk_core*.dat lim_step_file_in.dat setmp_step_file_in.dat cryomodule_in.dat cryomodule_p.dat cryomodule.dat $(RTEFI_CLEAN) CLEAN_DIRS += _xilinx include $(BUILD_DIR)/bottom_rules.mk diff --git a/cmoc/cryomodule_badger.v b/cmoc/cryomodule_badger.v index 8c2d5fd44..21b449f36 100644 --- a/cmoc/cryomodule_badger.v +++ b/cmoc/cryomodule_badger.v @@ -14,7 +14,8 @@ module cryomodule_badger ( // Ethernet configuration port input eth_cfg_clk, input [9:0] eth_cfg_set, - output [7:0] eth_status + output [7:0] eth_status, + output thinking ); parameter ip ={8'd192, 8'd168, 8'd7, 8'd4}; @@ -58,10 +59,11 @@ rtefi_blob #(.ip(ip), .mac(mac)) badger( .p3_control_rd(rtefi_lb_control_rd), .p3_control_rd_valid(rtefi_lb_control_rd_valid), .p3_data_out(rtefi_lb_data_out), - .p3_data_in(rtefi_lb_data_in) + .p3_data_in(rtefi_lb_data_in), // // Dumb stuff to get LEDs blinking // output rx_mon, // output tx_mon, + .in_use(thinking) ); diff --git a/cmoc/cryomodule_badger_tb.v b/cmoc/cryomodule_badger_tb.v index 8f95d2002..797c73885 100644 --- a/cmoc/cryomodule_badger_tb.v +++ b/cmoc/cryomodule_badger_tb.v @@ -3,7 +3,7 @@ module cryomodule_badger_tb; // based mostly on aggregate_tb.v -parameter [31:0] ip = 32'd3232237316; // 192.168.7.4 +parameter [31:0] ip = {8'd192, 8'd168, 8'd7, 8'd4}; // 192.168.7.4 parameter [47:0] mac = 48'h112233445566; // Buffer memory to hold a packet read from a file @@ -40,6 +40,7 @@ reg [7:0] eth_in=0, eth_in_=0; reg eth_in_s=0, eth_in_s_=0; wire [7:0] eth_out; wire eth_out_s; +wire thinking; // hook to make things run efficiently reg eth_out_s1=0, ok_to_print=1; integer ci; @@ -48,7 +49,7 @@ always @(posedge clk) begin ci = cc % (data_len+150); if (use_tap) begin // Access to Linux tap interface, see tap-vpi.c - if (cc > 4) $tap_io(eth_out, eth_out_s, eth_in_, eth_in_s_); + if (cc > 4) $tap_io(eth_out, eth_out_s, eth_in_, eth_in_s_, thinking); eth_in <= eth_in_; eth_in_s <= eth_in_s_; end else if ((ci>=100) & (ci<(100+data_len))) begin From 398d68f2423be599057220c285d7084a4736d15a Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Fri, 30 Aug 2024 19:48:27 -0700 Subject: [PATCH 19/75] picorv32 bootLoad_tb.v: exercise new bootloader.S feature --- soc/picorv32/test/bootLoad/bootLoad_tb.v | 17 +++++++++++++++-- soc/picorv32/test/bootLoad/settings.h | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/soc/picorv32/test/bootLoad/bootLoad_tb.v b/soc/picorv32/test/bootLoad/bootLoad_tb.v index 9f2dfc9b2..29a45531f 100644 --- a/soc/picorv32/test/bootLoad/bootLoad_tb.v +++ b/soc/picorv32/test/bootLoad/bootLoad_tb.v @@ -122,6 +122,8 @@ module bootloader_tb; reg [31:0] _startup_adr_arr[0:0]; wire [31:0] _startup_adr = _startup_adr_arr[0]; reg [ 7:0] hexData [0:255]; + reg [1:0] jx; + integer start_time, delay, dok; //-------------------- // The test sequence @@ -168,26 +170,37 @@ module bootloader_tb; uart_read_task("!"); uart_read_task("!"); //------------------- - // Test timeout + // Test timeout or timeout bypass //------------------- + for (jx=0; jx<2; jx=jx+1) begin $display("\n"); @ (posedge mem_clk); reset <= 1; repeat (10) @(posedge mem_clk); reset <= 0; $display("---------------------"); - $display(" Testing timeout"); + $display(" Testing timeout %d", jx); $display("---------------------"); // Sync sequence: ok uart_read_task("o"); uart_read_task("o"); uart_read_task("k"); uart_read_task("\n"); + // exercise new (Aug 2024) feature of being able to bypass timeout + if (jx==1) uart_write_task("q"); + start_time = $time; // The user program should start talking after the timeout uart_read_task("!"); + delay = $time - start_time; + // Be very lenient, to avoid failure with past or future gcc versions + if (jx == 0) dok = (delay > 20000 && delay < 90000); + if (jx == 1) dok = (delay < 4000); + $display("\nmeasured delay %d ticks %s", delay, dok ? " OK" : "BAD"); + pass &= dok; uart_read_task("!"); uart_read_task("!"); $write("\n"); + end #500 if (pass) begin $display("PASS"); diff --git a/soc/picorv32/test/bootLoad/settings.h b/soc/picorv32/test/bootLoad/settings.h index 2ddda78fe..ce9aad1b2 100644 --- a/soc/picorv32/test/bootLoad/settings.h +++ b/soc/picorv32/test/bootLoad/settings.h @@ -13,7 +13,7 @@ #define F_CLK 100000000 // [Hz] for CMODA7 -#define BOOTLOADER_DELAY 16 +#define BOOTLOADER_DELAY 160 #define BOOTLOADER_BAUDRATE 9216000 // Used for fast simulation #endif From fda69d5208483de5f2a3b8b959c8f967369f0025 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Tue, 3 Sep 2024 09:06:35 -0700 Subject: [PATCH 20/75] Python source formatting: Harmonize on putting line break after binary operator Now have 71 x W504 line break after binary operator (ignored via tox.ini) and 0 x W503 line break before binary operator (dropped from tox.ini) --- board_support/zest/lmk01801.py | 16 ++++++++-------- build-tools/newad.py | 12 ++++++------ peripheral_drivers/i2cbridge/assem.py | 2 +- projects/common/leep/raw.py | 4 ++-- tox.ini | 2 +- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/board_support/zest/lmk01801.py b/board_support/zest/lmk01801.py index 429f563f7..3f9d6abcf 100644 --- a/board_support/zest/lmk01801.py +++ b/board_support/zest/lmk01801.py @@ -19,10 +19,10 @@ def R0( CLKout0_3_PD="0", POWERDOWN="0", RESET="0"): - return eval('0b' + "01001000" + CLKin1_MUX + CLKin1_DIV + CLKin0_MUX - + CLKin0_DIV + "11" + CLKin1_BUF_TYPE + CLKin0_BUF_TYPE - + CLKout12_13_PD + CLKout8_11_PD + CLKout4_7_PD - + CLKout0_3_PD + POWERDOWN + RESET) + return eval('0b' + "01001000" + CLKin1_MUX + CLKin1_DIV + CLKin0_MUX + + CLKin0_DIV + "11" + CLKin1_BUF_TYPE + CLKin0_BUF_TYPE + + CLKout12_13_PD + CLKout8_11_PD + CLKout4_7_PD + + CLKout0_3_PD + POWERDOWN + RESET) # Register R1 and R2, see section 8.5, especially Tables 8-13 and 8-14 def R1( @@ -68,8 +68,8 @@ def R3(self, CLKout12_13_ADLY="000000"): return eval('0b' + "00010" + SYNC1_AUTO + SYNC0_AUTO + SYNC1_FAST + SYNC0_FAST + "011" + NO_SYNC_CLKout12_13 + - NO_SYNC_CLKout8_11 + NO_SYNC_CLKout4_7 + NO_SYNC_CLKout0_3 - + SYNC1_POL_INV + SYNC0_POL_INV + "0" + SYNC1_QUAL + + NO_SYNC_CLKout8_11 + NO_SYNC_CLKout4_7 + NO_SYNC_CLKout0_3 + + SYNC1_POL_INV + SYNC0_POL_INV + "0" + SYNC1_QUAL + CLKout12_13_HS + CLKout12_13_ADLY) # Register R4, see section 8.7, especially table 8-22 @@ -85,8 +85,8 @@ def R5( CLKout8_11_DIV="001", # 1 CLKout4_7_DIV="001", # 1 CLKout0_3_DIV="001"): # 2 - return eval('0b' + "0000" + CLKout12_13_DIV + "00" + CLKout13_ADLY_SEL - + CLKout12_ADLY_SEL + CLKout8_11_DIV + CLKout4_7_DIV + + return eval('0b' + "0000" + CLKout12_13_DIV + "00" + CLKout13_ADLY_SEL + + CLKout12_ADLY_SEL + CLKout8_11_DIV + CLKout4_7_DIV + CLKout0_3_DIV) # Register 15, see section 8.9, especially table 8-27 diff --git a/build-tools/newad.py b/build-tools/newad.py index 0139b9bae..ef2e269f2 100755 --- a/build-tools/newad.py +++ b/build-tools/newad.py @@ -89,9 +89,9 @@ def generate_addresses( bitwidth = gch[k][0] register_array_size = 1 << gch[k][0] if ( - gen_mirror - and mirror_base == -1 - and register_array_size <= MIN_MIRROR_ARRAY_SIZE + gen_mirror and + mirror_base == -1 and + register_array_size <= MIN_MIRROR_ARRAY_SIZE ): mirror_base = base mirror_bit_len = mirror_size.bit_length() @@ -267,9 +267,9 @@ def print_decode_header(fi, modname, fo, dir_list, lb_width, gen_mirror, use_yos # Below only applies for modules with genvar constructions if modname in vfile_parser.self_map: obuf.write( - "`define AUTOMATIC_map " - + " ".join(vfile_parser.self_map[modname] if modname in vfile_parser.self_map else []) - + "\n" + "`define AUTOMATIC_map " + + " ".join(vfile_parser.self_map[modname] if modname in vfile_parser.self_map else []) + + "\n" ) if fo: with open(fo, "w") as fd: diff --git a/peripheral_drivers/i2cbridge/assem.py b/peripheral_drivers/i2cbridge/assem.py index 0f1df6501..aa1bddf1d 100644 --- a/peripheral_drivers/i2cbridge/assem.py +++ b/peripheral_drivers/i2cbridge/assem.py @@ -312,7 +312,7 @@ def write(self, dadr, madr, data, addr_bytes=1): self._check_pc() return None - def read(self, dadr, madr, dlen, addr_bytes=1, reg_name = None): + def read(self, dadr, madr, dlen, addr_bytes=1, reg_name=None): """Add an I2C read transaction to the program. Params: int dadr : Device I2C Address diff --git a/projects/common/leep/raw.py b/projects/common/leep/raw.py index 657a6da5f..23972a476 100644 --- a/projects/common/leep/raw.py +++ b/projects/common/leep/raw.py @@ -513,8 +513,8 @@ def _trysize(self, start_addr): values_preamble = numpy.array(values) self._checkrom(values, True) if self.size_rom != 0: - total_rom_size = (self.hash_descriptor_size - + self.size_desc + self.size_rom) + total_rom_size = (self.hash_descriptor_size + + self.size_desc + self.size_rom) stop_addr = end_addr + total_rom_size - self.preamble_max_size values_json = self.exchange(range(end_addr, stop_addr)) preamble_json = numpy.concatenate((values_preamble, values_json)) diff --git a/tox.ini b/tox.ini index 75250160d..9e5c72c4e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,3 +1,3 @@ [flake8] -ignore=E402,E226,W503,W504,E221,E241,E251 +ignore=E402,E226,W504,E221,E241,E251 max-line-length=120 From 01a0da6bfa4b7a3cb2771627a151a9c7b45ae7d0 Mon Sep 17 00:00:00 2001 From: Keith Penney Date: Wed, 4 Sep 2024 13:15:33 -0700 Subject: [PATCH 21/75] Added more flexible CLI options for LEEP python package --- .gitlab-ci.yml | 3 +- .gitlab/ci/leep.gitlab-ci.yml | 4 + badger/tests/cluster_run.gold | 12 +- projects/common/leep/Makefile | 22 ++ projects/common/leep/base.py | 31 ++- projects/common/leep/cli.py | 101 +++++++- projects/common/leep/raw.py | 151 ++++++++---- projects/common/leep/test/test_cli.py | 321 ++++++++++++++++++++++++++ selfclean.sh | 1 + selftest.sh | 5 +- 10 files changed, 581 insertions(+), 70 deletions(-) create mode 100644 .gitlab/ci/leep.gitlab-ci.yml create mode 100644 projects/common/leep/Makefile create mode 100644 projects/common/leep/test/test_cli.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 137154425..7caf17870 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -38,10 +38,11 @@ include: - local: .gitlab/ci/cdc_check.gitlab-ci.yml - local: .gitlab/ci/localbus.gitlab-ci.yml - local: .gitlab/ci/ctrace.gitlab-ci.yml + - local: .gitlab/ci/leep.gitlab-ci.yml leep_test: script: - - cd projects/common && python3 -m unittest -v + - cd projects/common && PYTHONPATH=../../build-tools python3 -m unittest -v flake8: stage: test diff --git a/.gitlab/ci/leep.gitlab-ci.yml b/.gitlab/ci/leep.gitlab-ci.yml new file mode 100644 index 000000000..856356430 --- /dev/null +++ b/.gitlab/ci/leep.gitlab-ci.yml @@ -0,0 +1,4 @@ +leep_test2: + stage: test + script: + - make -C projects/common/leep && make -C projects/common/leep clean diff --git a/badger/tests/cluster_run.gold b/badger/tests/cluster_run.gold index c26a3b98b..313c90803 100644 --- a/badger/tests/cluster_run.gold +++ b/badger/tests/cluster_run.gold @@ -1,9 +1,9 @@ a3633a315dc8a61e6c2c81b0433258e71dcb43ad a3633a315dc8a61e6c2c81b0433258e71dcb43ad a3633a315dc8a61e6c2c81b0433258e71dcb43ad -scratch_out 00001e61 -scratch_in_r 00001e61 -scratch_out 000022b8 -scratch_in_r 000022b8 -scratch_out 0000270f -scratch_in_r 0000270f +scratch_out 1e61 +scratch_in_r 1e61 +scratch_out 22b8 +scratch_in_r 22b8 +scratch_out 270f +scratch_in_r 270f diff --git a/projects/common/leep/Makefile b/projects/common/leep/Makefile new file mode 100644 index 000000000..55317abad --- /dev/null +++ b/projects/common/leep/Makefile @@ -0,0 +1,22 @@ +# A Makefile to run LEEP tests +THIS_DIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))) +include $(THIS_DIR)/../../../dir_list.mk + +PYTHON=python3 + +LEEP_CORE=base.py raw.py ca.py file.py logic.py + +all: test_cli + +test_cli: $(LEEP_CORE) cli.py + PYTHONPATH="$(THIS_DIR)/..:$(BUILD_DIR)" $(PYTHON) -m leep.test.test_cli test + +# This is a test target currently only used for manual testing. Development is in progress +# for including this in automated regression tests. +server: $(LEEP_CORE) cli.py + PYTHONPATH="$(THIS_DIR)/..:$(BUILD_DIR)" $(PYTHON) -m leep.test.test_cli server + +CLEANS=test.json + +clean: + rm -rf $(CLEANS) diff --git a/projects/common/leep/base.py b/projects/common/leep/base.py index ade632836..47cfff683 100644 --- a/projects/common/leep/base.py +++ b/projects/common/leep/base.py @@ -26,12 +26,35 @@ def wrapper(*args, **kwargs): regs = args[1] if len(regs) and isinstance(regs[0], str): # it's a read operation - for reg in regs: - print('reading register {}'.format(reg)) + for n in range(len(regs)): + reg = regs[n][0] + if len(regs) > 1: + offset = regs[n][1] + try: + reg = "from address 0x{:x}".format(reg) + except ValueError: + reg = "register {}".format(reg) + if offset is not None and offset != 0: + offsetstr = " (offset {})".format(offset) + else: + offsetstr = "" + print('reading {}{}'.format(reg, offsetstr)) else: # it's a write operation, 'regs' is now a tuple, not str - for reg, val in regs: - print('writing {} to register {}'.format(val, reg)) + offset = 0 + for n in range(len(regs)): + reg, val = regs[n][:2] + if len(regs) > 2: + offset = regs[n][2] + try: + reg = "address 0x{:x}".format(reg) + except ValueError: + reg = "register {}".format(reg) + if offset is not None and offset != 0: + offsetstr = " (offset {})".format(offset) + else: + offsetstr = "" + print('writing {} to {}{}'.format(val, reg, offsetstr)) return fcn(*args, **kwargs) return wrapper diff --git a/projects/common/leep/cli.py b/projects/common/leep/cli.py index 07076b022..1a3e95fdb 100644 --- a/projects/common/leep/cli.py +++ b/projects/common/leep/cli.py @@ -7,6 +7,7 @@ import tempfile import shutil import ast +import re from collections import defaultdict @@ -17,19 +18,103 @@ _log = logging.getLogger(__name__) +def _int(s): + return int(ast.literal_eval(s)) + + +def _expandWriteVals(ss): + """Convert string 'n,m,l,k,...' into list of ints [n, m, l, k, ...] + Raise Exception if not all items separated by commas can be interpreted as integers.""" + if ',' not in ss: + return _int(ss) + vals = [_int(x) for x in ss.split(',')] + return vals + + +def parseTransaction(xact): + """ + Parse transaction string from CLI. Returns (str/int reg, int offset, int/None size, int/None write_val) + If 'reg' is type int, it is an explicit base address. + If 'size' is None, size = 1 + If 'reg' is type str, it is a register name (supposedly). + If 'size' is None, size = 2**aw (where 'aw' is the 'addr_width' from the romx JSON) + If 'write_val' is None, it's a read transaction, else it's a write of value 'write_val' + Viable formats for a transaction (read/write) in string form: + Example Implied Transaction + ------------------------------------------- + regname Read from named register (str) 'regname' + regaddr Read from explicit address (int) 'regaddr' + regname=val Write (int) 'val' to named register (str) 'regname' + regaddr=val Write (int) 'val' to explicit address (int) 'regaddr' + regname=val0,...,valN Write (int) 'val0' through 'valN' to consecutive addresses beginning at the + address of named register (str) 'regname' + regaddr=val0,...,valN Write (int) 'val0' through 'valN' to consecutive addresses beginning at + address (int) 'regaddr' + regname+offset Read from address = romx['regname']['base_addr'] + (int) 'offset' + regaddr+offset Read from address = (int) 'regaddr' + (int) 'offset' + regname:size Read (int) 'size' elements starting from address romx['regname']['base_addr'] + regaddr:size Read (int) 'size' elements starting from (int) 'regaddr' + regname+offset=val Write (int) 'val' to address romx['regname']['base_addr'] + (int) 'offset' + regname+offset=val0,...,valN Write (int) 'val0' through 'valN' to consecutive addresses beginning at + address romx['regname']['base_addr'] + (int) 'offset' + regaddr+offset=val Write (int) 'val' to address (int) 'regaddr' + (int) 'offset' + regaddr+offset=val0,...,valN Write (int) 'val0' through 'valN' to consecutive addresses beginning at + address (int) 'regaddr' + regname+offset:size Read (int) 'size' elements starting from address romx['regname']['base_addr'] + \ + (int) 'offset' + regaddr+offset:size Read (int) 'size' elements starting from (int) 'regaddr' + (int) 'offset' + I'm not sure what use case the "regaddr+offset" syntax supports, but it does no harm to include it. + NOTE! Deliberately not supporting "regname-offset" (negative offsets) as it's use case is unclear + and a '_' to '-' typo could potentially collide with legitimate transactions. + """ + restr = r"(\w+)\s*([=+:])?\s*([0-9a-fA-Fx,\-]+)?\s*([=:])?\s*([0-9a-fA-Fx,\-]+)?" + _match = re.match(restr, xact) + offset = 0 + wval = None + size = None + if _match: + groups = _match.groups() + regstr = groups[0] # Always starts with 'regname' or 'regaddr' + if groups[1] == '=': + wval = _expandWriteVals(groups[2]) + elif groups[1] == '+': + offset = _int(groups[2]) + elif groups[1] == ':': + size = _int(groups[2]) + if groups[3] == '=': + if groups[1] == '=': + raise Exception("Malformed transaction: {}".format(xact)) + wval = _expandWriteVals(groups[4]) + elif groups[3] == ':': + if size is not None: + raise Exception("Malformed transaction: {}".format(xact)) + size = _int(groups[4]) + else: + raise Exception("Failed to match: {}".format(xact)) + try: + reg = _int(regstr) + except ValueError: + reg = regstr + if size is None: + if wval is None: + size = None + else: + size = 0 + return (reg, offset, size, wval) + + def readwrite(args, dev): - for pair in args.reg: - name, _eq, val = pair.partition('=') - if len(val): - val = ast.literal_eval(val) - dev.reg_write([(name, val)]) + for xact in args.reg: + reg, offset, size, wvals = parseTransaction(xact) + if wvals is not None: + dev.reg_write_offset([(reg, wvals, offset)]) else: - value, = dev.reg_read((name,)) + value, = dev.reg_read_size(((reg, size, offset),)) try: _ = iter(value) - print("%s \t%s" % (name, ' '.join(['%x' % v for v in value]))) + print("%s \t%s" % (reg, ' '.join(['%x' % v for v in value]))) except TypeError: - print("%s \t%08x" % (name, value)) + print("%s \t%x" % (reg, value)) def listreg(args, dev): diff --git a/projects/common/leep/raw.py b/projects/common/leep/raw.py index 23972a476..28faefc86 100644 --- a/projects/common/leep/raw.py +++ b/projects/common/leep/raw.py @@ -105,6 +105,21 @@ def log2(n): raise RuntimeError("yscale_rfs(%s) %s" % (wave_samp_per, e)) +def _int(s): + try: + # Catch actual ints + return int(s) + except ValueError: + pass + bases = (2, 16, 10) + for base in bases: + try: + return int(s, base) + except (TypeError, ValueError): + pass + return None + + class LEEPDevice(DeviceBase): backend = 'leep' init_rom_addr = 0x800 @@ -132,10 +147,12 @@ def __init__(self, addr, timeout=0.1, **kws): self._readrom() - try: - app_string = self.regmap["__metadata__"]["application"] - except KeyError: - app_string = "Unknown" + app_string = "Unknown" + if self.regmap is not None: + try: + app_string = self.regmap["__metadata__"]["application"] + except KeyError: + pass self.rfs = False self.resctrl = False self.injector = False @@ -150,58 +167,75 @@ def close(self): self.sock.close() super(LEEPDevice, self).close() + def _decode(self, reg, instance=[]): + """Returns (name, addr, len, infodict)""" + info = { # Default info dict + "addr_width": 0, # TODO enable variable read size + "data_width": 32, + "sign": "unsigned", + } + _reg = _int(reg) + if _reg is not None: + return "0x{:x}".format(_reg), _reg, 1, info + if len(instance): + reg = self.expand_regname(reg, instance=instance) + info = self.get_reg_info(reg, instance=None) + size = 2**info.get('addr_width', 0) + base_addr = info['base_addr'] + if isinstance(base_addr, (bytes, unicode)): + base_addr = int(base_addr, 0) + return reg, base_addr, size, info + @print_reg - def reg_write(self, ops, instance=[]): + def reg_write_offset(self, ops, instance=[]): assert isinstance(ops, (list, tuple)) addrs, values = [], [] - for name, value in ops: - if instance is not None: - name = self.expand_regname(name, instance=instance) - info = self.get_reg_info(name, instance=None) - L = 2**info.get('addr_width', 0) - - base_addr = info['base_addr'] - if isinstance(base_addr, (bytes, unicode)): - base_addr = int(base_addr, 0) - + for op in ops: + name, value = op[:2] + offset = 0 + if len(op) > 2: + offset = op[2] + name, base_addr, size = self._decode(name, instance)[:3] + if not hasattr(value, '__len__'): + value = [value] value = numpy.array(value).astype('I') - - if L > 1: - _log.debug('reg_write %s <- %s ...', name, value[:10]) - assert value.ndim == 1 and value.shape[0] == L, \ - ('must write whole register', value.shape, L) - # array register - for A, V in enumerate(value, base_addr): - addrs.append(A) - values.append(V) - else: - assert value.ndim == 0, 'scalar register' - _log.debug('reg_write %s <- %s', name, value) - addrs.append(base_addr) - values.append(value) + _log.debug('reg_write %s <- %s', name, value) + for A, V in enumerate(value, base_addr+offset): + addrs.append(A) + values.append(V) addrs = numpy.asarray(addrs) values = numpy.asarray(values) self.exchange(addrs, values) - @print_reg - def reg_read(self, names, instance=[]): + def reg_write(self, ops, instance=[]): + return self.reg_write_offset([(op[0], op[1], 0) for op in ops], instance=instance) + + def reg_read_size(self, name_sizes, instance=[]): + """'name_sizes' is iterable of (name, size, offset) where: + 'name' can be either a string reg name or an int address + 'size' can be an int number of elements of 'data_width' to read, or None. + 'offset' can be int positive address offset or None (alias of 0) + If 'size' is None, then (2**aw) elements will be read (where 'aw' is the + 'addr_width' of the register). + If 'name' is an address (int) then a 'size' of None implies 'size' 1.""" addrs = [] lens = [] - for name in names: - if instance is not None: - name = self.expand_regname(name, instance=instance) - info = self.get_reg_info(name, instance=None) - L = 2**info.get('addr_width', 0) - - lens.append((info, L)) - base_addr = info['base_addr'] - if isinstance(base_addr, (bytes, str, unicode)): - base_addr = int(base_addr, 0) - addrs.extend(range(base_addr, base_addr + L)) + for name_size in name_sizes: + name, size = name_size[:2] + offset = 0 + if len(name_size) > 2: + offset = name_size[2] + name, base_addr, L, info = self._decode(name, instance) + if size is None: + size = L + else: + size = int(size) + lens.append((info, size)) + addrs.extend(range(base_addr + offset, base_addr + offset + size)) raw = self.exchange(addrs) @@ -221,14 +255,21 @@ def reg_read(self, names, instance=[]): data[neg] |= mask # cast to signed data = data.astype('i4') - _log.debug('reg_read %s -> %s ...', names[i], data[:10]) + _log.debug('reg_read %s -> %s ...', name_sizes[i][0], data[:10]) # unwrap scalar from ndarray - if info.get('addr_width', 0) == 0: + # if info.get('addr_width', 0) == 0: + # TODO - does this break anything? + if L <= 1: data = data[0] ret.append(data) return ret + @print_reg + def reg_read(self, names, instance=[]): + name_sizes = [(name, None) for name in names] + return self.reg_read_size(name_sizes, instance) + def set_decimate(self, dec, instance=[]): if self.rfs: wave_shift, _Ymax = yscale_rfs(dec) @@ -477,6 +518,7 @@ def _exchange(self, addrs, values=None): msg[:2], reply[:2]) continue elif (msg[2::2] != reply[2::2]).any(): + print(f" msg[2::2] = {msg[2::2]}\n reply[2::2] = {reply[2::2]}") _log.error('reply addresses are out of order') continue @@ -498,6 +540,10 @@ def exchange(self, addrs, values=None): else: values = list(values) + if len(values) > len(addrs): + base = addrs[0] + addrs = [base+n for n in range(len(values))] + ret = numpy.zeros(len(addrs), be32) for i in range(0, len(addrs), 127): A, B = addrs[i:i + 127], values[i:i + 127] @@ -585,20 +631,25 @@ def _readrom(self): self.descript = None self.codehash = None self.jsonhash = None - self.regmap = None + self.regmap = None + self._has_rom = False # Try to read ROM at both addresses before raising error try: _log.debug("Trying with init_addr %d", self.init_rom_addr) self.the_rom = self._trysize(self.init_rom_addr) except (RuntimeError, ValueError, RomError): + self.the_rom = [] _log.debug("Trying with max_addr %d", self.max_rom_addr) try: self.the_rom = self._trysize(self.max_rom_addr) except RomError as e: - _log.error("raw.py: %s. Quitting." % str(e)) - raise + self.the_rom = [] + _log.error("raw.py: {}. Register name decoding disabled.".format(str(e))) except (RuntimeError, ValueError): - msg = "Could not read ROM using either start addresses" - raise ValueError(msg) - _log.debug("ROM was successfully read") + self.the_rom = [] + _log.debug("Could not read ROM using either start addresses") + if len(self.the_rom) > 0: + _log.debug("ROM was successfully read") + self._has_rom = True + return diff --git a/projects/common/leep/test/test_cli.py b/projects/common/leep/test/test_cli.py new file mode 100644 index 000000000..3c0ebadb8 --- /dev/null +++ b/projects/common/leep/test/test_cli.py @@ -0,0 +1,321 @@ + +import socket +import numpy +import json +import math +import random + +from build_rom import create_array +from ..cli import parseTransaction + + +class LASS(): + be32 = numpy.dtype('>u4') + be16 = numpy.dtype('>u2') + # see badger/mem_gate.md + OP_WRITE = 0b00 + OP_READ = 0b01 + OP_BURST = 0b10 + + _valid_ops = (OP_WRITE, OP_READ, OP_BURST) + + class InvalidPacket(Exception): + def __init__(self, msg): + super().__init__(msg) + + @classmethod + def _pack(cls, addrs, values=None, request=True, nonce=None): + """Returns (int nonce, bytes packet)""" + pad = None + if len(addrs) < 3: + pad = 3 - len(addrs) + addrs.extend([0] * pad) + values.extend([None] * pad) + msg = numpy.zeros(2 + 2 * len(addrs), dtype=cls.be32) + if nonce is None: + msg[0] = random.randint(0, 0xffffffff) + else: + msg[0] = int(nonce) & 0xffffffff + msg[1] = msg[0] ^ 0xffffffff + for i, (A, V) in enumerate(zip(addrs, values), 1): + A &= 0x00ffffff + if (request and (V is None)) or ((not request) and (V is not None)): + A |= 0x10000000 + msg[2 * i] = A + msg[2 * i + 1] = V or 0 + return (msg[0], msg.tobytes()) + + @classmethod + def _unpack(cls, pkt, request=True): + """Returns (nonce, xacts) where 'xacts' is enumerator of (addr, value) pairs. + For a request packet ('request' = True), for each (addr, value) pair, if 'value' is None, + it's a read from address 'address', otherwise it's a write to address 'addr'. + For a response packet ('request' = False), for each (addr, value) pair, if 'value' is None, + it's a response to a write to address 'address', otherwise it's the value read from address 'addr'. + """ + if len(pkt) % 4 > 0: + raise cls.InvalidPacket("Fragmented packet") + pkt_info = numpy.frombuffer(pkt, cls.be32) + nonce, xor_nonce = pkt_info[0:2] + if len(pkt_info) < 4: + raise cls.InvalidPacket("Packet too small") + if xor_nonce != (nonce ^ 0xffffffff): + raise cls.InvalidPacket("Failed nonce check") + expect_data = False + burst_count = 0 + addrs = [] + values = [] + rnw = True + addr = 0 + for word in pkt_info[2:]: + if not expect_data: + addr = word & 0xffffff + cmd = (word >> 24) + op = (cmd >> 4) & 3 + if op == cls.OP_BURST: + expect_data = False + burst_count = addr & 0x1ff # 9-bit burst count + elif op in (cls.OP_READ, cls.OP_WRITE): + expect_data = True + rnw = op == cls.OP_READ + else: + addrs.append(addr) + if request: + if rnw: + values.append(None) + else: + values.append(word) + else: + if rnw: + values.append(word) + else: + values.append(None) + if burst_count == 0: + expect_data = False + else: + addr = addr + 1 + return (nonce, addrs, values) + + @classmethod + def pack_request(cls, addrs, values=None): + return cls._pack(addrs, values, request=True) + + @classmethod + def unpack_request(cls, pkt): + """Returns (int nonce, list addrs, list values) + For each (addr, value) pair, if 'value' is None, it's a read from address 'address'. + Otherwise it's a write to address 'addr'.""" + return cls._unpack(pkt, request=True) + + @classmethod + def pack_response(cls, nonce, addrs, values=None): + return cls._pack(addrs, values, request=False, nonce=nonce) + + @classmethod + def unpack_response(cls, pkt): + """Returns (int nonce, list addrs, list values) + For each (addr, value) pair, if 'value' is None, it's a response to a write to address 'address'. + Otherwise it's the value read from address 'addr'.""" + return cls._unpack(pkt, request=False) + + +class RespondingDevice(): + @staticmethod + def mem(aw, signed=True): + if signed: + dt = numpy.int32 + else: + dt = numpy.uint32 + return numpy.zeros((1 << aw,), dtype=dt) + + def __init__(self, portnum, verbose=False): + self._verbose = verbose + self._port = int(portnum) + self.regmap = { + "foo": { + "base_addr": 0, + "addr_width": 8, + "signed": True, + "data_width": 32, + "access": "rw", + }, + "bar": { + "base_addr": 0x1000, + "addr_width": 1, + "data_width": 32, + "access": "rw", + }, + "rom": { + "base_addr": 0x4000, + "addr_width": 10, + "data_width": 16, + "access": "r", + }, + } + self._regmap = self.regmap.copy() + self.build_regmap() + + def build_regmap(self): + # Make sure the ROM gets built first + for name, entry in self.regmap.items(): + if name == "rom": + entry["mem"] = self._mkROM() + break + # Then add memory regions + for name, entry in self.regmap.items(): + if name != "rom": + entry["mem"] = self.mem(entry.get("addr_width", 0), signed=entry.get("signed", False)) + return + + def _mkROM(self): + json_file = "test.json" + with open(json_file, "w") as fd: + json.dump(self._regmap, fd) + descrip = "RespondingDevice" + arr = create_array(descrip.encode("utf-8"), json_file, placeholder_rev=True) + aw = math.ceil(math.log2(len(arr))) + mem = self.mem(aw, signed=False) + mem[:len(arr)] = arr + return mem + + def _print(self, *args, **kwargs): + if self._verbose: + print(*args, **kwargs) + + def runServer(self): + server_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0) + # server_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM | socket.SOCK_NONBLOCK, 0) + server_sock.bind(('', self._port)) + print("Listening on port {}".format(self._port)) + print(" Use keyboard interrupt (ctrl+c) to terminate") + while True: + try: + msg, msg_addr = server_sock.recvfrom(1472) + nonce, addrs, values = LASS.unpack_request(msg) + for n in range(len(addrs)): + addr = addrs[n] + value = values[n] + if value is None: + # it's a read + self._print("Server Received: READ from 0x{:x}".format(addr)) + rval = self.read(addr) + values[n] = rval + else: + # it's a write + self._print("Server Received: WRITE 0x{:x} to 0x{:x}".format(value, addr)) + self.write(addr, value) + values[n] = None + nonce_out, response = LASS.pack_response(nonce, addrs, values) + server_sock.sendto(response, msg_addr) + except KeyboardInterrupt: + break + print("Done") + server_sock.close() + return + + def read(self, addr): + for name, entry in self.regmap.items(): + base = entry["base_addr"] + end = entry["base_addr"] + (1 << entry["addr_width"]) + if addr >= base and addr < end: + return entry["mem"][addr-base] + return 0 + + def write(self, addr, value): + for name, entry in self.regmap.items(): + base = entry["base_addr"] + end = entry["base_addr"] + (1 << entry["addr_width"]) + if addr >= base and addr < end: + entry["mem"][addr-base] = value + return None + return None + + +def test_parseTransaction(): + # Baddies raise Exception, so we'll indicate this as the expected + # result by setting the "result" value below to None + dd = { + # CLI string: result (reg, offset, read_size, write_vals) + # regname Read from named register (str) 'regname' + "foo": ("foo", 0, None, None), + # regaddr Read from explicit address (int) 'regaddr' + "0x100": (0x100, 0, None, None), + # regname=val Write (int) 'val' to named register (str) 'regname' + "foo=42": ("foo", 0, 0, 42), + "bar=0x42": ("bar", 0, 0, 0x42), + "foo_baz=0b100": ("foo_baz", 0, 0, 0b100), + # regaddr=val Write (int) 'val' to explicit address (int) 'regaddr' + "0x123=100": (0x123, 0, 0, 100), + "123=0xabc": (123, 0, 0, 0xabc), + "0b1010=-10": (0b1010, 0, 0, -10), + # regname=val0,...,valN Write (int) 'val0' through 'valN' to consecutive addresses beginning at the + # address of named register (str) 'regname' + "reg_foo=1,2,3,4,5": ("reg_foo", 0, 0, [1, 2, 3, 4, 5]), + # regaddr=val0,...,valN Write (int) 'val0' through 'valN' to consecutive addresses beginning at + # address (int) 'regaddr' + "0x4000=1,-1,0,42,0x10": (0x4000, 0, 0, [1, -1, 0, 42, 0x10]), + # regname+offset Read from address = romx['regname']['base_addr'] + (int) 'offset' + "BINGO+100": ("BINGO", 100, None, None), + # regaddr+offset Read from address = (int) 'regaddr' + (int) 'offset' + "0x100+100": (0x100, 100, None, None), + # regname:size Read (int) 'size' elements starting from address romx['regname']['base_addr'] + "_reg_:32": ("_reg_", 0, 32, None), + # regaddr:size Read (int) 'size' elements starting from (int) 'regaddr' + "0:0xff": (0, 0, 0xff, None), + # regname+offset=val Write (int) 'val' to address romx['regname']['base_addr'] + (int) 'offset' + "bandit+0x100=5000": ("bandit", 0x100, 0, 5000), + # regname+offset=val0,...,valN Write (int) 'val0' through 'valN' to consecutive addresses beginning at + # address romx['regname']['base_addr'] + (int) 'offset' + "status+0x20=50,40,0x30": ("status", 0x20, 0, [50, 40, 0x30]), + # regaddr+offset=val Write (int) 'val' to address (int) 'regaddr' + (int) 'offset' + "128+0xc0=-1000": (128, 0xc0, 0, -1000), + # regaddr+offset=val0,...,valN Write (int) 'val0' through 'valN' to consecutive addresses beginning at + # address (int) 'regaddr' + "0x128+0xc0=1,0,1,0,2": (0x128, 0xc0, 0, [1, 0, 1, 0, 2]), + # regname+offset:size Read (int) 'size' elements starting from address romx['regname']['base_addr'] + \ + # (int) 'offset' + "Socks+0x100:100": ("Socks", 0x100, 100, None), + # regaddr+offset:size Read (int) 'size' elements starting from (int) 'regaddr' + (int) 'offset' + "0x4000+15:0b1111": (0x4000, 15, 0b1111, None), + } + errors = 0 + for _input, _expected in dd.items(): + try: + result = parseTransaction(_input) + except Exception: + result = None + if result != _expected: + print("Failed on input: {}.\n Expected: {}\n Result: {}".format(_input, _expected, result)) + errors += 1 + return errors + + +def doTests(args): + errors = 0 + errors += test_parseTransaction() + if errors == 0: + print("PASSED") + return 0 + else: + print("FAILED with {} errors".format(errors)) + return 1 + + +def runServer(args): + dev = RespondingDevice(4592, verbose=False) + dev.runServer() + return 0 + + +if __name__ == "__main__": + import argparse + import sys + parser = argparse.ArgumentParser("LEEP CLI Test") + parser.set_defaults(handler=lambda args: None) + subparsers = parser.add_subparsers(help="Subcommands") + parserServer = subparsers.add_parser("server", help="Run a simulated LEEPDevice server.") + parserServer.set_defaults(handler=runServer) + parserTest = subparsers.add_parser("test", help="Run regression tests.") + parserTest.set_defaults(handler=doTests) + args = parser.parse_args() + sys.exit(args.handler(args)) diff --git a/selfclean.sh b/selfclean.sh index 6dbc08299..f353a7eee 100644 --- a/selfclean.sh +++ b/selfclean.sh @@ -11,6 +11,7 @@ make -C dsp clean make -C dsp/feedforward clean make -C homeless/freq_demo clean make -C homeless clean +make -C projects/common/leep clean make -C localbus clean make -C build-tools/make-demo spotless make -C projects/test_marble_family/pps_lock clean diff --git a/selftest.sh b/selftest.sh index c0a850457..9bd338410 100644 --- a/selftest.sh +++ b/selftest.sh @@ -89,7 +89,10 @@ make -C homeless all checks make -C homeless/freq_demo ## leep_test -(cd projects/common && python3 -m unittest -v) +(cd projects/common && PYTHONPATH=../../build-tools python3 -m unittest -v) + +## leep_test2 +make -C projects/common/leep ## localbus make -C localbus From af704af85d26e7c673d56f1ae9840cb0b42d66c7 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Wed, 4 Sep 2024 14:04:07 -0700 Subject: [PATCH 22/75] Break up ten of the longest Verilog source lines --- cmoc/fdbk_core_tb.v | 9 ++++++--- dsp/cim_12x.v | 18 ++++++++++++------ fpga_family/spartan6/adc_cells.v | 4 +++- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/cmoc/fdbk_core_tb.v b/cmoc/fdbk_core_tb.v index 289ec1311..56d1ec254 100644 --- a/cmoc/fdbk_core_tb.v +++ b/cmoc/fdbk_core_tb.v @@ -224,11 +224,14 @@ always @(posedge clk) begin sync_d2 <= sync_d; // Write aligned input, set-point and error signals onto file (set-point scaling test) - if (out_file != 0 && sync_d2 && (test_type==0 || test_type==1)) $fwrite(out_file," %d %d %d %d %d %d\n", setmp_d2, setmp_d, in_mp_d2, in_mp_d, mp_err_d, mp_err); + if (out_file != 0 && sync_d2 && (test_type==0 || test_type==1)) + $fwrite(out_file," %d %d %d %d %d %d\n", setmp_d2, setmp_d, in_mp_d2, in_mp_d, mp_err_d, mp_err); // Write aligned input and output signals onto file (feedback gain scaling test) - if (out_file != 0 && ~iq && (test_type==2 || test_type==3)) $fwrite(out_file," %d %d %d %d %d %d\n", setmp_d, setmp, out_xy_d, out_xy, m_err_scaling, p_err_scaling); - if (out_file != 0 && ~iq && test_type==4) $fwrite(out_file," %d %d %d %d %d %d\n", in1_d, in1, out_xy_d, out_xy, m_err_scaling, p_err_scaling); + if (out_file != 0 && ~iq && (test_type==2 || test_type==3)) + $fwrite(out_file," %d %d %d %d %d %d\n", setmp_d, setmp, out_xy_d, out_xy, m_err_scaling, p_err_scaling); + if (out_file != 0 && ~iq && test_type==4) + $fwrite(out_file," %d %d %d %d %d %d\n", in1_d, in1, out_xy_d, out_xy, m_err_scaling, p_err_scaling); if (sync_d) count_syncs <= count_syncs + 1'b1; end `endif diff --git a/dsp/cim_12x.v b/dsp/cim_12x.v index 072689fb9..280829a97 100644 --- a/dsp/cim_12x.v +++ b/dsp/cim_12x.v @@ -40,22 +40,28 @@ module cim_12x #( // Snapshots double-integrator outputs at times flagged by "sample", then shifts the results out on the next twelve cycles. wire signed [dw-1:0] s01; wire g01; wire signed [dw-1:0] s03; wire g03; -mon_2chan #(.dwi(16), .rwi(dw)) mon01(.clk(clk), .adcf(adca), .mcos(cosa), .msin(sina), .samp(sample), .s_in(s03), .s_out(s01), .g_in(g03), .g_out(g01), .reset(reset)); +mon_2chan #(.dwi(16), .rwi(dw)) mon01(.clk(clk), .adcf(adca), .mcos(cosa), .msin(sina), + .samp(sample), .s_in(s03), .s_out(s01), .g_in(g03), .g_out(g01), .reset(reset)); wire signed [dw-1:0] s05; wire g05; -mon_2chan #(.dwi(16), .rwi(dw)) mon03(.clk(clk), .adcf(adcb), .mcos(cosa), .msin(sina), .samp(sample), .s_in(s05), .s_out(s03), .g_in(g05), .g_out(g03), .reset(reset)); +mon_2chan #(.dwi(16), .rwi(dw)) mon03(.clk(clk), .adcf(adcb), .mcos(cosa), .msin(sina), + .samp(sample), .s_in(s05), .s_out(s03), .g_in(g05), .g_out(g03), .reset(reset)); wire signed [dw-1:0] s07; wire g07; -mon_2chan #(.dwi(16), .rwi(dw)) mon05(.clk(clk), .adcf(adcc), .mcos(cosa), .msin(sina), .samp(sample), .s_in(s07), .s_out(s05), .g_in(g07), .g_out(g05), .reset(reset)); +mon_2chan #(.dwi(16), .rwi(dw)) mon05(.clk(clk), .adcf(adcc), .mcos(cosa), .msin(sina), + .samp(sample), .s_in(s07), .s_out(s05), .g_in(g07), .g_out(g05), .reset(reset)); wire signed [dw-1:0] s09; wire g09; -mon_2chiq #(.dwi(16), .rwi(dw)) mon07(.clk(clk), .iqd(inm), .scale(scale), .iqs(iqs), .samp(sample), .s_in(s09), .s_out(s07), .g_in(g09), .g_out(g07), .reset(reset)); +mon_2chiq #(.dwi(16), .rwi(dw)) mon07(.clk(clk), .iqd(inm), .scale(scale), .iqs(iqs), + .samp(sample), .s_in(s09), .s_out(s07), .g_in(g09), .g_out(g07), .reset(reset)); wire signed [dw-1:0] s11; wire g11; -mon_2chiq #(.dwi(16), .rwi(dw)) mon09(.clk(clk), .iqd(outm), .scale(scale), .iqs(iqs), .samp(sample), .s_in(s11), .s_out(s09), .g_in(g11), .g_out(g09), .reset(reset)); +mon_2chiq #(.dwi(16), .rwi(dw)) mon09(.clk(clk), .iqd(outm), .scale(scale), .iqs(iqs), + .samp(sample), .s_in(s11), .s_out(s09), .g_in(g11), .g_out(g09), .reset(reset)); wire signed [dw-1:0] s13; wire g13; -mon_2chan #(.dwi(16), .rwi(dw)) mon11(.clk(clk), .adcf(adcx), .mcos(cosb), .msin(sinb), .samp(sample), .s_in(s13), .s_out(s11), .g_in(g13), .g_out(g11), .reset(reset)); +mon_2chan #(.dwi(16), .rwi(dw)) mon11(.clk(clk), .adcf(adcx), .mcos(cosb), .msin(sinb), + .samp(sample), .s_in(s13), .s_out(s11), .g_in(g13), .g_out(g11), .reset(reset)); // terminate the chain assign s13 = {dw{`FILL_BIT}}; diff --git a/fpga_family/spartan6/adc_cells.v b/fpga_family/spartan6/adc_cells.v index 835622962..37872c03b 100644 --- a/fpga_family/spartan6/adc_cells.v +++ b/fpga_family/spartan6/adc_cells.v @@ -41,7 +41,9 @@ module adc_cells( wire adc_iddr2_rst=1'b0; wire adc_iddr2_set=1'b0; wire adc_iddr2_ce=1'b1; - // IDDR2 primitive of sp6, refer to http://www.xilinx.com/support/documentation/sw_manuals/xilinx13_4/spartan6_hdl.pdf, page 56 for ddr_alignment + // IDDR2 primitive of sp6 + // Refer to http://www.xilinx.com/support/documentation/sw_manuals/xilinx13_4/spartan6_hdl.pdf + // page 56 for ddr_alignment genvar ix; generate for (ix=0; ix Date: Wed, 4 Sep 2024 19:20:21 -0700 Subject: [PATCH 23/75] Fix marble si570 support in marble_soc/firmware/ --- board_support/marble_soc/firmware/marble.c | 159 ++++++++++++++++----- board_support/marble_soc/firmware/marble.h | 24 +++- 2 files changed, 145 insertions(+), 38 deletions(-) diff --git a/board_support/marble_soc/firmware/marble.c b/board_support/marble_soc/firmware/marble.c index 2b61e225f..adfa79ab1 100644 --- a/board_support/marble_soc/firmware/marble.c +++ b/board_support/marble_soc/firmware/marble.c @@ -37,7 +37,7 @@ marble_dev_t marble = { .adn4600 = { .i2c_mux_sel = I2C_SEL_CLK, .i2c_addr = I2C_ADR_ADN4600}, .si570 = { - .f_xtal_hz = 114285000ULL, .rfreq = 0ULL, + .f_reset_hz = 0, .rfreq = 0ULL, .i2c_mux_sel = I2C_SEL_APPL, .i2c_addr = I2C_ADR_SI570_NBB} }; @@ -159,6 +159,22 @@ bool get_adn4600_info(adn4600_info_t *info) { return ret; } +bool reset_si570(si570_info_t *info) { + bool ret = true; + uint8_t reg_135 = (1<<7); + ret &= marble_i2c_mux_set(info->i2c_mux_sel); + // reset si570 to read default registers, corresponding to f_reset_hz + i2c_write_regs(info->i2c_addr, 135, ®_135, 1); + DELAY_MS(10); + info->f_out_hz = info->f_reset_hz; + + // calculate f_xtal_hz + ret &= get_si570_info(info); + debug_printf(" %s: SI570 f_xtal: %12lu kHz\n", __func__, marble.si570.f_xtal_hz / 1000); + debug_printf(" %s: SI570 f_out : %12lu kHz\n", __func__, marble.si570.f_out_hz / 1000); + return ret; +} + bool get_si570_info(si570_info_t *info) { bool ret = true; unsigned char *regs = &info->regs[0]; @@ -169,14 +185,61 @@ bool get_si570_info(si570_info_t *info) { } info->hs_div = (regs[0] >> 5) + 4; info->n1 = (((regs[0] & 0x1f) << 2) | (regs[1] >> 6)) + 1; - info->rfreq = ((uint64_t)(regs[1] & 0x3f) << 32) + ((uint64_t)regs[2] << 24) + ((uint64_t)regs[3] << 16) + info->rfreq = ((uint64_t)(regs[1] & 0x3f) << 32) + + ((uint64_t)regs[2] << 24) + + ((uint64_t)regs[3] << 16) + ((uint64_t)regs[4] << 8) + (uint64_t)regs[5]; - info->f_out_hz = info->rfreq * info->f_xtal_hz / (info->hs_div * info->n1) / (1 << 28); + info->f_dco_hz = info->f_out_hz * info->hs_div * info->n1; + info->f_xtal_hz = info->f_dco_hz * (1 << 28) / info->rfreq; + return ret; +} + +bool calc_si570_dividers(si570_info_t *info, uint64_t f1_hz) { + uint8_t hs_divs[] = {11, 9, 7, 6, 5, 4}; + uint64_t fdco; + uint8_t n1; + for (uint8_t i=0; i<65; i++) { + n1 = (i==0) ? 1 : i * 2; + for (uint8_t j=0; j<6; j++) { + fdco = f1_hz * n1 * hs_divs[j]; + if (fdco > 5670000000) break; + if (fdco > 4850000000) { + info->hs_div = hs_divs[j]; + info->n1 = n1; + info->f_dco_hz = fdco; + info->rfreq = fdco * (1 << 28) / info->f_xtal_hz; + debug_printf(" %s: SI570 HSDIV: %12u\n", __func__, marble.si570.hs_div); + debug_printf(" %s: SI570 N1 : %12u\n", __func__, marble.si570.n1); + debug_printf(" %s: SI570 f_dco: %12lu MHz\n", __func__, marble.si570.f_dco_hz / 1000000); + debug_printf(" %s: SI570 rfreq: %12u\n", __func__, marble.si570.rfreq); + return true; + } + } + } + printf(" %s: Failed to find valid si570 dividers.\n", __func__); + return false; +} + +bool calc_si570_regs(si570_info_t *info, uint64_t f1_hz) { + bool ret = true; + unsigned char *regs = &info->regs[0]; + ret &= reset_si570(info); + ret &= calc_si570_dividers(info, f1_hz); + uint8_t n1 = info->n1 - 1; + uint8_t hs_div = info->hs_div - 4; + regs[0] = (hs_div << 5) | ((n1 & 0x7C) >> 2); // reg 7: hs_div[2:0], n1[6:2] + regs[1] = ((n1 & 3) << 6) | (info->rfreq >> 32); // reg 8: n1[1:0] rfreq[37:32] + regs[2] = (info->rfreq >> 24) & 0xff; // reg 9: rfreq[31:24] + regs[3] = (info->rfreq >> 16) & 0xff; // reg 10: rfreq[23:16] + regs[4] = (info->rfreq >> 8) & 0xff; // reg 11: rfreq[15:8] + regs[5] = info->rfreq & 0xff; // reg 12: rfreq[7:0] return ret; } -bool set_si570_info(si570_info_t *info, marble_init_byte_t *p_data) { +bool set_si570_regs(si570_info_t *info, uint64_t f1_hz) { bool ret = true; + unsigned char *regs = &info->regs[0]; + uint8_t reg_freeze_dco = (1<<4); uint8_t reg_unfreeze_dco = 0; uint8_t reg_newfreq = (1<<6); @@ -185,12 +248,8 @@ bool set_si570_info(si570_info_t *info, marble_init_byte_t *p_data) { // freeze DCO ret &= i2c_write_regs(info->i2c_addr, 137, ®_freeze_dco, 1); - // ret &= i2c_write_regmap_byte( - // info->i2c_addr, p_data->regmap, p_data->len); - t_reg8 *regmap = p_data->regmap; - for (unsigned ix=0; ixlen; ix++) { - i2c_write_regs(info->i2c_addr, regmap->addr + info->start_addr, &(regmap->data), 1); - regmap++; + for (unsigned ix=0; ix<6; ix++) { + ret &= marble_i2c_write(info->i2c_addr, info->start_addr+ix, regs+ix, 1); } // Unfreeze DCO ret &= i2c_write_regs(info->i2c_addr, 137, ®_unfreeze_dco, 1); @@ -203,10 +262,10 @@ bool set_si570_info(si570_info_t *info, marble_init_byte_t *p_data) { // any arbitrary point during a clock cycle. This process // can take up to 10 ms. DELAY_MS(20); + if (ret) info->f_out_hz = f1_hz; return ret; } - bool set_ina219_info(ina219_info_t *info, marble_init_word_t *p_data) { bool ret = true; ret &= marble_i2c_mux_set(info->i2c_mux_sel); @@ -258,18 +317,35 @@ void print_marble_status(void) { pca9555_info_t pca9555[2] = {marble.pca9555_qsfp, marble.pca9555_misc}; qsfp_info_t qsfp[2] = {marble.qsfp1, marble.qsfp2}; + switch (marble.variant) { + case MARBLE_VAR_MARBLE_V1_4: + printf(" %s: Marble Variant 1.4\n", __func__); + break; + case MARBLE_VAR_MARBLE_V1_3: + printf(" %s: Marble Variant 1.3\n", __func__); + break; + case MARBLE_VAR_MARBLE_V1_2: + printf(" %s: Marble Variant 1.2\n", __func__); + break; + case MARBLE_VAR_UNKNOWN: + default: + printf(" %s: Marble Variant Unknown\n", __func__); + break; + } + for (unsigned ix=0; ix<8; ix++) { printf(" %s: ADN4600: IN%1u -> OUT%1u\n", __func__, marble.adn4600.xpt_status[ix], ix); } // si570 register dump for (unsigned ix=0; ix<6; ix++) { - debug_printf(" %s SI570: addr = %1u, val = %#04x \n", + printf(" %s: SI570: addr = %1u, val = %#04x \n", __func__, marble.si570.start_addr+ix, marble.si570.regs[ix]); } - debug_printf(" %s: SI570 HSDIV: %12u\n", __func__, marble.si570.hs_div); - debug_printf(" %s: SI570 N1 : %12u\n", __func__, marble.si570.n1); - printf(" %s: SI570 f_out: %12lu kHz\n", __func__, marble.si570.f_out_hz / 1000); + printf(" %s: SI570 HSDIV : %12u\n", __func__, marble.si570.hs_div); + printf(" %s: SI570 N1 : %12u\n", __func__, marble.si570.n1); + printf(" %s: SI570 f_xtal: %12lu kHz\n", __func__, marble.si570.f_xtal_hz / 1000); + printf(" %s: SI570 f_out : %12lu kHz\n", __func__, marble.si570.f_out_hz / 1000); for (unsigned i=0; i<3; i++) { printf(" %s: INA219 %.4s, %.4s:\n", __func__, ina219[i].refdes, ina219[i].name); @@ -320,6 +396,8 @@ static void set_marble_variant(marble_init_t *init_data) { if ((mb4_pcb_rev >> 4) == 0x1) { marble.variant = mb4_pcb_rev & 0xf; printf(" %s: Found MMC Mailbox. mb4_pcb_rev = %x\n", __func__, mb4_pcb_rev); + } else { + printf(" %s: Invalid MMC Mailbox reading: mb4_pcb_rev = %x\n", __func__, mb4_pcb_rev); } #endif } else { // known Marble variant @@ -327,42 +405,54 @@ static void set_marble_variant(marble_init_t *init_data) { } } -static void configure_marble_variant(void) { - // look up si570 for i2c address: - // https://tools.skyworksinc.com/TimingUtility/timing-part-number-search-results.aspx - // https://www.skyworksinc.com/-/media/SkyWorks/SL/documents/public/data-sheets/Si570-71.pdf +// look up si570 for i2c address: +// https://tools.skyworksinc.com/TimingUtility/timing-part-number-search-results.aspx +// https://www.skyworksinc.com/-/media/SkyWorks/SL/documents/public/data-sheets/Si570-71.pdf +static void configure_si570_nbb_i2c(void) { + // 570NBB001808DGR, 20ppm + marble.si570.i2c_addr = I2C_ADR_SI570_NBB; + marble.si570.start_addr = 7; + marble.si570.f_reset_hz = 270000000ULL; +} + +static void configure_si570_ncb_i2c(void) { + // 570NCB000933DG, 7ppm + marble.si570.i2c_addr = I2C_ADR_SI570_NCB; + marble.si570.start_addr = 13; + marble.si570.f_reset_hz = 125000000ULL; +} +static void configure_marble_variant(void) { switch (marble.variant) { case MARBLE_VAR_MARBLE_V1_4: - printf("Marble Variant 1.4\n"); - marble.si570.i2c_addr = I2C_ADR_SI570_NBB; - marble.si570.start_addr = 7; + configure_si570_nbb_i2c(); break; case MARBLE_VAR_MARBLE_V1_3: case MARBLE_VAR_MARBLE_V1_2: - printf("Marble Variant 1.3 or 1.2\n"); - marble.si570.i2c_addr = I2C_ADR_SI570_NCB; - marble.si570.start_addr = 13; + configure_si570_ncb_i2c(); break; + // Auto-determine Marble variants, + // to support a project with mixed hardware versions case MARBLE_VAR_UNKNOWN: default: // in case mmc mailbox is not available, test i2c address for si570 - printf("Marble Variant Unknown\n"); - marble.si570.i2c_addr = I2C_ADR_SI570_NBB; - marble.si570.start_addr = 7; + // reset si570 to read f_xtal_hz + configure_si570_nbb_i2c(); if (get_si570_info(&marble.si570)) { printf(" %s: Found SI570 NBB (Marble 1.4)\n", __func__); + marble.variant = MARBLE_VAR_MARBLE_V1_4; break; } - marble.si570.i2c_addr = I2C_ADR_SI570_NCB; - marble.si570.start_addr = 13; + configure_si570_ncb_i2c(); if (get_si570_info(&marble.si570)) { printf(" %s: Found SI570 NCB (Marble 1.3).\n", __func__); + marble.variant = MARBLE_VAR_MARBLE_V1_3; break; } + printf(" %s: Failed to determine Marble variant).\n", __func__); break; } } @@ -377,16 +467,17 @@ bool init_marble(marble_init_t *init_data) set_marble_variant(init_data); configure_marble_variant(); - p = set_si570_info(&marble.si570, &init_data->si570_data); pass &= p; + p = calc_si570_regs(&marble.si570, init_data->si570_freq_hz); pass &= p; + p &= set_si570_regs(&marble.si570, init_data->si570_freq_hz); pass &= p; printf("==== SI570 init ==== : %s.\n", p?"PASS":"FAIL"); p = set_ina219_info(&marble.ina219_fmc1, &init_data->ina219_fmc1_data); pass &= p; - p = set_ina219_info(&marble.ina219_fmc2, &init_data->ina219_fmc2_data); pass &= p; - p = set_ina219_info(&marble.ina219_12v, &init_data->ina219_12v_data); pass &= p; + p &= set_ina219_info(&marble.ina219_fmc2, &init_data->ina219_fmc2_data); pass &= p; + p &= set_ina219_info(&marble.ina219_12v, &init_data->ina219_12v_data); pass &= p; printf("==== INA219 init ==== : %s.\n", p?"PASS":"FAIL"); p = set_pca9555_info(&marble.pca9555_qsfp, &init_data->pca9555_qsfp_data); pass &= p; - p = set_pca9555_info(&marble.pca9555_misc, &init_data->pca9555_misc_data); pass &= p; + p &= set_pca9555_info(&marble.pca9555_misc, &init_data->pca9555_misc_data); pass &= p; printf("==== PCA9555 init ==== : %s.\n", p?"PASS":"FAIL"); p = set_adn4600_info(&marble.adn4600, &init_data->adn4600_data); pass &= p; diff --git a/board_support/marble_soc/firmware/marble.h b/board_support/marble_soc/firmware/marble.h index 3c37e5d3b..7b58d657b 100644 --- a/board_support/marble_soc/firmware/marble.h +++ b/board_support/marble_soc/firmware/marble.h @@ -49,7 +49,7 @@ typedef struct marble_init_t { marble_init_byte_t pca9555_qsfp_data; // u34 marble_init_byte_t pca9555_misc_data; // u39 marble_init_byte_t adn4600_data; - marble_init_byte_t si570_data; + uint64_t si570_freq_hz; } marble_init_t; typedef struct ina219_info_t { @@ -138,6 +138,8 @@ typedef struct si570_info_t { uint64_t rfreq; uint8_t hs_div; uint8_t n1; + uint64_t f_reset_hz; + uint64_t f_dco_hz; uint64_t f_out_hz; } si570_info_t; @@ -244,12 +246,26 @@ bool set_adn4600_info(adn4600_info_t *info, marble_init_byte_t *p_data); */ bool get_si570_info(si570_info_t *info); + /** - * Write SI570 registers + * Reset SI570 * @param info pointer to si570_info_t struct - * @param p_data pointer to marble_init_byte_t struct */ -bool set_si570_info(si570_info_t *info, marble_init_byte_t *p_data); +bool reset_si570(si570_info_t *info); + +/** + * Calculate SI570 registers from si570_info, and write + * @param info pointer to si570_info_t struct + * @param f1_hz new frequency in Hz + */ +bool calc_si570_regs(si570_info_t *info, uint64_t f1_hz); + +/** + * Write SI570 registers from si570_info + * @param info pointer to si570_info_t struct + * @param f1_hz new frequency in Hz + */ +bool set_si570_regs(si570_info_t *info, uint64_t f1_hz); /** * Poll marble board device info including ina219, pca9555, qsfp From 1a9ef0b09e043bf3e1d3d60629620031fbe10d21 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Fri, 6 Sep 2024 11:10:01 -0700 Subject: [PATCH 24/75] Python style: remove unhelpful extra () wrapper around if conditions --- board_support/zest/zest_setup.py | 8 ++++---- build-tools/gen_features.py | 2 +- cmoc/cryomodule_test_setup.py | 6 +++--- dsp/feedforward/cic_bank_memgen.py | 2 +- dsp/filter_test.py | 4 ++-- peripheral_drivers/i2cbridge/assem.py | 4 ++-- peripheral_drivers/spi_mon_prog.py | 2 +- projects/comms_top/test/comms_top_test.py | 12 ++++++------ projects/test_marble_family/config_si570.py | 10 +++++----- 9 files changed, 25 insertions(+), 25 deletions(-) diff --git a/board_support/zest/zest_setup.py b/board_support/zest/zest_setup.py index beb77db84..34e2f178a 100644 --- a/board_support/zest/zest_setup.py +++ b/board_support/zest/zest_setup.py @@ -727,7 +727,7 @@ def log_step(_s, _smp, _seek, _set, _hld): HLD += 1 while HLD < 16: SEEK = self.seeksethldsmp(SET, HLD, SMP) - if (SEEK != SEEK_000): + if SEEK != SEEK_000: HLD_TIME = HLD break HLD += 1 @@ -743,7 +743,7 @@ def log_step(_s, _smp, _seek, _set, _hld): SET += 1 while SET < 16: SEEK = self.seeksethldsmp(SET, HLD, SMP) - if (SEEK != SEEK_000): + if SEEK != SEEK_000: SET_TIME = SET break SET += 1 @@ -766,7 +766,7 @@ def log_step(_s, _smp, _seek, _set, _hld): HLD += 1 while HLD < 16: SEEK = self.seeksethldsmp(SET, HLD, SMP) - if (SEEK != SEEK_SMP): + if SEEK != SEEK_SMP: HLD_OK = HLD break HLD += 1 @@ -778,7 +778,7 @@ def log_step(_s, _smp, _seek, _set, _hld): SET += 1 while SET < 16: SEEK = self.seeksethldsmp(SET, HLD, SMP) - if (SEEK != SEEK_SMP): + if SEEK != SEEK_SMP: SET_OK = SET break SET += 1 diff --git a/build-tools/gen_features.py b/build-tools/gen_features.py index fb6b423cb..279a7e59e 100644 --- a/build-tools/gen_features.py +++ b/build-tools/gen_features.py @@ -82,7 +82,7 @@ def write_vlog(basename, cfg_dict, split=False, verbose=False): # Use include guard for defines only FD.write("`ifndef __%(n)s__\n`define __%(n)s__\n\n" % {'n': basename.upper()}) for d, v in d_dict.items(): - if (v == 0): + if v == 0: FD.write("//") FD.write(d_string % d.upper()) FD.write("\n`endif // __%s__\n" % basename.upper()) diff --git a/cmoc/cryomodule_test_setup.py b/cmoc/cryomodule_test_setup.py index 4b8d6dd53..be04659cf 100644 --- a/cmoc/cryomodule_test_setup.py +++ b/cmoc/cryomodule_test_setup.py @@ -174,7 +174,7 @@ def fix(x, b, msg, opt=None): # prefix and name are used to give a helpful comment def set_reg(offset, prefix, name, regmap): val = globals()[name] # globals() or locals()? - if (type(val) is list): + if type(val) is list: for i, v in enumerate(val): print(offset + regmap[name] + i, v, "#", prefix + name + "[" + str(i) + "]") @@ -321,7 +321,7 @@ def push_seed(addr, hf): hf.update(chr(jx).encode('utf-8')) -if (prng_seed is not None): +if prng_seed is not None: from hashlib import sha1 print("# PRNG subsystem seed is '%s'" % prng_seed) hf = sha1() @@ -413,6 +413,6 @@ def delay_set(ticks, addr, data): print("%d 1 # Flip the circle buffer" % (0x13800)) print("%d 1 # Flip the circle buffer" % (0x13801)) -if (error_cnt > 0): +if error_cnt > 0: print("# %d scaling errors found" % error_cnt) exit(1) diff --git a/dsp/feedforward/cic_bank_memgen.py b/dsp/feedforward/cic_bank_memgen.py index 38575ccfd..aa834f52d 100644 --- a/dsp/feedforward/cic_bank_memgen.py +++ b/dsp/feedforward/cic_bank_memgen.py @@ -94,7 +94,7 @@ def gen_array(pulse_vals, print_me=True): filln = 4*512 - len(pulse_vals) pulse_vals += [0] * filln - if (print_me): + if print_me: for x in pulse_vals: print(x) diff --git a/dsp/filter_test.py b/dsp/filter_test.py index 89906bf02..6227d82e5 100644 --- a/dsp/filter_test.py +++ b/dsp/filter_test.py @@ -118,12 +118,12 @@ def check_tf(freq, gain, phase, tb_cfg, plot=False): fmeas = c_est fspec = tb_cfg["fcorner"] diff = (np.log10(fmeas) - np.log10(fspec))/np.log10(fspec) - if (abs(diff) > 0.1): + if abs(diff) > 0.1: print("FAIL: Measured 3dB corner (%.1f) too far from spec (%.1f)!" % (fmeas, fspec)) fail = True sspec = tb_cfg["slope"] diff = (slope - sspec)/sspec - if (abs(diff) > 0.1): + if abs(diff) > 0.1: print("FAIL: Measured slope (%.3f) too far from spec (%.3f)!" % (slope, sspec)) fail = True diff --git a/peripheral_drivers/i2cbridge/assem.py b/peripheral_drivers/i2cbridge/assem.py index aa1bddf1d..b59c609db 100644 --- a/peripheral_drivers/i2cbridge/assem.py +++ b/peripheral_drivers/i2cbridge/assem.py @@ -488,10 +488,10 @@ def pad(self, n=None): if n is None: n = (self._pc()//32)+1 # ceil(pc/32) n = int(n) - if (n < self._pc()//32): + if n < self._pc()//32: raise I2C_Assembler_Exception(f"Cannot pad to index {n} which corresponds to an address earlier than" + " the current program counter value {self._pc()}") - elif (n > self._INDEX_MAX): + elif n > self._INDEX_MAX: raise I2C_Assembler_Exception(f"Program counter index {n} exceeds maximum {self._INDEX_MAX}") self._program += super().pad(n, self._pc()) self._check_pc() diff --git a/peripheral_drivers/spi_mon_prog.py b/peripheral_drivers/spi_mon_prog.py index 78fd73fb2..da098455b 100644 --- a/peripheral_drivers/spi_mon_prog.py +++ b/peripheral_drivers/spi_mon_prog.py @@ -8,7 +8,7 @@ def __init__(self, IMEM=512, RMEM=128): def gen(self, cmd_arr, verbose=False): '''cmd_arr is array of tuples: (hw_sel, rnw, command[31:0])''' l_cmd = len(cmd_arr) - if (l_cmd > self.MAX_CMD): + if l_cmd > self.MAX_CMD: print("spi_mon: SPI commands (%d) exceed instruction memory size" % l_cmd) return [] imem_a = [] diff --git a/projects/comms_top/test/comms_top_test.py b/projects/comms_top/test/comms_top_test.py index 92303a387..b73c137da 100755 --- a/projects/comms_top/test/comms_top_test.py +++ b/projects/comms_top/test/comms_top_test.py @@ -117,13 +117,13 @@ def _badarg(self, cmd): print("ERROR: Bad arguments to command {}".format(cmd)) def _pprint(self, cmd, args): - if (len(args) == 0): + if len(args) == 0: self._badarg(cmd) return print("\n> {}\n".format(" ".join(args))) def _pread(self, cmd, args): - if (len(args) != 1): + if len(args) != 1: self._badarg(cmd) return raddr = int(args[0].lstrip(':'), 0) @@ -133,7 +133,7 @@ def _pread(self, cmd, args): print("{} {} RDATA = {} ({})".format(cmd, " ".join(args), d_hex, d_asc)) def _pwrite(self, cmd, args): - if (len(args) != 2): + if len(args) != 2: self._badarg(cmd) return waddr = int(args[0].lstrip(':'), 0) @@ -144,7 +144,7 @@ def _pwrite(self, cmd, args): print("{} {}".format(cmd, " ".join(args))) def _prdmem(self, cmd, args): - if (len(args) != 3): + if len(args) != 3: self._badarg(cmd) return base_addr = int(args[0].lstrip(':'), 0) @@ -162,7 +162,7 @@ def _prdmem(self, cmd, args): print("{} {} : Successfully read {} memory positions".format(cmd, " ".join(args), read_length)) def _pwait(self, cmd, args): - if (len(args) != 1): + if len(args) != 1: self._badarg(cmd) return tsleep = int(args[0]) @@ -171,7 +171,7 @@ def _pwait(self, cmd, args): time.sleep(tsleep) def _pcmp(self, cmd, args): - if (len(args) != 2): + if len(args) != 2: self._badarg(cmd) return diff --git a/projects/test_marble_family/config_si570.py b/projects/test_marble_family/config_si570.py index 91ebe6db9..3ebcae12d 100644 --- a/projects/test_marble_family/config_si570.py +++ b/projects/test_marble_family/config_si570.py @@ -37,11 +37,11 @@ def decode_settings(mbox, verbose): i2c_addr = mbox[96] config = mbox[97] start_freq = int.from_bytes(bytes(mbox[98:102]), 'big') # 4 bytes, MSB-first, unused - if ((i2c_addr == 0) or (i2c_addr == 0xff) or (config == 0) or (config == 0xff) or (pcb_rev == 0xdeadbeef)): + if (i2c_addr == 0) or (i2c_addr == 0xff) or (config == 0) or (config == 0xff) or (pcb_rev == 0xdeadbeef): print("SI570 settings not configured through MMC,using default for {:s} v1.{:d}".format(board_name, marble_rev)) start_freq = 0 # use default values if it's a marble v1.2, v1.3 or marble_mini - if (marble_rev == 2 or marble_rev == 3 or board == 2): + if marble_rev == 2 or marble_rev == 3 or board == 2: i2c_addr = 0xee polarity = 0 start_addr = 0x0d @@ -50,7 +50,7 @@ def decode_settings(mbox, verbose): polarity = 0 start_addr = 0x07 # check the [7:6] bits of the config value is either 2'b01 or 2'b10, to make sure it valid - elif (((config >> 6) == 1) ^ ((config >> 6) == 2)): + elif ((config >> 6) == 1) ^ ((config >> 6) == 2): start_addr = 0x0d if (config & 0x02) else 0x07 polarity = config & 0x01 else: @@ -166,7 +166,7 @@ def hw_write_prog(si570_addr, start_addr, reg): # check if the final output frequency is <= 50 ppm def check(fin): ppm = ((fin)*(1/args.new_freq) - 1.0)*1e6 - if (abs(ppm) >= 50): + if abs(ppm) >= 50: raise ValueError('SI570 final frequency measurement is not correct, out of spec by %i ppm' % ppm) @@ -212,7 +212,7 @@ def config_si570(addr, verbose): if args.new_freq: si570_addr, config_addr, fxtal, default = compute_si570(addr, "Measured", verbose) # if first measured frequency and new output frequency are < 10 ppm don't change/update - if (abs(((default)*(1/args.new_freq) - 1.0)*1e6) < 10): + if abs(((default)*(1/args.new_freq) - 1.0)*1e6) < 10: pass else: print("#######################################") From 9c9bea0c531bdf73cb3bbda4c3211da9cc75e5aa Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Fri, 6 Sep 2024 17:22:29 -0700 Subject: [PATCH 25/75] Convert many URLs from http:// to https:// All new URLs are confirmed correct and reachable today. About 23 left, that have no clear direct replacements. --- CONTRIBUTING.md | 2 +- README.md | 2 +- badger/README.md | 2 +- badger/crc8e_guts.v | 2 +- badger/tests/badger.tcl | 2 +- badger/tests/crc8e_guts_x.v | 2 +- board_support/fmc120/firmware/fmc120.c | 2 +- board_support/fmc150/dac3283.v | 2 +- board_support/fmc150/firmware/cdce72010.h | 2 +- build-tools/portfind.py | 4 ++-- build-tools/riscv_meta.sh | 6 +++--- build-tools/riscv_prep.sh | 2 +- build-tools/top_rules.mk | 2 +- build-tools/vivado_tcl/project_proc.tcl | 2 +- build-tools/xil_syn | 2 +- cmoc/cryomodule_test_setup.py | 2 +- doc/conf.py | 2 +- dsp/digaree/sched.py | 2 +- dsp/fifo_2c.v | 2 +- dsp/freq_gcount.v | 2 +- dsp/hosted/non_iq_interleaved_piloop.v | 2 +- homeless/freq_demo/simplest_gray.v | 2 +- localbus/README.md | 2 +- peripheral_drivers/i2cbridge/c2vcd.py | 2 +- peripheral_drivers/i2cbridge/i2c_slave_model.v | 2 +- peripheral_drivers/idelay_scanner/scanner.tcl | 2 +- projects/oscope/marble_family/README.md | 2 +- projects/oscope/software/bmb7/ctrace_dump.py | 2 +- projects/test_marble_family/README.md | 2 +- projects/test_marble_family/ctrace_dump_gps.py | 2 +- projects/test_marble_family/fmc_test_iam.py | 2 +- projects/test_marble_family/fmc_test_l.py | 2 +- projects/test_marble_family/marble.tcl | 2 +- projects/test_marble_family/nmea_view.py | 6 +++--- rtsim/param.py | 2 +- serial_io/EVG_EVR/NMEA.c | 2 +- serial_io/crc16.v | 2 +- serial_io/negotiate.v | 2 +- soc/picorv32/project/kc705/sim/i2c_model.v | 2 +- 39 files changed, 44 insertions(+), 44 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6022a46d5..e70327d6d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -121,7 +121,7 @@ We're not the first group to deal with this topic. The following are useful resources: 1. [Linux kernel coding style guide](https://www.kernel.org/doc/html/v4.10/process/coding-style.html) many of the concepts it discusses have general applicability. -2. [Google python guide](http://google.github.io/styleguide/pyguide.html) and [PEP8](https://www.python.org/dev/peps/pep-0008/) +2. [Google python guide](https://google.github.io/styleguide/pyguide.html) and [PEP8](https://www.python.org/dev/peps/pep-0008/) 3. [GNU Coding Standards: Makefile Conventions](https://www.gnu.org/prep/standards/html_node/Makefile-Conventions.html) Please spell-check your code, comments, and documentation. diff --git a/README.md b/README.md index dd6eee41f..ef95e408c 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ A few comments regarding the codebase We are on an active lookout for other methods, if they're actually better for us. 3. iverilog is used for simulation. We are slowly starting to use [Verilator](https://www.veripool.org/wiki/verilator) as well (see badger) -4. Xilinx tools are used for synthesis, and starting to support [YoSys](http://www.clifford.at/yosys/) (again see badger) +4. Xilinx tools are used for synthesis, and starting to support [YoSys](https://yosyshq.net/yosys/) (again see badger) 5. This repository is connected to Gitlab CI. All simulation based tests run automatically upon every commit on the continuous integration server. This helps us move faster (without breaking things). A helpful subset of those tests diff --git a/badger/README.md b/badger/README.md index dd0fe032d..f16bf2a5e 100644 --- a/badger/README.md +++ b/badger/README.md @@ -139,7 +139,7 @@ Demonstrating both Packet Badger functionality, and the test framework's ability to attach the simulation to the host's Ethernet subsystem. Your development machine needs to provide a traditional unix-y environment, -e.g., make, cc, python, awk, cmp. Also some version of [Icarus Verilog](http://iverilog.icarus.com/); see [status.md](status.md) for more details. +e.g., make, cc, python, awk, cmp. Also some version of [Icarus Verilog](https://steveicarus.github.io/iverilog/); see [status.md](status.md) for more details. In one shell session (Linux terminal), try: diff --git a/badger/crc8e_guts.v b/badger/crc8e_guts.v index af0c7c473..d9562aa52 100644 --- a/badger/crc8e_guts.v +++ b/badger/crc8e_guts.v @@ -7,7 +7,7 @@ module crc8e_guts( output [7:0] d_out, output zero ); -// http://en.wikipedia.org/wiki/Cyclic_redundancy_check +// https://en.wikipedia.org/wiki/Cyclic_redundancy_check parameter wid=32; parameter init=32'hffffffff; diff --git a/badger/tests/badger.tcl b/badger/tests/badger.tcl index f806200ed..7d70f9736 100644 --- a/badger/tests/badger.tcl +++ b/badger/tests/badger.tcl @@ -8,7 +8,7 @@ proc project_rpt {dest_dir} { report_datasheet -v -file $dest_dir/imp_datasheet.rpt report_cdc -v -details -file $dest_dir/cdc_report.rpt report_timing_summary -delay_type min_max -report_unconstrained -check_timing_verbose -max_paths 10 -input_pins -file $dest_dir/imp_timing.rpt - # http://xillybus.com/tutorials/vivado-timing-constraints-error + # https://xillybus.com/tutorials/vivado-timing-constraints-error if {! [string match -nocase {*timing constraints are met*} [report_timing_summary -no_header -no_detailed_paths -return_string]]} { puts "Timing constraints weren't met. Please check your design." exit 2 diff --git a/badger/tests/crc8e_guts_x.v b/badger/tests/crc8e_guts_x.v index ddcc786e6..ca7d23fa8 100644 --- a/badger/tests/crc8e_guts_x.v +++ b/badger/tests/crc8e_guts_x.v @@ -7,7 +7,7 @@ module crc8e_guts( output [7:0] d_out, output zero ); -// http://en.wikipedia.org/wiki/Cyclic_redundancy_check +// https://en.wikipedia.org/wiki/Cyclic_redundancy_check parameter wid=32; parameter init=32'hffffffff; diff --git a/board_support/fmc120/firmware/fmc120.c b/board_support/fmc120/firmware/fmc120.c index f712ab90a..6a161b6a0 100644 --- a/board_support/fmc120/firmware/fmc120.c +++ b/board_support/fmc120/firmware/fmc120.c @@ -15,7 +15,7 @@ /* JESD204B subclass1 deterministic latency - http://www.ti.com/lit/ml/slap159/slap159.pdf + https://www.ti.com/lit/ml/slap159/slap159.pdf ADC: ADS54J60 * LMFS: 4 2 1 1 * ceil(17/F) <= K <= min(32, floor(1024/F)) diff --git a/board_support/fmc150/dac3283.v b/board_support/fmc150/dac3283.v index 79e0edc49..b756b3afb 100644 --- a/board_support/fmc150/dac3283.v +++ b/board_support/fmc150/dac3283.v @@ -1,6 +1,6 @@ // DAC3283 Dual-Channel, 16-Bit, 800 MSPS, Digital-to-Analog Converter // LVDS PHY interface -// [1]: http://www.ti.com/lit/ds/symlink/dac3283.pdf +// [1]: https://www.ti.com/lit/ds/symlink/dac3283.pdf module dac3283 #( parameter [7:0] BASE_ADDR = 8'h0, diff --git a/board_support/fmc150/firmware/cdce72010.h b/board_support/fmc150/firmware/cdce72010.h index 036588589..7fb317933 100644 --- a/board_support/fmc150/firmware/cdce72010.h +++ b/board_support/fmc150/firmware/cdce72010.h @@ -1,7 +1,7 @@ // Ten Output High Performance Clock Synchronizer, // Jitter Cleaner, and Clock Distributor // Controlled over SPI, used on FMC150 -// See: http://www.ti.com/lit/ds/scas858c/scas858c.pdf +// See: https://www.ti.com/lit/ds/scas858c/scas858c.pdf #ifndef CDCE72010_H #define CDCE72010_H diff --git a/build-tools/portfind.py b/build-tools/portfind.py index e8340558e..352bd995c 100644 --- a/build-tools/portfind.py +++ b/build-tools/portfind.py @@ -208,7 +208,7 @@ def make_html(fname, param_list, port_list): print(hdata["implement_html"] + "\n") if True: print("

") - print("A GTKWave-generated") + print("A GTKWave-generated") print("timing diagram showing {} is shown here:" .format(hdata["timing_html"])) print("

\"timing\n" @@ -319,7 +319,7 @@ def make_rst(fname, param_list, port_list, mod_comment_list, with_timing=None): print("") print("A `GTKWave`_-generated timing diagram is shown below:") print("") - print(".. _`GTKWave`: http://gtkwave.sourceforge.net/") + print(".. _`GTKWave`: https://gtkwave.sourceforge.net/") print("") print(".. _fig:{}_timing:".format(fbase)) print(".. figure:: {}_timing.png".format(fbase)) diff --git a/build-tools/riscv_meta.sh b/build-tools/riscv_meta.sh index eefa2dc6c..aaa1cbecc 100644 --- a/build-tools/riscv_meta.sh +++ b/build-tools/riscv_meta.sh @@ -32,11 +32,11 @@ # # Versions: # binutils-2.32, released 2019-02-02 -# http://www.gnu.org/software/binutils/ +# https://www.gnu.org/software/binutils/ # gcc-8.3.0, released 2019-02-22 -# http://www.gnu.org/software/gcc/ +# https://www.gnu.org/software/gcc/ # newlib-3.1.0, released 2018-12-31 -# ftp://sourceware.org/pub/newlib/index.html +# https://sourceware.org/newlib/ # # 0ab6c55dd86a92ed561972ba15b9b70a8b9f75557f896446c82e8b36e473ee04 binutils-2.32.tar.xz # 64baadfe6cc0f4947a84cb12d7f0dfaf45bb58b7e92461639596c21e02d97d2c gcc-8.3.0.tar.xz diff --git a/build-tools/riscv_prep.sh b/build-tools/riscv_prep.sh index 8f1547679..f58c0273f 100644 --- a/build-tools/riscv_prep.sh +++ b/build-tools/riscv_prep.sh @@ -7,7 +7,7 @@ set -e # Get upstream stable sources mkdir ref cd ref -wget --no-verbose http://mirrors.kernel.org/gnu/binutils/binutils-2.32.tar.xz +wget --no-verbose https://mirrors.kernel.org/gnu/binutils/binutils-2.32.tar.xz wget --no-verbose https://bigsearcher.com/mirrors/gcc/releases/gcc-8.3.0/gcc-8.3.0.tar.xz wget --no-verbose ftp://sourceware.org/pub/newlib/newlib-3.1.0.tar.gz diff --git a/build-tools/top_rules.mk b/build-tools/top_rules.mk index 9373d9d57..96ec2b70f 100644 --- a/build-tools/top_rules.mk +++ b/build-tools/top_rules.mk @@ -218,7 +218,7 @@ EMPTY := SPACE := $(EMPTY) $(EMPTY) COMMA := , -# http://www.graphviz.org/content/dot-language +# https://graphviz.org/doc/info/lang.html # apt-get install graphviz %.ps: %.dot dot -Tps $< -o $@ diff --git a/build-tools/vivado_tcl/project_proc.tcl b/build-tools/vivado_tcl/project_proc.tcl index caf8e4e14..b8dc8dbee 100644 --- a/build-tools/vivado_tcl/project_proc.tcl +++ b/build-tools/vivado_tcl/project_proc.tcl @@ -237,7 +237,7 @@ proc project_rpt {project_name} { report_datasheet -v -file ./_xilinx/$project_name/imp_datasheet.rpt report_cdc -v -details -file ./_xilinx/$project_name/cdc_report.rpt report_timing_summary -delay_type min_max -report_unconstrained -check_timing_verbose -max_paths 10 -input_pins -file ./_xilinx/$project_name/imp_timing.rpt - # http://xillybus.com/tutorials/vivado-timing-constraints-error + # https://xillybus.com/tutorials/vivado-timing-constraints-error if {! [string match -nocase {*timing constraints are met*} [report_timing_summary -no_header -no_detailed_paths -return_string]]} { puts "Timing constraints weren't met. Please check your design." exit 2 diff --git a/build-tools/xil_syn b/build-tools/xil_syn index e0daf8916..53ecd85ed 100644 --- a/build-tools/xil_syn +++ b/build-tools/xil_syn @@ -258,7 +258,7 @@ if [ "$arch" = "s6" ]; then else case "$PART" in # LLRF46 needs -g StartUpClk:CClk per page 1 of - # http://www.dimtel.com/_media/support/llrf4/packet46.pdf + # https://www.dimtel.com/_media/support/llrf4/packet46.pdf # otherwise the DAC outputs get messed up. xc6slx*) BG_OPT="-g StartUpClk:CClk" ;; *) BG_OPT="-g StartUpClk:JtagClk" ;; diff --git a/cmoc/cryomodule_test_setup.py b/cmoc/cryomodule_test_setup.py index be04659cf..fbaeef7cb 100644 --- a/cmoc/cryomodule_test_setup.py +++ b/cmoc/cryomodule_test_setup.py @@ -3,7 +3,7 @@ from math import pi, sqrt, log from numpy import exp as cexp from numpy import ceil -# http://stackoverflow.com/questions/14132789/python-relative-imports-for-the-billionth-time +# https://stackoverflow.com/questions/14132789/relative-imports-for-the-billionth-time # Leaves me with only one choice ... :( # Since I don't want to modify shell variables sys.path.append( diff --git a/doc/conf.py b/doc/conf.py index bf2fbbbe5..609a949f4 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -4,7 +4,7 @@ # # This file does only contain a selection of the most common options. For a # full list see the documentation: -# http://www.sphinx-doc.org/en/master/config +# https://www.sphinx-doc.org/en/master/usage/configuration.html # -- Path setup -------------------------------------------------------------- diff --git a/dsp/digaree/sched.py b/dsp/digaree/sched.py index 2916d650b..e47b79f09 100644 --- a/dsp/digaree/sched.py +++ b/dsp/digaree/sched.py @@ -19,7 +19,7 @@ def tobin(x, count=8): # Integer to binary; count is number of bits - # Credit to W.J. van der Laan in http://code.activestate.com/recipes/219300/ + # Credit to W.J. van der Laan in https://code.activestate.com/recipes/219300/ return "".join([str((x >> y) & 1) for y in range(count-1, -1, -1)]) diff --git a/dsp/fifo_2c.v b/dsp/fifo_2c.v index c5451f530..0c1c5466a 100644 --- a/dsp/fifo_2c.v +++ b/dsp/fifo_2c.v @@ -3,7 +3,7 @@ // Based on, and mostly compatible with, OpenCores (Rudolf Usselmann) // generic_fifo_dc_gray (Universal FIFO Dual Clock, gray encoded), // downloaded from: -// http://www.opencores.org/cores/generic_fifos/ +// https://opencores.org/projects/generic_fifos // This version drops the rst and clr inputs, as befits my FPGA needs, // and neglects to provide wr_level and rd_level outputs. It is also // coded in a more compact style. diff --git a/dsp/freq_gcount.v b/dsp/freq_gcount.v index e403c13e9..cf9b1b29c 100644 --- a/dsp/freq_gcount.v +++ b/dsp/freq_gcount.v @@ -33,7 +33,7 @@ initial begin end // four-bit Gray code counter on the input signal -// http://en.wikipedia.org/wiki/Gray_code +// https://en.wikipedia.org/wiki/Gray_code localparam gw=4; reg [gw-1:0] gray1=0; diff --git a/dsp/hosted/non_iq_interleaved_piloop.v b/dsp/hosted/non_iq_interleaved_piloop.v index 11a15a804..86cb77107 100644 --- a/dsp/hosted/non_iq_interleaved_piloop.v +++ b/dsp/hosted/non_iq_interleaved_piloop.v @@ -16,7 +16,7 @@ // + // K_i/K_p // -// Created with http://asciiflow.com +// Created with https://asciiflow.com // DELAY: 9 cycles of delay at @clk `timescale 1ns / 1ns diff --git a/homeless/freq_demo/simplest_gray.v b/homeless/freq_demo/simplest_gray.v index 137965cee..1699089dd 100644 --- a/homeless/freq_demo/simplest_gray.v +++ b/homeless/freq_demo/simplest_gray.v @@ -1,5 +1,5 @@ // Simplest possible Gray code counter with parameterized width -// http://en.wikipedia.org/wiki/Gray_code +// https://en.wikipedia.org/wiki/Gray_code module simplest_gray #( parameter gw=4 ) ( diff --git a/localbus/README.md b/localbus/README.md index 2c0098053..00a88c6b8 100644 --- a/localbus/README.md +++ b/localbus/README.md @@ -2,7 +2,7 @@ Many bedrock components revolve around or depend on an on-chip [localbus](https://en.wikipedia.org/wiki/Local_bus). -Speficially a stripped-down lightweight bus reminiscent +Specifically a stripped-down lightweight bus reminiscent of a VME A24 bus. In a given clock domain, expect diff --git a/peripheral_drivers/i2cbridge/c2vcd.py b/peripheral_drivers/i2cbridge/c2vcd.py index dbb929515..e8f8f486d 100644 --- a/peripheral_drivers/i2cbridge/c2vcd.py +++ b/peripheral_drivers/i2cbridge/c2vcd.py @@ -4,7 +4,7 @@ def tobin(x, count=8): # Integer to binary; count is number of bits - # Props to W.J. van der Laan in http://code.activestate.com/recipes/219300/ + # Props to W.J. van der Laan in https://code.activestate.com/recipes/219300/ return list(map(lambda y: (x >> y) & 1, range(count-1, -1, -1))) diff --git a/peripheral_drivers/i2cbridge/i2c_slave_model.v b/peripheral_drivers/i2cbridge/i2c_slave_model.v index 16b6a6639..1f0b3527b 100644 --- a/peripheral_drivers/i2cbridge/i2c_slave_model.v +++ b/peripheral_drivers/i2cbridge/i2c_slave_model.v @@ -6,7 +6,7 @@ //// Authors: Richard Herveille (richard@asics.ws) www.asics.ws //// //// John Sheahan (jrsheahan@optushome.com.au) //// //// //// -//// Downloaded from: http://www.opencores.org/projects/i2c/ //// +//// Downloaded from: https://www.opencores.org/projects/i2c/ //// //// //// ///////////////////////////////////////////////////////////////////// //// //// diff --git a/peripheral_drivers/idelay_scanner/scanner.tcl b/peripheral_drivers/idelay_scanner/scanner.tcl index fc0265369..c5b452b29 100644 --- a/peripheral_drivers/idelay_scanner/scanner.tcl +++ b/peripheral_drivers/idelay_scanner/scanner.tcl @@ -7,7 +7,7 @@ proc project_rpt {project_name} { # Generate implementation timing & power report report_power -file ./vivado_project/$project_name.imp_power.rpt report_timing_summary -delay_type min_max -report_unconstrained -check_timing_verbose -max_paths 10 -input_pins -file ./vivado_project/$project_name.imp_timing.rpt - # http://xillybus.com/tutorials/vivado-timing-constraints-error + # https://xillybus.com/tutorials/vivado-timing-constraints-error if {! [string match -nocase {*timing constraints are met*} [report_timing_summary -no_header -no_detailed_paths -return_string]]} { puts "Timing constraints weren't met. Please check your design." exit 2 diff --git a/projects/oscope/marble_family/README.md b/projects/oscope/marble_family/README.md index c4c0e4562..9001be97a 100644 --- a/projects/oscope/marble_family/README.md +++ b/projects/oscope/marble_family/README.md @@ -54,7 +54,7 @@ With below ADC clock domain can be set to 100MHz LMK dividers in zest_setup.py for zest are set to divide the below 1400MHz down to 100MHz [This can be changed Inside zest_setup.py .. good luck] For waveforms, using Si***_loader from: -https://github.com/yetifrisstlama/Si5xx-5x7-EVV_autoloader +https://github.com/michael-betz/Si5xx-5x7-EVV_autoloader ``` python setFreq.py -p /dev/ttyUSB2 156.25e6 1400e6 ``` diff --git a/projects/oscope/software/bmb7/ctrace_dump.py b/projects/oscope/software/bmb7/ctrace_dump.py index 6909d6b0b..f2666d27d 100644 --- a/projects/oscope/software/bmb7/ctrace_dump.py +++ b/projects/oscope/software/bmb7/ctrace_dump.py @@ -6,7 +6,7 @@ def tobin(x, count=8): # Integer to binary; count is number of bits # Some credit to W.J. van der Laan in - # http://code.activestate.com/recipes/219300/ + # https://code.activestate.com/recipes/219300/ return [(x >> y) & 1 for y in range(count-1, -1, -1)] diff --git a/projects/test_marble_family/README.md b/projects/test_marble_family/README.md index d747d4a5e..110a86526 100644 --- a/projects/test_marble_family/README.md +++ b/projects/test_marble_family/README.md @@ -7,7 +7,7 @@ The Marble.xdc file here is the one generated by a script in that repository. Infrastructure provided by [Bedrock](https://github.com/BerkeleyLab/Bedrock). -Currently tested successful at booting a bitfile (using [openocd](http://openocd.org/)), +Currently tested successful at booting a bitfile (using [openocd](https://openocd.org/)), bringing up Ethernet (synthesized default IP address 192.168.19.10, but that's normally overridden by the on-board MMC), blinking LEDs, and reading/writing/booting SPI Flash (using Bedrock's spi_test.py). diff --git a/projects/test_marble_family/ctrace_dump_gps.py b/projects/test_marble_family/ctrace_dump_gps.py index c8b72bc11..ea1ea5bd4 100644 --- a/projects/test_marble_family/ctrace_dump_gps.py +++ b/projects/test_marble_family/ctrace_dump_gps.py @@ -5,7 +5,7 @@ def tobin(x, count=8): # Integer to binary; count is number of bits # Some credit to W.J. van der Laan in - # http://code.activestate.com/recipes/219300/ + # https://code.activestate.com/recipes/219300/ return [(x >> y) & 1 for y in range(count-1, -1, -1)] diff --git a/projects/test_marble_family/fmc_test_iam.py b/projects/test_marble_family/fmc_test_iam.py index 0caf682d3..342704d27 100644 --- a/projects/test_marble_family/fmc_test_iam.py +++ b/projects/test_marble_family/fmc_test_iam.py @@ -12,7 +12,7 @@ def tobin(x, count=8): # Integer to binary; count is number of bits - # Credit to W.J. van der Laan in http://code.activestate.com/recipes/219300/ + # Credit to W.J. van der Laan in https://code.activestate.com/recipes/219300/ return "".join([str((x >> y) & 1) for y in range(count-1, -1, -1)]) diff --git a/projects/test_marble_family/fmc_test_l.py b/projects/test_marble_family/fmc_test_l.py index 0acbde687..e6a485fe9 100644 --- a/projects/test_marble_family/fmc_test_l.py +++ b/projects/test_marble_family/fmc_test_l.py @@ -105,7 +105,7 @@ def tobin(x, count=8): # Integer to binary; count is number of bits - # Props to W.J. van der Laan in http://code.activestate.com/recipes/219300/ + # Props to W.J. van der Laan in https://code.activestate.com/recipes/219300/ return list(map(lambda y: (x >> y) & 1, range(count-1, -1, -1))) diff --git a/projects/test_marble_family/marble.tcl b/projects/test_marble_family/marble.tcl index ac3fbb624..b25ff87b1 100644 --- a/projects/test_marble_family/marble.tcl +++ b/projects/test_marble_family/marble.tcl @@ -67,7 +67,7 @@ proc project_rpt {project_name} { report_datasheet -v -file ./_xilinx/$project_name/imp_datasheet.rpt report_cdc -v -details -file ./_xilinx/$project_name/cdc_report.rpt report_timing_summary -delay_type min_max -report_unconstrained -check_timing_verbose -max_paths 10 -input_pins -file ./_xilinx/$project_name/imp_timing.rpt - # http://xillybus.com/tutorials/vivado-timing-constraints-error + # https://xillybus.com/tutorials/vivado-timing-constraints-error if {! [string match -nocase {*timing constraints are met*} [report_timing_summary -no_header -no_detailed_paths -return_string]]} { puts "Timing constraints weren't met. Please check your design." exit 2 diff --git a/projects/test_marble_family/nmea_view.py b/projects/test_marble_family/nmea_view.py index 9dd8ec5dc..31d3429f2 100644 --- a/projects/test_marble_family/nmea_view.py +++ b/projects/test_marble_family/nmea_view.py @@ -8,7 +8,7 @@ # helpful hints at -# http://aprs.gids.nl/nmea/#gsv +# https://aprs.gids.nl/nmea/#gsv def handle_gsv(gsv_state, a): global sats s_nmsg, s_imsg, s_nsat = gsv_state @@ -70,7 +70,7 @@ def nmea_line(gsv_state, ll, verbose=False): if aa[0] == "GPGSV": gsv_state = handle_gsv(gsv_state, aa[1:]) if aa[0] == "GPGGA" and len(aa) > 6: - # helpful hints at http://aprs.gids.nl/nmea/#gga + # helpful hints at https://aprs.gids.nl/nmea/#gga # note the weird time format: "060534.000" means # 06:05:34.000 Z # note the weird lat/lon format: "3752.6812 N" means @@ -82,7 +82,7 @@ def nmea_line(gsv_state, ll, verbose=False): pl = utc_time, lat, aa[3], lon, aa[5] print("GPS time %s coordinates %.6f %s, %.6f %s" % pl) if aa[0] == "GPRMC" and len(aa) > 9: - # helpful hints at http://aprs.gids.nl/nmea/#rmc + # helpful hints at https://aprs.gids.nl/nmea/#rmc # same weird formats as above, plus date "111222" means 2022-12-11 gt = aa[1] utc_time = gt[0:2] + ":" + gt[2:4] + ":" + gt[4:] + " Z" diff --git a/rtsim/param.py b/rtsim/param.py index fedb0edf3..1e0006f03 100644 --- a/rtsim/param.py +++ b/rtsim/param.py @@ -2,7 +2,7 @@ from numpy import exp as cexp from numpy import ceil -# http://stackoverflow.com/questions/14132789/python-relative-imports-for-the-billionth-time +# https://stackoverflow.com/questions/14132789/relative-imports-for-the-billionth-time # Leaves me with only one choice ... :( # Since I don't want to modify shell variables import os diff --git a/serial_io/EVG_EVR/NMEA.c b/serial_io/EVG_EVR/NMEA.c index 5d0ad9da0..0a1a6f788 100644 --- a/serial_io/EVG_EVR/NMEA.c +++ b/serial_io/EVG_EVR/NMEA.c @@ -34,7 +34,7 @@ static int satellitesInView = -1; /* * Returns number of days since civil 1970-01-01 - * Ref: http://howardhinnant.github.io/date_algorithms.html#days_from_civil + * Ref: https://howardhinnant.github.io/date_algorithms.html#days_from_civil */ static int days_from_civil(int y, unsigned m, unsigned d) diff --git a/serial_io/crc16.v b/serial_io/crc16.v index cd5ef4156..75a7d2ebc 100644 --- a/serial_io/crc16.v +++ b/serial_io/crc16.v @@ -13,7 +13,7 @@ module crc16( // D is the 16-bit input data (msb-first) // crc and O are the new and old 16-bit CRC // Generating polynomial is 0x1021 (normal form, leading 1 suppressed) - // Reference: http://en.wikipedia.org/wiki/Cyclic_redundancy_check + // Reference: https://en.wikipedia.org/wiki/Cyclic_redundancy_check crc[0] <= D[0]^O[0]^D[4]^O[4]^D[8]^O[8]^D[11]^O[11]^D[12]^O[12]; crc[1] <= D[1]^O[1]^D[5]^O[5]^D[9]^O[9]^D[12]^O[12]^D[13]^O[13]; crc[2] <= D[2]^O[2]^D[6]^O[6]^D[10]^O[10]^D[13]^O[13]^D[14]^O[14]; diff --git a/serial_io/negotiate.v b/serial_io/negotiate.v index 2de8392d3..a5a99a321 100644 --- a/serial_io/negotiate.v +++ b/serial_io/negotiate.v @@ -263,7 +263,7 @@ module negotiate( // 16-bit Ethernet configuration register as documented in // Networking Protocol Fundamentals, by James Long - // and http://grouper.ieee.org/groups/802/3/z/public/presentations/nov1996/RTpcs8b_sum5.pdf + // and https://grouper.ieee.org/groups/802/3/z/public/presentations/nov1996/RTpcs8b_sum5.pdf reg FD=1; // Full Duplex capable wire HD=0; // Half Duplex capable wire PS1=0; // Pause 1 diff --git a/soc/picorv32/project/kc705/sim/i2c_model.v b/soc/picorv32/project/kc705/sim/i2c_model.v index 6a70ae279..a68c64cb2 100644 --- a/soc/picorv32/project/kc705/sim/i2c_model.v +++ b/soc/picorv32/project/kc705/sim/i2c_model.v @@ -1,4 +1,4 @@ -// http://www.fpga4fun.com/I2C_2.html +// https://www.fpga4fun.com/I2C_2.html module i2c_model #( parameter I2C_ADR = 7'h27 ) ( From df41fd60c50342f842b5e74b171e09ef83a9cdec Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Sat, 7 Sep 2024 00:14:39 -0700 Subject: [PATCH 26/75] Update a bunch of URLs Most of the old ones gave HTTP 301 Moved Permanently --- CONTRIBUTING.md | 4 ++-- README.md | 4 ++-- badger/tests/ac701/ac701_rgmii.xdc | 2 +- badger/tests/gtkw_print.tcl | 2 +- badger/tests/kc705/kc705_gmii.xdc | 2 +- board_support/marblemini/marble.cfg | 2 +- board_support/zest/README.md | 2 +- build-tools/make-demo/makefile.md.in | 2 +- build-tools/makefile.md | 2 +- build-tools/riscv_meta.sh | 2 +- dsp/via.v | 2 +- fpga_family/xilinx/IDDR.v | 2 +- peripheral_drivers/i2cbridge/i2c_slave_model.v | 2 +- projects/test_marble_family/bringup.txt | 2 +- projects/test_marble_family/fmc_test_iam.py | 2 +- projects/test_marble_family/fmc_test_l.py | 2 +- soc/picorv32/README.md | 4 ++-- soc/picorv32/project/cmod_a7/common/test.c | 4 ++-- soc/picorv32/project/cmod_a7/synth/digilent_cmod_a7.cfg | 2 +- soc/picorv32/rules.mk | 2 +- soc/picorv32/test/badger_lwip/README.md | 2 +- 21 files changed, 25 insertions(+), 25 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e70327d6d..56b44ccd6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -105,7 +105,7 @@ a git commit ID (or similar) instead. PDF and object files often take extra effort to make reproducible. FPGA bitfiles are not typically shown to be reproducible, but Xilinx -[acknowledges](https://support.xilinx.com/s/article/61599) that is a +[acknowledges](https://adaptivesupport.amd.com/s/article/61599) that is a reasonable goal (they call it "repeatable"). Our toolchain has demonstrated this working in at least couple of cases. @@ -164,7 +164,7 @@ to represent logical indentation level has advantages; people's setting of tab width can systematically and locally adjust the visual indentation level. Just like Wikipedia's English vs. American spelling policy, don't gratuitously change the tab vs. spaces convention of a file. See also -[Silicon Valley - S03E06 - Tabs versus Spaces](https://www.youtube.com/watch?v=SsoOG6ZeyUI) (2:50). +[Silicon Valley - S03E06 - Tabs versus Spaces](https://www.youtube.com/watch?v=cowtgmZuai0) (2:01). Special case for python files: No tabs, per [PEP8](https://www.python.org/dev/peps/pep-0008/) diff --git a/README.md b/README.md index ef95e408c..d3f012406 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Overview ======== -Bedrock generated documentation: https://berkeleylab.github.io/Bedrock +Bedrock generated documentation: https://berkeleylab.github.io/Bedrock/ [Bedrock](https://gitlab.lbl.gov/hdl-libraries/bedrock) is largely an accumulation of Verilog codebase written over the past several years at LBNL. It contains @@ -33,7 +33,7 @@ A few comments regarding the codebase 1. All software is set up to easily run on *nix systems. 2. Currently everything is [built using GNU Make](build-tools/makefile.md). We are on an active lookout for other methods, if they're actually better for us. -3. iverilog is used for simulation. We are slowly starting to use [Verilator](https://www.veripool.org/wiki/verilator) as well +3. iverilog is used for simulation. We are slowly starting to use [Verilator](https://www.veripool.org/wiki/verilator/) as well (see badger) 4. Xilinx tools are used for synthesis, and starting to support [YoSys](https://yosyshq.net/yosys/) (again see badger) 5. This repository is connected to Gitlab CI. All simulation based tests run diff --git a/badger/tests/ac701/ac701_rgmii.xdc b/badger/tests/ac701/ac701_rgmii.xdc index 8eec1e2d1..3a6b7cf84 100644 --- a/badger/tests/ac701/ac701_rgmii.xdc +++ b/badger/tests/ac701/ac701_rgmii.xdc @@ -15,7 +15,7 @@ set_property -dict {PACKAGE_PIN U15 IOSTANDARD HSTL_I_18} [get_ports {RGMII_TXD[ set_property -dict {PACKAGE_PIN T18 IOSTANDARD HSTL_I_18} [get_ports {RGMII_TXD[2]}] set_property -dict {PACKAGE_PIN T17 IOSTANDARD HSTL_I_18} [get_ports {RGMII_TXD[3]}] -# https://www.xilinx.com/support/answers/53092.html +# https://adaptivesupport.amd.com/s/article/53092 set_property IOB TRUE [get_ports {RGMII_TXD[*]}] set_property IOB TRUE [get_ports RGMII_TX_CTRL] set_property IOB TRUE [get_ports {RGMII_RXD[*]}] diff --git a/badger/tests/gtkw_print.tcl b/badger/tests/gtkw_print.tcl index 9a46962be..e6558968b 100644 --- a/badger/tests/gtkw_print.tcl +++ b/badger/tests/gtkw_print.tcl @@ -4,6 +4,6 @@ set n1 [ string length $fn ] set n2 [ string last ".vcd" $fn ] if { $n2+4==$n1 } { set fpdf [ string range $fn 0 [ expr $n2-1 ] ] } else { set fpdf $fn } append fpdf ".pdf" -# https://github.com/acklinr/gtkwave/blob/master/examples/des.tcl +# https://github.com/gtkwave/gtkwave/blob/master/examples/des.tcl gtkwave::/File/Print_To_File PDF {Letter (8.5" x 11")} Full $fpdf gtkwave::/File/Quit diff --git a/badger/tests/kc705/kc705_gmii.xdc b/badger/tests/kc705/kc705_gmii.xdc index a6838c5a9..5b72bcd44 100644 --- a/badger/tests/kc705/kc705_gmii.xdc +++ b/badger/tests/kc705/kc705_gmii.xdc @@ -26,7 +26,7 @@ set_property -dict {PACKAGE_PIN K26 IOSTANDARD LVCMOS25} [get_ports {GMII_TXD[5] set_property -dict {PACKAGE_PIN L30 IOSTANDARD LVCMOS25} [get_ports {GMII_TXD[6]}] set_property -dict {PACKAGE_PIN J28 IOSTANDARD LVCMOS25} [get_ports {GMII_TXD[7]}] -# https://www.xilinx.com/support/answers/53092.html +# https://adaptivesupport.amd.com/s/article/53092 set_property IOB TRUE [get_ports GMII_TXD[*]] set_property IOB TRUE [get_ports GMII_TX_EN] set_property IOB TRUE [get_ports GMII_RXD[*]] diff --git a/board_support/marblemini/marble.cfg b/board_support/marblemini/marble.cfg index 807b2b71f..f28768a4f 100644 --- a/board_support/marblemini/marble.cfg +++ b/board_support/marblemini/marble.cfg @@ -1,5 +1,5 @@ # openocd config file for Marble Mini -# https://github.com/BerkeleyLab/Marble-mini +# https://github.com/BerkeleyLab/Marble-Mini interface ftdi diff --git a/board_support/zest/README.md b/board_support/zest/README.md index 3b8cbefee..79bfd962c 100644 --- a/board_support/zest/README.md +++ b/board_support/zest/README.md @@ -1,6 +1,6 @@ Zest is a dual LPC FMC mezzanine board with 8 ADCs and 2 DACs. -Full information about the Zest hardware is at: https://github.com/BerkeleyLab/zest +Full information about the Zest hardware is at: https://github.com/BerkeleyLab/Zest ### Using zest_setup.py diff --git a/build-tools/make-demo/makefile.md.in b/build-tools/make-demo/makefile.md.in index 11cf1bcca..49f55f22a 100644 --- a/build-tools/make-demo/makefile.md.in +++ b/build-tools/make-demo/makefile.md.in @@ -135,7 +135,7 @@ There have been [many attempts](https://en.wikipedia.org/wiki/List_of_build_auto continuing today, to build on, enhance, or replace make. Two in particular attempt to address the needs of an HDL environment. - * [Hdlmake](https://www.ohwr.org/project/hdl-make/wikis/home) + * [Hdlmake](https://ohwr.org/project/hdl-make/-/wikis/home) * [FuseSoC](https://pypi.org/project/fusesoc/) Our experiments with these tools have generally been frustrating. diff --git a/build-tools/makefile.md b/build-tools/makefile.md index 7cbfc437b..147a70a7f 100644 --- a/build-tools/makefile.md +++ b/build-tools/makefile.md @@ -205,7 +205,7 @@ There have been [many attempts](https://en.wikipedia.org/wiki/List_of_build_auto continuing today, to build on, enhance, or replace make. Two in particular attempt to address the needs of an HDL environment. - * [Hdlmake](https://www.ohwr.org/project/hdl-make/wikis/home) + * [Hdlmake](https://ohwr.org/project/hdl-make/-/wikis/home) * [FuseSoC](https://pypi.org/project/fusesoc/) Our experiments with these tools have generally been frustrating. diff --git a/build-tools/riscv_meta.sh b/build-tools/riscv_meta.sh index aaa1cbecc..655a9155b 100644 --- a/build-tools/riscv_meta.sh +++ b/build-tools/riscv_meta.sh @@ -17,7 +17,7 @@ # Same gcc version, in fact! Slightly different configuration. # # I tried to peek at -# https://github.com/riscv/riscv-gnu-toolchain +# https://github.com/riscv-collab/riscv-gnu-toolchain # but that's kind of obfuscated. # http://www.ifp.illinois.edu/~nakazato/tips/xgcc.html # is more to-the-point, but out-of-date (2007). diff --git a/dsp/via.v b/dsp/via.v index 5e4fdbba4..c79b5c3cd 100644 --- a/dsp/via.v +++ b/dsp/via.v @@ -1,4 +1,4 @@ -//https://forums.xilinx.com/t5/Welcome-Join/synthesizable-verilog-connecting-inout-pins/td-p/284628 +// https://forums.xilinx.com/t5/Welcome-Join/synthesizable-verilog-connecting-inout-pins/td-p/284628 /*module via (w, w) inout w; wire w; diff --git a/fpga_family/xilinx/IDDR.v b/fpga_family/xilinx/IDDR.v index 366c950d0..7d2cdbbcb 100644 --- a/fpga_family/xilinx/IDDR.v +++ b/fpga_family/xilinx/IDDR.v @@ -1,6 +1,6 @@ // trivial substitute for xilinx unisim models // for more info refer to -// https://www.xilinx.com/support/documentation/user_guides/ug471_7Series_SelectIO.pdf +// https://docs.amd.com/go/en-US/ug471_7Series_SelectIO module IDDR #( parameter DDR_CLK_EDGE="SAME_EDGE_PIPELINED" diff --git a/peripheral_drivers/i2cbridge/i2c_slave_model.v b/peripheral_drivers/i2cbridge/i2c_slave_model.v index 1f0b3527b..f0ce4f1b9 100644 --- a/peripheral_drivers/i2cbridge/i2c_slave_model.v +++ b/peripheral_drivers/i2cbridge/i2c_slave_model.v @@ -6,7 +6,7 @@ //// Authors: Richard Herveille (richard@asics.ws) www.asics.ws //// //// John Sheahan (jrsheahan@optushome.com.au) //// //// //// -//// Downloaded from: https://www.opencores.org/projects/i2c/ //// +//// Downloaded from: https://opencores.org/projects/i2c/ //// //// //// ///////////////////////////////////////////////////////////////////// //// //// diff --git a/projects/test_marble_family/bringup.txt b/projects/test_marble_family/bringup.txt index 43fc38060..dc624107f 100644 --- a/projects/test_marble_family/bringup.txt +++ b/projects/test_marble_family/bringup.txt @@ -78,7 +78,7 @@ cmp /tmp/f2 /tmp/c2 # LPC1776, seems to work OK using OpenOCD from either git master # or stock Debian Buster. -git clone https://github.com/richardeoin/lpc-toolchain.git +git clone https://github.com/richardeoin/lpc-toolchain git checkout LPC1769 patch -p1 < marble-lpc1776.patch # apt-get install gcc-arm-none-eabi diff --git a/projects/test_marble_family/fmc_test_iam.py b/projects/test_marble_family/fmc_test_iam.py index 342704d27..de14623b8 100644 --- a/projects/test_marble_family/fmc_test_iam.py +++ b/projects/test_marble_family/fmc_test_iam.py @@ -1,5 +1,5 @@ # PoC Marble FMC tester based on IAM Electronic FPGA Mezzanine Card (FMC) Loopback Module -# https://www.iamelectronic.com/shop/produkt/fpga-mezzanine-card-fmc-loopback-module +# https://www.iamelectronic.com/shop/produkt/fpga-mezzanine-card-fmc-loopback-module/ # Still doesn't cover LA_1 to GBTCLK0_M2C or LA_18 to GBTCLK1_M2C (HPC) import sys diff --git a/projects/test_marble_family/fmc_test_l.py b/projects/test_marble_family/fmc_test_l.py index e6a485fe9..c31a7fd2d 100644 --- a/projects/test_marble_family/fmc_test_l.py +++ b/projects/test_marble_family/fmc_test_l.py @@ -1,5 +1,5 @@ # Mapping functions to support CERN's OHWR FMC Carrier Tester board -# https://www.ohwr.org/project/fmc-conn-tester/wikis/home +# https://ohwr.org/project/fmc-conn-tester/-/wikis/home # a703f7f70230f579a87bd9c17df9f9591a629c91d9f8a5fc84de695a3bcf9ae3 EDA-02327-V1-0_sch.pdf # specifically its connectivity between the LA bank and I2C port expanders diff --git a/soc/picorv32/README.md b/soc/picorv32/README.md index f1f8a54e4..4075b66bf 100644 --- a/soc/picorv32/README.md +++ b/soc/picorv32/README.md @@ -26,7 +26,7 @@ An open-source system on a chip based on the [PicoRV32](https://github.com/Yosys * build and install `picolibc` into `/usr/local/picolibc` following its building [instructions](https://github.com/picolibc/picolibc/blob/main/doc/build.md): ```bash mkdir -p /usr/local/picolibc -git clone https://github.com/picolibc/picolibc.git +git clone https://github.com/picolibc/picolibc cd picolibc mkdir build-riscv64-unknown-elf cd build-riscv64-unknown-elf @@ -78,7 +78,7 @@ Within each project directory, use `make` to synthesize a bitstream file. Use `make system_config` to program the FPGA with a bitstream file, using `xc3sprog` or Digilent Adept2, which is available from -[digilent](https://reference.digilentinc.com/reference/software/adept/start?redirect=1#software_downloads). +[digilent](https://digilent.com/reference/software/adept/start). ## Reload CPU program without re-synthesizing diff --git a/soc/picorv32/project/cmod_a7/common/test.c b/soc/picorv32/project/cmod_a7/common/test.c index 0db3542e5..1623218db 100644 --- a/soc/picorv32/project/cmod_a7/common/test.c +++ b/soc/picorv32/project/cmod_a7/common/test.c @@ -24,7 +24,7 @@ unsigned xorshift32(unsigned *state) int cmd_memtest(volatile unsigned *base, unsigned len, unsigned stride, unsigned cycles) { // adapted from: - // https://github.com/cliffordwolf/picorv32/blob/master/picosoc/firmware.c + // https://github.com/YosysHQ/picorv32/blob/master/picosoc/firmware.c unsigned state; volatile uint8_t *base_byte = (volatile uint8_t*)base; @@ -68,7 +68,7 @@ int cmd_memtest(volatile unsigned *base, unsigned len, unsigned stride, unsigned // A simple Sieve of Eratosthenes // copied from: -// https://github.com/cliffordwolf/picorv32/blob/master/firmware/sieve.c +// https://github.com/YosysHQ/picorv32/blob/master/firmware/sieve.c static unsigned bitmap[BITMAP_SIZE/32]; static unsigned hash; diff --git a/soc/picorv32/project/cmod_a7/synth/digilent_cmod_a7.cfg b/soc/picorv32/project/cmod_a7/synth/digilent_cmod_a7.cfg index ac4487b5f..2cf86438a 100644 --- a/soc/picorv32/project/cmod_a7/synth/digilent_cmod_a7.cfg +++ b/soc/picorv32/project/cmod_a7/synth/digilent_cmod_a7.cfg @@ -1,7 +1,7 @@ # # Digilent Cmod A7 Xilinx Artix-7 FPGA # -# https://store.digilentinc.com/cmod-a7-breadboardable-artix-7-fpga-module/ +# https://digilent.com/shop/cmod-a7-35t-breadboardable-artix-7-fpga-module/ # # iManufacturer 1 Digilent diff --git a/soc/picorv32/rules.mk b/soc/picorv32/rules.mk index 6ff8fad88..20a1f4697 100644 --- a/soc/picorv32/rules.mk +++ b/soc/picorv32/rules.mk @@ -19,7 +19,7 @@ CCSPECS = -specs=picolibc.specs CLFLAGS = -march=rv32imc -mabi=ilp32 -ffreestanding -DBLOCK_RAM_SIZE=$(BLOCK_RAM_SIZE) -nostartfiles $(CCSPECS) CFLAGS = -std=c99 -Os -Wall -Wextra -Wundef -Wstrict-prototypes $(CLFLAGS) LDFLAGS = $(CLFLAGS) -Wl,--strip-debug,--print-memory-usage,-Bstatic,-Map,$*.map,--defsym,BLOCK_RAM_SIZE=$(BLOCK_RAM_SIZE),--gc-sections,--no-relax -T$(filter %.lds, $^) -# --no-relax is a workaround for https://github.com/riscv/riscv-binutils-gdb/issues/144 +# --no-relax is a workaround for https://github.com/riscvarchive/riscv-binutils-gdb/issues/144 # --verbose=3,-M for verbose linker output / debugging %.lst: %.elf diff --git a/soc/picorv32/test/badger_lwip/README.md b/soc/picorv32/test/badger_lwip/README.md index b8686c7cf..5260a2a32 100644 --- a/soc/picorv32/test/badger_lwip/README.md +++ b/soc/picorv32/test/badger_lwip/README.md @@ -34,7 +34,7 @@ sudo ip link set dev tap0 up * to demonstrate DHCP, uncomment `dhcp_start(&netif);` and run a DHCP server on the local TAP0 network -### (Bridging)[https://wiki.archlinux.org/index.php/Network_bridge] tap0 +### (Bridging)[https://wiki.archlinux.org/title/Network_bridge] tap0 A bridge is like a virtual network switch, connecting two or more links together (here tap0 and eth0). This allows the Verilog simulation to access the Internet. ```bash From aeb09e616c69c5d04449b174220f1f3a48746c8b Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Sat, 7 Sep 2024 15:41:04 -0700 Subject: [PATCH 27/75] More URL touch-up Recover a few lost links, especially for Xilinx UG and support articles Avoid a few more 301 Moved Permanently Delegating ci/README.org updates to Vamsi --- CONTRIBUTING.md | 2 +- README.md | 2 +- badger/tests/ac701/ac701_rgmii.xdc | 2 +- badger/tests/kc705/kc705_gmii.xdc | 2 +- board_support/sp605/base.ucf | 6 +++--- board_support/sp605/mgt.ucf | 4 ++-- board_support/sp605/sp605_mgt_gmii_base.ucf | 6 +++--- build-tools/riscv_meta.sh | 1 + cordic/README | 2 +- dsp/via.v | 2 +- fpga_family/spartan6/adc_cells.v | 7 ++++--- projects/trigger_capture/platforms/marble.py | 2 +- soc/picorv32/test/memio/spiflash.v | 2 +- 13 files changed, 21 insertions(+), 19 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 56b44ccd6..27d093dd5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -105,7 +105,7 @@ a git commit ID (or similar) instead. PDF and object files often take extra effort to make reproducible. FPGA bitfiles are not typically shown to be reproducible, but Xilinx -[acknowledges](https://adaptivesupport.amd.com/s/article/61599) that is a +[acknowledges](https://adaptivesupport.amd.com/s/article/61599?language=en_US) that is a reasonable goal (they call it "repeatable"). Our toolchain has demonstrated this working in at least couple of cases. diff --git a/README.md b/README.md index d3f012406..d1e1355aa 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ A few comments regarding the codebase 1. All software is set up to easily run on *nix systems. 2. Currently everything is [built using GNU Make](build-tools/makefile.md). We are on an active lookout for other methods, if they're actually better for us. -3. iverilog is used for simulation. We are slowly starting to use [Verilator](https://www.veripool.org/wiki/verilator/) as well +3. iverilog is used for simulation. We are slowly starting to use [Verilator](https://www.veripool.org/verilator/) as well (see badger) 4. Xilinx tools are used for synthesis, and starting to support [YoSys](https://yosyshq.net/yosys/) (again see badger) 5. This repository is connected to Gitlab CI. All simulation based tests run diff --git a/badger/tests/ac701/ac701_rgmii.xdc b/badger/tests/ac701/ac701_rgmii.xdc index 3a6b7cf84..37bba2b79 100644 --- a/badger/tests/ac701/ac701_rgmii.xdc +++ b/badger/tests/ac701/ac701_rgmii.xdc @@ -15,7 +15,7 @@ set_property -dict {PACKAGE_PIN U15 IOSTANDARD HSTL_I_18} [get_ports {RGMII_TXD[ set_property -dict {PACKAGE_PIN T18 IOSTANDARD HSTL_I_18} [get_ports {RGMII_TXD[2]}] set_property -dict {PACKAGE_PIN T17 IOSTANDARD HSTL_I_18} [get_ports {RGMII_TXD[3]}] -# https://adaptivesupport.amd.com/s/article/53092 +# https://adaptivesupport.amd.com/s/article/53092?language=en_US set_property IOB TRUE [get_ports {RGMII_TXD[*]}] set_property IOB TRUE [get_ports RGMII_TX_CTRL] set_property IOB TRUE [get_ports {RGMII_RXD[*]}] diff --git a/badger/tests/kc705/kc705_gmii.xdc b/badger/tests/kc705/kc705_gmii.xdc index 5b72bcd44..114218b81 100644 --- a/badger/tests/kc705/kc705_gmii.xdc +++ b/badger/tests/kc705/kc705_gmii.xdc @@ -26,7 +26,7 @@ set_property -dict {PACKAGE_PIN K26 IOSTANDARD LVCMOS25} [get_ports {GMII_TXD[5] set_property -dict {PACKAGE_PIN L30 IOSTANDARD LVCMOS25} [get_ports {GMII_TXD[6]}] set_property -dict {PACKAGE_PIN J28 IOSTANDARD LVCMOS25} [get_ports {GMII_TXD[7]}] -# https://adaptivesupport.amd.com/s/article/53092 +# https://adaptivesupport.amd.com/s/article/53092?language=en_US set_property IOB TRUE [get_ports GMII_TXD[*]] set_property IOB TRUE [get_ports GMII_TX_EN] set_property IOB TRUE [get_ports GMII_RXD[*]] diff --git a/board_support/sp605/base.ucf b/board_support/sp605/base.ucf index 68a5e1334..85bf4021d 100644 --- a/board_support/sp605/base.ucf +++ b/board_support/sp605/base.ucf @@ -1,10 +1,10 @@ # Xilinx SP605 (Spartan-6 XC6SLX45T-FGG484) -# as documented in ug526.pdf -# http://www.xilinx.com/support/documentation/sp605.htm +# as documented in UG526 +# https://docs.amd.com/v/u/en-US/ug526 # Table 1-9: Ethernet PHY Connections # Connections to Marvell 88E1111 shown in comments -# http://www.marvell.com/products/tranceivers/alaska_gigabit_ethernet_transceivers/Alaska_88E1111-002.pdf +# https://www.marvell.com/content/dam/marvell/en/public-collateral/transceivers/marvell-phys-transceivers-alaska-88e1111-datasheet.pdf ##------- Pin Constraints ------- ## 200 MHz Clock input diff --git a/board_support/sp605/mgt.ucf b/board_support/sp605/mgt.ucf index 7d9b9c953..c13d3d8eb 100644 --- a/board_support/sp605/mgt.ucf +++ b/board_support/sp605/mgt.ucf @@ -1,6 +1,6 @@ # Xilinx SP605 (Spartan-6 XC6SLX45T-FGG484) -# as documented in ug526.pdf -# http://www.xilinx.com/support/documentation/sp605.htm +# as documented in UG526 +# https://docs.amd.com/v/u/en-US/ug526 ##------- Pin Constraints ------- ## GTP Mapping diff --git a/board_support/sp605/sp605_mgt_gmii_base.ucf b/board_support/sp605/sp605_mgt_gmii_base.ucf index d868ed565..aabe0bc08 100644 --- a/board_support/sp605/sp605_mgt_gmii_base.ucf +++ b/board_support/sp605/sp605_mgt_gmii_base.ucf @@ -1,10 +1,10 @@ # Xilinx SP605 (Spartan-6 XC6SLX45T-FGG484) -# as documented in ug526.pdf -# http://www.xilinx.com/support/documentation/sp605.htm +# as documented in UG526 +# https://docs.amd.com/v/u/en-US/ug526 # Table 1-9: Ethernet PHY Connections # Connections to Marvell 88E1111 shown in comments -# http://www.marvell.com/products/tranceivers/alaska_gigabit_ethernet_transceivers/Alaska_88E1111-002.pdf +# https://www.marvell.com/content/dam/marvell/en/public-collateral/transceivers/marvell-phys-transceivers-alaska-88e1111-datasheet.pdf ##------- Pin Constraints ------- diff --git a/build-tools/riscv_meta.sh b/build-tools/riscv_meta.sh index 655a9155b..20904d010 100644 --- a/build-tools/riscv_meta.sh +++ b/build-tools/riscv_meta.sh @@ -20,6 +20,7 @@ # https://github.com/riscv-collab/riscv-gnu-toolchain # but that's kind of obfuscated. # http://www.ifp.illinois.edu/~nakazato/tips/xgcc.html +# (link is dead, but document can be found at archive.org) # is more to-the-point, but out-of-date (2007). # The numbered flow below is straight from nakazato. # This script is meant to be as short, sweet, and concrete as possible. diff --git a/cordic/README b/cordic/README index 243350588..f8d075d29 100644 --- a/cordic/README +++ b/cordic/README @@ -9,7 +9,7 @@ See LICENSE.md, enclosed. Good reference material on CORDIC hardware in general is given by Ray Andraka at - http://www.andraka.com/cordic.php + http://andraka.com/cordic.php and of course see the general and long-winded background at https://en.wikipedia.org/wiki/CORDIC diff --git a/dsp/via.v b/dsp/via.v index c79b5c3cd..8f4eb964d 100644 --- a/dsp/via.v +++ b/dsp/via.v @@ -1,4 +1,4 @@ -// https://forums.xilinx.com/t5/Welcome-Join/synthesizable-verilog-connecting-inout-pins/td-p/284628 +// https://adaptivesupport.amd.com/s/question/0D52E00006iHrFnSAK/synthesizable-verilog-connecting-inout-pins?language=en_US /*module via (w, w) inout w; wire w; diff --git a/fpga_family/spartan6/adc_cells.v b/fpga_family/spartan6/adc_cells.v index 37872c03b..633b6a7b8 100644 --- a/fpga_family/spartan6/adc_cells.v +++ b/fpga_family/spartan6/adc_cells.v @@ -41,9 +41,10 @@ module adc_cells( wire adc_iddr2_rst=1'b0; wire adc_iddr2_set=1'b0; wire adc_iddr2_ce=1'b1; - // IDDR2 primitive of sp6 - // Refer to http://www.xilinx.com/support/documentation/sw_manuals/xilinx13_4/spartan6_hdl.pdf - // page 56 for ddr_alignment + // IDDR2 primitive of Spartan-6 + // Refer to UG615 + // https://docs.amd.com/v/u/en-US/spartan6_hdl + // page 124 for ddr_alignment genvar ix; generate for (ix=0; ix Date: Tue, 17 Sep 2024 14:33:19 -0700 Subject: [PATCH 28/75] reverse_json.py: accept signal definitions based on output ports Also fuss with formatting and a diagnostic message --- build-tools/reverse_json.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/build-tools/reverse_json.py b/build-tools/reverse_json.py index f3bf2db4d..fdab23d27 100644 --- a/build-tools/reverse_json.py +++ b/build-tools/reverse_json.py @@ -41,10 +41,9 @@ def ponder_int(s): # stderr.write('p, pv, o = %s, %d, %d\n' % (p, pv, o)) return pv - o else: - stderr.write('ERROR: parameter %s not found?\n' % p) + stderr.write('ERROR: parameter %s not found? (%s)\n' % (p, s)) else: - stderr.write("ERROR: Couldn't" + ' understand "%s", using 31\n' % - s) + stderr.write("ERROR: Couldn't" + ' understand "%s", using 31\n' % s) return r @@ -151,6 +150,10 @@ def memorize(g): m2 = re.search(r"\binput\s+(signed)?\s*\[([^:]+):0\]\s*(\w+)", line) if m2: memorize(m2.group) + if "output" in line: + m2 = re.search(r"\boutput\s+(signed)?\s*\[([^:]+):0\]\s*(\w+)", line) + if m2: + memorize(m2.group) if any(x in line for x in ["parameter", "localparam"]): # This logic can handle parameter as a statement, or in the header of a module. # It does get tripped up by the _last_ parameter of a module, From f3709965f76ce6b3518558b92d2d54d5a6dba462 Mon Sep 17 00:00:00 2001 From: Lucas Russo Date: Wed, 18 Sep 2024 09:41:33 -0700 Subject: [PATCH 29/75] .github: update actions to latest versions --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5c810def1..388ac139c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,10 +18,10 @@ jobs: fail-fast: false steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Setup python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: '3.8' @@ -49,13 +49,13 @@ jobs: make -C doc html - name: Deploy gh-pages - uses: peaceiris/actions-gh-pages@v3 + uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./doc/_build/html - name: Upload artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: badger-doc path: badger/doc/*.svg From 2f59b56203625a14efa9008e3a43ab332e7930a1 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Fri, 20 Sep 2024 12:30:01 -0700 Subject: [PATCH 30/75] flag_xdomain: add a warning message if gate is held high Not perfect, but will catch the most common anti-pattern, especially for data_xdomain. --- dsp/flag_xdomain.v | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/dsp/flag_xdomain.v b/dsp/flag_xdomain.v index 3f3fa3d45..34e92ae84 100644 --- a/dsp/flag_xdomain.v +++ b/dsp/flag_xdomain.v @@ -20,4 +20,19 @@ reg sync2_clk2=0; always @(posedge clk2) sync2_clk2 <= sync1_clk2; assign flagout_clk2 = sync2_clk2 ^ sync1_clk2; +// Step 4: (simulation-only) complain if this module is abused +// Too many people wire data_xdomain's .gate_in(1'b1) without understanding +// how the logic is supposed to work. +`ifdef SIMULATE +reg old_flagin=0, warning_sent=0; +always @(posedge clk1) begin + old_flagin <= flagin_clk1; + if (flagin_clk1 & old_flagin & ~warning_sent) begin + // Don't actually crash, at least not for now. + $display("XXXX Warning: flag_xdomain module abuse in %m XXXX"); + warning_sent <= 1; + end +end +`endif + endmodule From 4778a6b082ffa81b6955a9b2d44c214ae1b3d588 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Wed, 25 Sep 2024 14:57:13 -0700 Subject: [PATCH 31/75] minor test bench maintenance chitchat_txrx_wrap_tb.v: clean up tx_valid{0,1} signals, to not abuse flag_xdomain serial_io/patt_gen_tb.v: don't try to test pgen_rate = 1, to not abuse flag_xdomain --- serial_io/chitchat/chitchat_txrx_wrap_tb.v | 4 ++-- serial_io/patt_gen_tb.v | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/serial_io/chitchat/chitchat_txrx_wrap_tb.v b/serial_io/chitchat/chitchat_txrx_wrap_tb.v index 9466140df..58f499f26 100644 --- a/serial_io/chitchat/chitchat_txrx_wrap_tb.v +++ b/serial_io/chitchat/chitchat_txrx_wrap_tb.v @@ -113,8 +113,8 @@ module chitchat_txrx_wrap_tb; if (tx_transmit_en) val_cnt <= val_cnt + 1; end - assign tx_valid0 = (val_cnt!=0 & (val_cnt % valid_period)==0); - assign tx_valid1 = (val_cnt!=0 & (val_cnt % valid_period)==5); + assign tx_valid0 = (val_cnt!=0) & ((val_cnt % valid_period)==0) & tx_transmit_en; + assign tx_valid1 = (val_cnt!=0) & ((val_cnt % valid_period)==5) & tx_transmit_en; reg [7:0] tx_data=0; diff --git a/serial_io/patt_gen_tb.v b/serial_io/patt_gen_tb.v index 68b559095..63062c083 100644 --- a/serial_io/patt_gen_tb.v +++ b/serial_io/patt_gen_tb.v @@ -57,7 +57,7 @@ module patt_gen_tb; // ---------------------- // Generate stimulus // ---------------------- - wire [4:0] pgen_rate; + wire [4:0] pgen_rate_maybe, pgen_rate; wire pgen_test_mode; wire [2:0] pgen_inc_step; wire [15:0] pgen_usr_data; @@ -89,7 +89,9 @@ module patt_gen_tb; end end - assign {pgen_rate, pgen_test_mode, pgen_inc_step, pgen_usr_data} = rand_setup; + assign {pgen_rate_maybe, pgen_test_mode, pgen_inc_step, pgen_usr_data} = rand_setup; + // pgen_rate = 1 is invalid + assign pgen_rate = (pgen_rate_maybe == 1) ? 2 : pgen_rate_maybe; flag_xdomain i_flag_xdomain ( .clk1 (tx_clk), .flagin_clk1 (rx_valid), @@ -131,6 +133,12 @@ module patt_gen_tb; reg rx_valid_dly [DELAY_DATA-1:0]; reg [15:0] rx_data_dly [DELAY_DATA-1:0]; + // Initialize delay pipe so simulation doesn't start with a bunch of Xs + integer ix; + initial begin + for (ix=0; ix Date: Thu, 26 Sep 2024 12:51:30 -0700 Subject: [PATCH 32/75] zest.c: Renable both DACs after checking --- board_support/zest_soc/firmware/zest.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/board_support/zest_soc/firmware/zest.c b/board_support/zest_soc/firmware/zest.c index daf60b33e..c28039e81 100644 --- a/board_support/zest_soc/firmware/zest.c +++ b/board_support/zest_soc/firmware/zest.c @@ -243,6 +243,8 @@ bool check_ad9781_bist(void) { // two's complement binary mode write_zest_reg(ZEST_DEV_AD9781, 0x2, 0x0); + SET_SFR1(g_base_sfr, SFR_OUT_REG1, SFR_OUT_BIT_DAC0_ENABLE, 1); + SET_SFR1(g_base_sfr, SFR_OUT_REG1, SFR_OUT_BIT_DAC1_ENABLE, 1); return pass; } From 68530e0e9df0e503e62681b23bf7538a92fde0bb Mon Sep 17 00:00:00 2001 From: Qiang Du Date: Thu, 26 Sep 2024 19:49:37 -0700 Subject: [PATCH 33/75] board_support/marble_soc/firmware/marble.h: add switch for evr enabling --- board_support/marble_soc/firmware/marble.h | 1 + 1 file changed, 1 insertion(+) diff --git a/board_support/marble_soc/firmware/marble.h b/board_support/marble_soc/firmware/marble.h index 7b58d657b..57db91754 100644 --- a/board_support/marble_soc/firmware/marble.h +++ b/board_support/marble_soc/firmware/marble.h @@ -50,6 +50,7 @@ typedef struct marble_init_t { marble_init_byte_t pca9555_misc_data; // u39 marble_init_byte_t adn4600_data; uint64_t si570_freq_hz; + bool enable_evr_gtx; } marble_init_t; typedef struct ina219_info_t { From ff2a7e689b88203962c1ddd475058de256c61aef Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Fri, 4 Oct 2024 15:59:56 -0700 Subject: [PATCH 34/75] Move tgen from cmoc/ to localbus/ --- cmoc/Makefile | 6 +++--- cmoc/rules.mk | 4 ++-- doc/Makefile | 9 +++++++-- localbus/Makefile | 3 +++ localbus/README.md | 26 ++++++++++++++++++++++++-- localbus/localbus.vh | 6 +++--- {cmoc => localbus}/tgen.gtkw | 0 {cmoc => localbus}/tgen.v | 0 {cmoc => localbus}/tgen_seq.dat | 0 {cmoc => localbus}/tgen_tb.v | 0 10 files changed, 42 insertions(+), 12 deletions(-) rename {cmoc => localbus}/tgen.gtkw (100%) rename {cmoc => localbus}/tgen.v (100%) rename {cmoc => localbus}/tgen_seq.dat (100%) rename {cmoc => localbus}/tgen_tb.v (100%) diff --git a/cmoc/Makefile b/cmoc/Makefile index 072bb162c..e7bb10443 100644 --- a/cmoc/Makefile +++ b/cmoc/Makefile @@ -1,6 +1,6 @@ include ../dir_list.mk -vpath %.v $(RTSIM_DIR) $(DSP_DIR) $(DSP_DIR)/hosted $(BADGER_DIR) +vpath %.v $(RTSIM_DIR) $(DSP_DIR) $(DSP_DIR)/hosted $(BEDROCK_DIR)/localbus $(BADGER_DIR) vpath %.c ../badger/tests .PHONY: all @@ -11,14 +11,14 @@ include $(BADGER_DIR)/rules.mk NEWAD_ARGS += -y -TEST_BENCH = xy_pi_clip_tb fdbk_core_tb tgen_tb circle_buf_tb cryomodule_tb cryomodule_badger_tb rf_controller_tb +TEST_BENCH = xy_pi_clip_tb fdbk_core_tb circle_buf_tb cryomodule_tb cryomodule_badger_tb rf_controller_tb RTEFI_CLIENT_LIST = hello.v speed_test.v mem_gateway.v include rules.mk TGT_ := $(TEST_BENCH) -NO_CHECK = tgen_check cryomodule_badger_check rf_controller_check +NO_CHECK = cryomodule_badger_check rf_controller_check CHK_ = $(filter-out $(NO_CHECK), $(TEST_BENCH:%_tb=%_check)) NO_LINT = $(NO_CHECK) LNT_ = $(filter-out $(NO_LINT), $(TEST_BENCH:%_tb=%_lint)) diff --git a/cmoc/rules.mk b/cmoc/rules.mk index 500267ab5..fe7d62f55 100644 --- a/cmoc/rules.mk +++ b/cmoc/rules.mk @@ -2,11 +2,11 @@ include $(CORDIC_DIR)/rules.mk include $(DSP_DIR)/lo_lut/rules.mk # be lazy about dependencies -VFLAGS += -y. -I. -y$(RTSIM_DIR) -y$(DSP_DIR) -y$(DSP_DIR)/hosted -y$(CORDIC_DIR) -y$(BADGER_DIR) -y_autogen +VFLAGS += -y. -I. -y$(RTSIM_DIR) -y$(DSP_DIR) -y$(DSP_DIR)/hosted -y$(CORDIC_DIR) -y$(BADGER_DIR) -y$(BEDROCK_DIR)/localbus -y_autogen LB_AW = 15 NEWAD_ARGS += -m -l -NEWAD_DIRS += $(DSP_DIR) $(DSP_DIR)/hosted $(RTSIM_DIR) $(CMOC_DIR) +NEWAD_DIRS += $(DSP_DIR) $(DSP_DIR)/hosted $(RTSIM_DIR) $(CMOC_DIR) $(BEDROCK_DIR)/localbus VERILOG_AUTOGEN += "cordicg_b22.v" diff --git a/doc/Makefile b/doc/Makefile index 1f2737bf4..91e1801ea 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -26,6 +26,10 @@ GEN_DIR = _gen_rst GEN_MD_DIR = _gen_md GEN_SRC_DIR = _gen_src_rst +# Works for now, but is an indication that our makefiles need work +VCD_ARGS = $(VCD_ARGS_$@) +VCD_ARGS_tgen.vcd = +tgen_seq=../localbus/tgen_seq.dat + # No need to specify directory for each of these, thanks to the magic of make's vpath. SRC = \ afterburner.v \ @@ -97,6 +101,7 @@ SRC = \ serializer_multichannel.v \ serialize.v \ shortfifo.v \ + tgen.v \ timestamp.v \ tt800.v \ upconv.v \ @@ -160,7 +165,7 @@ SRC_SVG = \ build-tools/cdc_OK1.svg \ build-tools/cdc_OKX.svg -DIRS = $(DSP_DIR) $(BADGER_DIR) $(CORDIC_DIR) $(PICORV_DIR) $(HOMELESS_DIR) $(SERIAL_IO_DIR)/EVG_EVR +DIRS = $(DSP_DIR) $(BADGER_DIR) $(CORDIC_DIR) $(PICORV_DIR) $(HOMELESS_DIR) $(SERIAL_IO_DIR)/EVG_EVR $(BEDROCK_DIR)/localbus VFLAGS += -y. -I. $(addprefix -y, $(DIRS)) $(addprefix -I, $(DIRS)) -y$(AUTOGEN_DIR) vpath %.v $(DIRS) @@ -302,5 +307,5 @@ clean:: include $(BUILD_DIR)/bottom_rules.mk CLEAN += $(SRC_RST) $(RST) $(BLOCK_EPS) $(BLOCK_PNG) $(TIMING_PNG) $(GEN_TB) $(addsuffix *, $(DEP_TB)) $(VCD) \ - cordicg_b22.v *_tb *.out + cordicg_b22.v *_tb *.out *.pdf CLEAN_DIRS += $(GEN_DIR) $(GEN_SRC_DIR) $(GEN_MD_DIR) diff --git a/localbus/Makefile b/localbus/Makefile index 844be550a..d07138e33 100644 --- a/localbus/Makefile +++ b/localbus/Makefile @@ -9,6 +9,7 @@ vpath %.v $(DSP_DIR) $(BADGER_DIR) $(BOARD_SUPPORT_DIR)/bmb7_kintex vpath %.c $(BADGER_DIR)/tests all: jit_rad_gateway_demo_badger jit_rad_gateway_demo_qf2 jit_rad_gateway_demo_cdc.txt Vjit_rad_gateway_demo jit_rad_gateway_check +all: tgen_tb jit_rad_gateway_demo_badger: $(BADGER_V) $(VERILOG) $(V_TB) -o $@ $^ @@ -35,6 +36,8 @@ live: Vjit_rad_gateway_demo ./Vjit_rad_gateway_demo +udp_port=3010 +trace # see README.md for suggestions for what to do with "make live" +tgen_tb: tgen.v dpram.v + clean: rm -f jit_rad_gateway_demo_badger jit_rad_gateway_demo_qf2 rm -f jit_rad_gateway_demo_cdc.txt jit_rad_gateway_demo_yosys.json diff --git a/localbus/README.md b/localbus/README.md index 00a88c6b8..35c44a3a2 100644 --- a/localbus/README.md +++ b/localbus/README.md @@ -17,10 +17,32 @@ Our use case covers real-time on-chip communication, where cycle counts are well-defined and set at configuration/synthesis time, _not_ run-time. -The key component held here is -Just In Time Readout Across Domains - [jit_rad](jit_rad.md) for short. +Components held here are +- Just In Time Readout Across Domains - [jit_rad](jit_rad.md) for short. +- localbus.vh, a helper for cycle-accurate bus simulations +- gen_regmap.py +- the much-maligned tgen, a general-purpose real-time write sequencer, + constructed as a localbus interposer; + has support in leep as assemble_tgen() and tgen_reg_sequence() + +As the jit_rad documentation explains, it's easy to shift the *write* +side of a localbus to a different clock domain. Throughput is not affected, +and the additional latency and jitter are typically irrelevant +compared to what goes on in the software and LASS host computer. +Here are the typical few lines of Verilog we use to accomplish this +clock domain shift (extracted from cmoc/cryomodule.v): +``` +wire [31:0] clk1x_data; +wire [16:0] clk1x_addr; +wire clk1x_write; +// Transfer local bus to clk1x domain +data_xdomain #(.size(32+17)) lb_to_1x( +.clk_in(lb_clk), .gate_in(lb_write), .data_in({lb_addr,lb_data}), +.clk_out(clk1x), .gate_out(clk1x_write), .data_out({clk1x_addr,clk1x_data})); +``` Also see +- [Memory gateway timing](../badger/doc/mem_gateway.svg) - [Lightweight Address Space Serialization](../badger/mem_gate.md) - Bus controller for Packet Badger [mem_gateway.v](../badger/mem_gateway.v) - Bus controller for BMB7 and QF2-pre [jxj_gate.v](../board_support/bmb7_kintex/jxj_gate.v) diff --git a/localbus/localbus.vh b/localbus/localbus.vh index c3e3c3013..edf558320 100644 --- a/localbus/localbus.vh +++ b/localbus/localbus.vh @@ -1,8 +1,8 @@ // verilog tasks for simulations -// see (Memory gateway timing)[]bedrock/badger/doc/mem_gateway.svg] +// see (Memory gateway timing)[bedrock/badger/doc/mem_gateway.svg] -// requires defining: -// localparam LB_ADW = 18; +// a verilog program that includes this file must first make declarations like: +// localparam LB_ADW = 24; // localparam LB_READ_DELAY = 3; reg lb_write=0, lb_read=0, lb_prefill=0; diff --git a/cmoc/tgen.gtkw b/localbus/tgen.gtkw similarity index 100% rename from cmoc/tgen.gtkw rename to localbus/tgen.gtkw diff --git a/cmoc/tgen.v b/localbus/tgen.v similarity index 100% rename from cmoc/tgen.v rename to localbus/tgen.v diff --git a/cmoc/tgen_seq.dat b/localbus/tgen_seq.dat similarity index 100% rename from cmoc/tgen_seq.dat rename to localbus/tgen_seq.dat diff --git a/cmoc/tgen_tb.v b/localbus/tgen_tb.v similarity index 100% rename from cmoc/tgen_tb.v rename to localbus/tgen_tb.v From 0ae774690bbe30b98ac460b1a77bc1804cb1e5d6 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Fri, 4 Oct 2024 23:31:42 -0700 Subject: [PATCH 35/75] Maintainance - mostly Verilog preprocessor hygiene Also realign cmoc_top.v with marble_base() port changes and marble_top.v --- cmoc/cryomodule.v | 8 ++-- cmoc/fdbk_core.v | 1 + cmoc/llrf_shell.v | 10 ++--- cmoc/piezo_control.v | 1 + cmoc/rf_controller.v | 1 + dsp/hosted/lp_2notch.v | 1 + dsp/hosted/lp_notch.v | 1 + dsp/timestamp.v | 6 +-- fpga_family/mgt/qgt_wrap_stub.vh | 3 ++ projects/cmoc_top/marblemini/cmoc_top.v | 49 +++++++++++++-------- projects/oscope/common/digitizer_slowread.v | 11 +++-- rtsim/cav_elec.v | 1 + rtsim/cav_mech.v | 2 + rtsim/cav_mode.v | 1 + rtsim/station.v | 2 + 15 files changed, 62 insertions(+), 36 deletions(-) diff --git a/cmoc/cryomodule.v b/cmoc/cryomodule.v index f2869dc71..1b70e275a 100644 --- a/cmoc/cryomodule.v +++ b/cmoc/cryomodule.v @@ -66,6 +66,7 @@ module cryomodule( input lb_read, output [31:0] lb_out ); +`undef AUTOMATIC_self // Note that the following five parameters should all be in the range 0 to 255, // in order to be properly read out via config_data0, below. @@ -104,8 +105,7 @@ wire lb2_clk = clk1x; parameter n_cycles = n_mech_modes * 2; parameter interp_span = 4; // ceil(log2(n_cycles)) -`define SLOW_SR_LEN 4*8 -parameter sr_length = `SLOW_SR_LEN; +parameter sr_length = 4*8; `ifndef SIMPLE_DEMO // Transfer local bus to clk2x domain @@ -239,13 +239,13 @@ generate for (cavity_n=0; cavity_n < cavity_count; cavity_n=cavity_n+1) begin: c assign slow_data_ready[cavity_n] = circle_data_ready[cavity_n] & ~slow_invalid; // XXX mixes domains, simulate to make sure it's glitch-free // Make our own additions to slow shift register // equivalence circle_stat: circle_fault 1, circle_wrap 1, circle_addr 14 -`define SLOW_SR_DATA { circle_count, circle_stat } + wire [sr_length-1:0] slow_sr_data = { circle_count, circle_stat }; // TODO: These `we_*` wires below, are taken from the decode signals that are auto generated wire [7:0] slow_shell_out; reg [sr_length-1:0] slow_read=0; always @(posedge clk1x) if (slow_op) begin - slow_read <= slow_snap ? `SLOW_SR_DATA : {slow_read[sr_length-9:0],slow_shell_out}; + slow_read <= slow_snap ? slow_sr_data : {slow_read[sr_length-9:0],slow_shell_out}; end assign slow_out = slow_read[sr_length-1:sr_length-8]; diff --git a/cmoc/fdbk_core.v b/cmoc/fdbk_core.v index 604d74b78..e93e0610b 100644 --- a/cmoc/fdbk_core.v +++ b/cmoc/fdbk_core.v @@ -33,6 +33,7 @@ module fdbk_core( input [1:0] coarse_scale, // external `AUTOMATIC_self ); +`undef AUTOMATIC_self // Knobs to use/bypass CORDIC multiplexer, Magnitude/Phase processor (slow), // and Low-Latency Processor (bypassing conversion to polar coordinates) diff --git a/cmoc/llrf_shell.v b/cmoc/llrf_shell.v index 379042604..41488b339 100644 --- a/cmoc/llrf_shell.v +++ b/cmoc/llrf_shell.v @@ -56,6 +56,7 @@ module llrf_shell( `AUTOMATIC_self ); +`undef AUTOMATIC_self `AUTOMATIC_decode @@ -103,13 +104,12 @@ timestamp ts(.clk(clk), .aux_trig(1'b0), .slow_op(slow_op), .slow_snap(slow_snap // changing other controls. tag_now shows the value of tag at the end-time of // the buffer, tag_old shows it at the begin-time of the buffer. Not perfect // because of non-boxcar filtering and sloppy pipelining. -`define SLOW_SR_LEN 7*16 -`define SLOW_SR_DATA { adc1_min, adc1_max, adc2_min, adc2_max, adc3_min, adc3_max, tag_now, tag_old } -parameter sr_length = `SLOW_SR_LEN; -reg [sr_length-1:0] slow_read=0; reg [7:0] tag_old=0; +parameter sr_length = 7*16; +wire [sr_length-1:0] slow_sr_data = { adc1_min, adc1_max, adc2_min, adc2_max, adc3_min, adc3_max, tag_now, tag_old }; +reg [sr_length-1:0] slow_read=0; always @(posedge clk) if (slow_op) begin - slow_read <= slow_snap ? `SLOW_SR_DATA : {slow_read[sr_length-9:0],timestamp_out}; + slow_read <= slow_snap ? slow_sr_data : {slow_read[sr_length-9:0],timestamp_out}; if (slow_snap) tag_old <= tag_now; end assign slow_out = slow_read[sr_length-1:sr_length-8]; diff --git a/cmoc/piezo_control.v b/cmoc/piezo_control.v index 92c670af7..0203e3550 100644 --- a/cmoc/piezo_control.v +++ b/cmoc/piezo_control.v @@ -23,6 +23,7 @@ module piezo_control( output [6:0] trace_en_addr // external address for trace_en //`AUTOMATIC_self ); +`undef AUTOMATIC_self // Non-zero placeholder // Eventually intend to use reg_mac2 or similar; diff --git a/cmoc/rf_controller.v b/cmoc/rf_controller.v index 07a2617d0..f54d21107 100644 --- a/cmoc/rf_controller.v +++ b/cmoc/rf_controller.v @@ -69,6 +69,7 @@ module rf_controller ( input [7:0] tag, // external `AUTOMATIC_self ); +`undef AUTOMATIC_self `AUTOMATIC_decode diff --git a/dsp/hosted/lp_2notch.v b/dsp/hosted/lp_2notch.v index cb1d228e3..c03c501b6 100644 --- a/dsp/hosted/lp_2notch.v +++ b/dsp/hosted/lp_2notch.v @@ -13,6 +13,7 @@ module lp_2notch( output signed [19:0] y, `AUTOMATIC_self ); +`undef AUTOMATIC_self `AUTOMATIC_decode diff --git a/dsp/hosted/lp_notch.v b/dsp/hosted/lp_notch.v index e59a6425e..60197a02d 100644 --- a/dsp/hosted/lp_notch.v +++ b/dsp/hosted/lp_notch.v @@ -16,6 +16,7 @@ module lp_notch( output signed [19:0] y, `AUTOMATIC_self ); +`undef AUTOMATIC_self `AUTOMATIC_decode diff --git a/dsp/timestamp.v b/dsp/timestamp.v index 1f3a90a99..347c24db4 100644 --- a/dsp/timestamp.v +++ b/dsp/timestamp.v @@ -101,8 +101,8 @@ assign shift_in2 = aux_reg ? (apost8 ? ashiftd : axmit ? asnap_out : 0) : shift_ // Making an explicit copy like this avoids a warning when dw != 8 assign shift_out=snap_out; -// More-or-less equivalent to -// define SLOW_SR_DATA { time1, time2, time3, time4, atime1, atime2, atime3, atime4 } -// but uses far fewer resources +// More-or-less equivalent to adding +// { time1, time2, time3, time4, atime1, atime2, atime3, atime4 } +// to slow_sr_data, but uses far fewer resources endmodule diff --git a/fpga_family/mgt/qgt_wrap_stub.vh b/fpga_family/mgt/qgt_wrap_stub.vh index d171c99e5..82bf9ddec 100644 --- a/fpga_family/mgt/qgt_wrap_stub.vh +++ b/fpga_family/mgt/qgt_wrap_stub.vh @@ -151,6 +151,9 @@ `ifdef GT1_ENABLE gt1_txresetdone & gt1_rxresetdone, `else 1'b0, `endif `ifdef GT0_ENABLE gt0_txresetdone & gt0_rxresetdone `else 1'b0 `endif }; + // practice good preprocessor hygiene + `undef Q_GT_MODULE + `else // SIMULATE // Instantiate dummy components to help dependency generation and basic syntax checking diff --git a/projects/cmoc_top/marblemini/cmoc_top.v b/projects/cmoc_top/marblemini/cmoc_top.v index 953ee8489..fef249caf 100644 --- a/projects/cmoc_top/marblemini/cmoc_top.v +++ b/projects/cmoc_top/marblemini/cmoc_top.v @@ -3,33 +3,35 @@ module cmoc_top( input GTPREFCLK_N, input SYSCLK_P, - // RGMII + // RGMII Tx port output [3:0] RGMII_TXD, output RGMII_TX_CTRL, output RGMII_TX_CLK, + + // RGMII Rx port input [3:0] RGMII_RXD, input RGMII_RX_CTRL, input RGMII_RX_CLK, // SPI boot flash programming port // BOOT_CCLK treated specially in 7-series - output BOOT_CS_B, + output BOOT_CS_B, input BOOT_MISO, - output BOOT_MOSI, - output CFG_D02, // hope R209 is DNF + output BOOT_MOSI, + output CFG_D02, // hope R209 is DNF - // One I2C bus, everything gatewayed through a TCA9548 - output TWI_SCL, + // One I2C bus, with everything gatewayed through a TCA9548 + output TWI_SCL, inout TWI_SDA, - output TWI_RST, + output TWI_RST, input TWI_INT, // SPI pins connected to microcontroller input SCLK, input CSB, input MOSI, - output MISO, - output MMC_INT, + output MISO, + output MMC_INT, // White Rabbit DAC output WR_DAC_SCLK, @@ -61,7 +63,7 @@ BUFG passg_125(.I(gtpclk0), .O(gtpclk)); parameter in_phase_tx_clk = 1; // Standardized interface, hardware-dependent implementation -wire tx_clk, tx_clk90; +wire tx_clk, tx_clk90, clk62; wire clk_locked; wire pll_reset = 0; // or RESET? @@ -92,6 +94,7 @@ gmii_clock_handle clocks( .clk_locked(clk_locked) ); `endif +assign clk62 = 0; // Ignore dna primitive at least for now // Double-data-rate conversion wire vgmii_tx_clk, vgmii_tx_clk90, vgmii_rx_clk; @@ -121,9 +124,11 @@ gmii_to_rgmii #(.in_phase_tx_clk(in_phase_tx_clk)) gmii_to_rgmii_i( ); wire BOOT_CCLK; +wire cfg_clk; // Just for fun, so we can measure its frequency `ifndef SIMULATE -STARTUPE2 set_cclk(.USRCCLKO(BOOT_CCLK), .USRCCLKTS(1'b0)); +STARTUPE2 set_cclk(.USRCCLKO(BOOT_CCLK), .USRCCLKTS(1'b0), .CFGMCLK(cfg_clk)); `else // !`ifndef SIMULATE + assign cfg_clk = 0; assign BOOT_CCLK = tx_clk; `endif // !`ifndef SIMULATE @@ -139,6 +144,15 @@ wire [33:0] FMC1_LA_P; wire [33:0] FMC1_LA_N; wire [33:0] FMC2_LA_P; wire [33:0] FMC2_LA_N; +wire [1:0] FMC1_CK_P; +wire [1:0] FMC1_CK_N; +wire [1:0] FMC2_CK_P; +wire [1:0] FMC2_CK_N; +wire [23:0] FMC2_HA_P; +wire [23:0] FMC2_HA_N; + +// vestiges of CERN FMC tester support +wire old_scl1, old_scl2, old_sda1, old_sda2; // Real, portable implementation // Consider pulling 3-state drivers out of this @@ -151,11 +165,12 @@ marble_base #(.USE_I2CBRIDGE(1)) base( .boot_clk(BOOT_CCLK), .boot_cs(BOOT_CS_B), .boot_mosi(BOOT_MOSI), .boot_miso(BOOT_MISO), .cfg_d02(CFG_D02), .mmc_int(MMC_INT), .ZEST_PWR_EN(ZEST_PWR_EN), - .aux_clk(SYSCLK_P), .GPS(4'b0), + .aux_clk(SYSCLK_P), .clk62(clk62), .cfg_clk(cfg_clk), + .GPS(4'b0), .SCLK(SCLK), .CSB(CSB), .MOSI(MOSI), .MISO(MISO), .FPGA_RxD(FPGA_RxD), .FPGA_TxD(FPGA_TxD), - .twi_scl({dum_scl, FMC2_LA_P[2] , FMC1_LA_P[2], TWI_SCL}), - .twi_sda({dum_sda, FMC2_LA_N[2], FMC1_LA_N[2], TWI_SDA}), + .twi_scl({dum_scl, old_scl1, old_scl2, TWI_SCL}), + .twi_sda({dum_sda, old_sda1, old_sda2, TWI_SDA}), .TWI_RST(TWI_RST), .TWI_INT(TWI_INT), .lb_clk(lb_clk), .lb_addr(lb_addr), @@ -166,10 +181,8 @@ marble_base #(.USE_I2CBRIDGE(1)) base( .lb_data_out(lb_data_out), .lb_data_in(lb_din), .fmc_test({ - FMC2_LA_P[33:3], FMC2_LA_P[1:0], - FMC2_LA_N[33:3], FMC2_LA_N[1:0], - FMC1_LA_P[33:3], FMC1_LA_P[1:0], - FMC1_LA_N[33:3], FMC1_LA_N[1:0]}), + FMC2_HA_P, FMC2_HA_N, FMC2_CK_P, FMC2_CK_N, FMC2_LA_P, FMC2_LA_N, + FMC1_CK_P, FMC1_CK_N, FMC1_LA_P, FMC1_LA_N}), .WR_DAC_SCLK(WR_DAC_SCLK), .WR_DAC_DIN(WR_DAC_DIN), .WR_DAC1_SYNC(WR_DAC1_SYNC), .WR_DAC2_SYNC(WR_DAC2_SYNC), .LED(LED) diff --git a/projects/oscope/common/digitizer_slowread.v b/projects/oscope/common/digitizer_slowread.v index 8bc090ac4..749795c7f 100644 --- a/projects/oscope/common/digitizer_slowread.v +++ b/projects/oscope/common/digitizer_slowread.v @@ -67,15 +67,14 @@ timestamp ts(.clk(adc_clk), .aux_trig(1'b0), .slow_op(slow_op), .slow_snap(slow_ // the buffer, tag_old shows it at the begin-time of the buffer. Not perfect // because of non-boxcar filtering and sloppy pipelining. reg [7:0] tag_old=0; -`define SLOW_SR_LEN 17*16 -`define SLOW_SR_DATA { \ - U3DA_min, U3DA_max, U3DB_min, U3DB_max, U3DC_min, U3DC_max, U3DD_min, U3DD_max, \ - U2DA_min, U2DA_max, U2DB_min, U2DB_max, U2DC_min, U2DC_max, U2DD_min, U2DD_max, \ +parameter sr_length = 17*16; +wire [sr_length-1:0] slow_sr_data = { + U3DA_min, U3DA_max, U3DB_min, U3DB_max, U3DC_min, U3DC_max, U3DD_min, U3DD_max, + U2DA_min, U2DA_max, U2DB_min, U2DB_max, U2DC_min, U2DC_max, U2DD_min, U2DD_max, tag_now, tag_old } -parameter sr_length = `SLOW_SR_LEN; reg [sr_length-1:0] slow_read=0; always @(posedge adc_clk) if (slow_op) begin - slow_read <= slow_snap ? `SLOW_SR_DATA : {slow_read[sr_length-9:0],timestamp_out}; + slow_read <= slow_snap ? slow_sr_data : {slow_read[sr_length-9:0],timestamp_out}; if (slow_snap) tag_old <= tag_now; end diff --git a/rtsim/cav_elec.v b/rtsim/cav_elec.v index 84f51c139..dfced2bf1 100644 --- a/rtsim/cav_elec.v +++ b/rtsim/cav_elec.v @@ -61,6 +61,7 @@ module cav_elec( input [11:0] modulo, // external `AUTOMATIC_self ); +`undef AUTOMATIC_self `AUTOMATIC_decode `AUTOMATIC_map diff --git a/rtsim/cav_mech.v b/rtsim/cav_mech.v index fa0e77f7e..ee6f10d16 100644 --- a/rtsim/cav_mech.v +++ b/rtsim/cav_mech.v @@ -17,6 +17,7 @@ module cav_mech( output res_clip, `AUTOMATIC_self ); +`undef AUTOMATIC_self `AUTOMATIC_decode @@ -62,4 +63,5 @@ always @(posedge clk) begin end assign environment = noise_out; +`undef AUTOMATIC_prng endmodule // cav_mech diff --git a/rtsim/cav_mode.v b/rtsim/cav_mode.v index 250b7996b..ad5face23 100644 --- a/rtsim/cav_mode.v +++ b/rtsim/cav_mode.v @@ -62,6 +62,7 @@ module cav_mode( input signed [17:0] bw, // external `AUTOMATIC_self ); +`undef AUTOMATIC_self `AUTOMATIC_decode diff --git a/rtsim/station.v b/rtsim/station.v index 46d2287b6..5fde8f1ff 100644 --- a/rtsim/station.v +++ b/rtsim/station.v @@ -57,6 +57,7 @@ module station( // Local Bus for simulator configuration `AUTOMATIC_self ); +`undef AUTOMATIC_self `AUTOMATIC_decode @@ -128,4 +129,5 @@ adc_em #(.del(1)) a_for // auto adc_em #(.del(1)) a_rfl // auto (.clk(clk), .strobe(iq), .in(reflect), .rnd(rndb[12: 0]), .adc(a_reflect), `AUTOMATIC_a_rfl); +`undef AUTOMATIC_prng endmodule From 2d5c8f73be2d4696a14fc0dcfcd2afbe8bed936b Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Sat, 5 Oct 2024 09:26:10 -0700 Subject: [PATCH 36/75] fix typo --- projects/oscope/common/digitizer_slowread.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/oscope/common/digitizer_slowread.v b/projects/oscope/common/digitizer_slowread.v index 749795c7f..ad02437e5 100644 --- a/projects/oscope/common/digitizer_slowread.v +++ b/projects/oscope/common/digitizer_slowread.v @@ -71,7 +71,7 @@ parameter sr_length = 17*16; wire [sr_length-1:0] slow_sr_data = { U3DA_min, U3DA_max, U3DB_min, U3DB_max, U3DC_min, U3DC_max, U3DD_min, U3DD_max, U2DA_min, U2DA_max, U2DB_min, U2DB_max, U2DC_min, U2DC_max, U2DD_min, U2DD_max, - tag_now, tag_old } + tag_now, tag_old }; reg [sr_length-1:0] slow_read=0; always @(posedge adc_clk) if (slow_op) begin slow_read <= slow_snap ? slow_sr_data : {slow_read[sr_length-9:0],timestamp_out}; From be94c9ab8b6faa1890e85b9001eaa01dda91102b Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Sat, 5 Oct 2024 14:28:12 -0700 Subject: [PATCH 37/75] marblemini/cmoc_top.v: reduce CRITICAL WARNING count by aligning a bit better wtih marble_top.v --- projects/cmoc_top/marblemini/cmoc_top.v | 29 ++++++++++++++++--- projects/cmoc_top/marblemini/oscope_rules.csv | 3 -- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/projects/cmoc_top/marblemini/cmoc_top.v b/projects/cmoc_top/marblemini/cmoc_top.v index fef249caf..13c49ce9e 100644 --- a/projects/cmoc_top/marblemini/cmoc_top.v +++ b/projects/cmoc_top/marblemini/cmoc_top.v @@ -50,7 +50,19 @@ module cmoc_top( output VCXO_EN, - output [7:0] LED + output [7:0] LED, + + // J15 TMDS 0, 1, 2, CLK + output [3:0] TMDS_P, + output [3:0] TMDS_N, + + // Directly attached LEDs + output LD16, + output LD17, + + // Physical Pmod + // Pmod1: use LED above with Digilent mapping + input [7:0] Pmod2 ); assign VCXO_EN = 1; @@ -61,6 +73,9 @@ IBUFDS_GTE2 passi_125(.I(GTPREFCLK_P), .IB(GTPREFCLK_N), .CEB(1'b0), .O(gtpclk0) // if you don't put this BUFG in the chain to the MMCM. BUFG passg_125(.I(gtpclk0), .O(gtpclk)); +wire si570; +assign si570 = 0; + parameter in_phase_tx_clk = 1; // Standardized interface, hardware-dependent implementation wire tx_clk, tx_clk90, clk62; @@ -161,12 +176,11 @@ marble_base #(.USE_I2CBRIDGE(1)) base( .vgmii_tx_en(vgmii_tx_en), .vgmii_tx_er(vgmii_tx_er), .vgmii_rx_clk(vgmii_rx_clk), .vgmii_rxd(vgmii_rxd), .vgmii_rx_dv(vgmii_rx_dv), .vgmii_rx_er(vgmii_rx_er), - .phy_rstn(PHY_RSTN), .clk_locked(clk_locked), + .phy_rstn(PHY_RSTN), .clk_locked(clk_locked), .si570(si570), .boot_clk(BOOT_CCLK), .boot_cs(BOOT_CS_B), .boot_mosi(BOOT_MOSI), .boot_miso(BOOT_MISO), .cfg_d02(CFG_D02), .mmc_int(MMC_INT), .ZEST_PWR_EN(ZEST_PWR_EN), .aux_clk(SYSCLK_P), .clk62(clk62), .cfg_clk(cfg_clk), - .GPS(4'b0), .SCLK(SCLK), .CSB(CSB), .MOSI(MOSI), .MISO(MISO), .FPGA_RxD(FPGA_RxD), .FPGA_TxD(FPGA_TxD), .twi_scl({dum_scl, old_scl1, old_scl2, TWI_SCL}), @@ -185,13 +199,20 @@ marble_base #(.USE_I2CBRIDGE(1)) base( FMC1_CK_P, FMC1_CK_N, FMC1_LA_P, FMC1_LA_N}), .WR_DAC_SCLK(WR_DAC_SCLK), .WR_DAC_DIN(WR_DAC_DIN), .WR_DAC1_SYNC(WR_DAC1_SYNC), .WR_DAC2_SYNC(WR_DAC2_SYNC), - .LED(LED) + .LED(LED), .GPS(Pmod2[3:0]) ); // TODO: Removing the SPI flash for now //defparam base.rtefi.p4_client.engine.seven = 1; parameter BUF_AW=13; +assign LD16 = LED[0]; +assign LD17 = LED[1]; + +// test_marble_family instantiates a "Silly little test pattern generator" for these pins +wire [3:0] tmds_q = 4'b0000; +OBUFDS obuf[0:3] (.I(tmds_q), .O(TMDS_P), .OB(TMDS_N)); + // These are meaningful LEDs, one could use them wire [2:0] D4rgb; wire [2:0] D5rgb; diff --git a/projects/cmoc_top/marblemini/oscope_rules.csv b/projects/cmoc_top/marblemini/oscope_rules.csv index 8b72b8a2c..32927357f 100644 --- a/projects/cmoc_top/marblemini/oscope_rules.csv +++ b/projects/cmoc_top/marblemini/oscope_rules.csv @@ -1,8 +1,5 @@ # Literal output follows -# This is to silence ERROR: [Place 30-574], as the pins above aren't clock dedicated -set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets i_zest_wrap/U1_lmk01801/clk_ibufgds] - create_clock -name clk1x -period 13.32 [get_nets clk_1x_90] create_clock -name clk2x -period 6.66 [get_nets clk_2x_0] From abddd57f740eabdc7fbd5605c62723425b59737a Mon Sep 17 00:00:00 2001 From: Shreeharshini Murthy Date: Tue, 8 Oct 2024 11:37:40 -0700 Subject: [PATCH 38/75] etrig_bridge --- dsp/Makefile | 1 + dsp/hosted/etrig_bridge.gtkw | 28 ++++++++ dsp/hosted/etrig_bridge.v | 134 +++++++++++++++++++++++++++++++++++ dsp/hosted/etrig_bridge_tb.v | 83 ++++++++++++++++++++++ dsp/hosted/rules.mk | 2 +- 5 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 dsp/hosted/etrig_bridge.gtkw create mode 100644 dsp/hosted/etrig_bridge.v create mode 100644 dsp/hosted/etrig_bridge_tb.v diff --git a/dsp/Makefile b/dsp/Makefile index f7c6e0aef..a557afd77 100644 --- a/dsp/Makefile +++ b/dsp/Makefile @@ -1,4 +1,5 @@ include ../dir_list.mk +VERILOG_AUTOGEN += "cordicg_b22.v" .PHONY: all all: targets include $(BUILD_DIR)/top_rules.mk diff --git a/dsp/hosted/etrig_bridge.gtkw b/dsp/hosted/etrig_bridge.gtkw new file mode 100644 index 000000000..52bf807c2 --- /dev/null +++ b/dsp/hosted/etrig_bridge.gtkw @@ -0,0 +1,28 @@ +[timestart] 0 +[size] 1166 445 +[pos] 763 125 +*-23.377670 3480000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] etrig_bridge_tb. +[treeopen] etrig_bridge_tb.UUT. +[sst_width] 233 +[signals_width] 198 +[sst_expanded] 1 +[sst_vpaned_height] 93 +@28 +etrig_bridge_tb.UUT.adc_clk +etrig_bridge_tb.UUT.lb_clk +etrig_bridge_tb.UUT.trign_0 +etrig_bridge_tb.UUT.trign_1 +@29 +etrig_bridge_tb.UUT.trign_2 +@28 +etrig_bridge_tb.UUT.sel[1:0] +@24 +etrig_bridge_tb.UUT.period[25:0] +etrig_bridge_tb.UUT.delay[25:0] +etrig_bridge_tb.etrig_pulse_cnt[15:0] +@28 +etrig_bridge_tb.UUT.etrig_pulse +etrig_bridge_tb.UUT.etrig_pulse_delayed +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/dsp/hosted/etrig_bridge.v b/dsp/hosted/etrig_bridge.v new file mode 100644 index 000000000..8fa0459db --- /dev/null +++ b/dsp/hosted/etrig_bridge.v @@ -0,0 +1,134 @@ +// Module that manages the asynchronous external trigger, and the internally-generated periodic trigger. +// Performs clock-domain synchronization, and delays the assertion of the trigger accordingly. +// ---------- + +module etrig_bridge ( + // Two clocks, ADC clock and local clock + input lb_clk, + input adc_clk, + // Three external triggers, active-low + input trign_0, + input trign_1, + input trign_2, + // Control registers + input [1:0] sel, // external + input [25:0] period, // external + input [25:0] delay, // external + // Trigger Counter + output [15:0] etrig_pulse_cnt, + // Trigger Outputs + output etrig_pulse, + output etrig_pulse_delayed +); + + // ------- + // Multi-board synchronization w/ selectable external or programmable trigger + // ------- + localparam ETRIG_0 = 0, + ETRIG_1 = 1, + ETRIG_2 = 2, + ETRIG_PROG = 3; + + // wires and regs + reg [25:0] etrig_p_cnt = 0; // counter for internally-generated trigger + wire etrig_p_pulse, etrig_p_pulse_x; // the internal trigger and its synced partner + wire async_trig, etrig; // MUX outputs + reg [6:0] async_filt_cnt = 0; // to filter-out glitches in the external trigger + wire async_trig_filt; // filtered-out trigger + reg etrig_r = 0, etrig_r1 = 0, etrig_pulse_i = 0; // for edge detection + reg [1:0] etrig_sreg = 0; // shift register to ensure proper delay + reg [15:0] etrig_pulse_cnt_i = 0; // count the triggers that are issued + reg [25:0] delay_cnt = 0; // delay counter + reg etrig_pulse_delayed_i = 0; // delayed pulse + reg etrig_toggle = 0; // flag indicating that we received a pulse + + // 2-FF synchronizers + (* ASYNC_REG = "TRUE" *) reg [1:0] trign_0_sync=0, trign_1_sync=0, trign_2_sync=0; + + // Move delay control to adc_clk domain. Should be attainable using newad. + reg [25:0] delay_r=0; always @(posedge adc_clk) delay_r <= delay; + + // generates the internal trigger + always @(posedge lb_clk) begin + etrig_p_cnt <= (etrig_p_cnt == 0) ? period : etrig_p_cnt - 1; + end + + assign etrig_p_pulse = (etrig_p_cnt == 1); + + // from lb to adc clock domain + flag_xdomain i_flagx_etrig ( + .clk1(lb_clk), .flagin_clk1(etrig_p_pulse), + .clk2(adc_clk), .flagout_clk2(etrig_p_pulse_x)); + + // 2-FF synchronizer before handling further + reg [1:0] sel_r=0; + always @(posedge adc_clk) begin + trign_0_sync <= {trign_0_sync[0], trign_0}; + trign_1_sync <= {trign_1_sync[0], trign_1}; + trign_2_sync <= {trign_2_sync[0], trign_2}; + sel_r <= sel; // arrived in lb_clk + end + + // MUX to decide which trigger to propagate (external triggers are active-low) + assign async_trig = (sel_r == ETRIG_0) ? ~trign_0_sync[1] : + (sel_r == ETRIG_1) ? ~trign_1_sync[1] : + (sel_r == ETRIG_2) ? ~trign_2_sync[1] : + 1'b0; + + // Glitch filter async inputs by ignoring pulses shorter than 128/adc_clk = 1.356 us + always @(posedge adc_clk) begin + if (async_trig == 0) async_filt_cnt <= 0; + else if (!async_trig_filt) async_filt_cnt <= async_filt_cnt + 1; + end + assign async_trig_filt = &(async_filt_cnt); + + assign etrig = (sel_r == ETRIG_PROG) ? etrig_p_pulse_x : async_trig_filt; + + // Rising-edge detect + always @(posedge adc_clk) begin + etrig_r <= etrig; + etrig_r1 <= etrig_r; + etrig_pulse_i <= etrig_r & ~etrig_r1; + if (etrig_pulse_i) + etrig_pulse_cnt_i <= etrig_pulse_cnt_i + 1; + end + + // Delay the trigger strobe + always @(posedge adc_clk) begin + if (etrig_pulse_i == 1'b1) begin + delay_cnt <= 0; // reset + etrig_toggle <= 1'b1; // raise the flag + etrig_pulse_delayed_i <= 1'b0; // not ready yet + end + else if (etrig_toggle == 1'b1 && delay_cnt < delay_r) begin + delay_cnt <= delay_cnt + 1; // keep rolling + etrig_toggle <= etrig_toggle; // retain + etrig_pulse_delayed_i <= 1'b0; // not ready yet + end + else if (etrig_toggle == 1'b1 && delay_cnt == delay_r) begin + delay_cnt <= 0; // reset + etrig_toggle <= 1'b0; // reset + etrig_pulse_delayed_i <= 1'b1; // one-clock pulse + end + else begin + delay_cnt <= 0; // reset + etrig_toggle <= 1'b0; // keep low + etrig_pulse_delayed_i <= 1'b0; // keep low + end + end + + // two-bit shift-register + // ensures one-cycle delay between trigger and delayed trigger if delay == 1 + always @(posedge adc_clk) begin + etrig_sreg <= etrig_sreg << 1; + etrig_sreg[0] <= etrig_pulse_i; + end + + // assigning to output ports + assign etrig_pulse_cnt = etrig_pulse_cnt_i; + assign etrig_pulse = etrig_sreg[1]; + + // mux for the case that the delay is zero + assign etrig_pulse_delayed = (delay_r == 0) ? etrig_sreg[1] : etrig_pulse_delayed_i; + +endmodule diff --git a/dsp/hosted/etrig_bridge_tb.v b/dsp/hosted/etrig_bridge_tb.v new file mode 100644 index 000000000..1e030bc16 --- /dev/null +++ b/dsp/hosted/etrig_bridge_tb.v @@ -0,0 +1,83 @@ +// etrig_bridge_tb.v + +`timescale 1 ns/10 ps // time-unit = 1 ns, precision = 10 ps + +module etrig_bridge_tb; + + reg j5_24v = 1, j4_24v = 1, de9_rxd = 1, de9_dsr = 1; // Active-low + reg [1:0] etrig_sel = 0; + reg [25:0] etrig_period = 26'h0000ff; + reg [25:0] etrig_delay = 26'h000000; + wire [15:0] etrig_pulse_cnt; + wire etrig_pulse; + wire etrig_pulse_delayed; + + // Testbench parameters and clocking + reg fail = 0; + integer seed_int=123; + localparam SIM_TIME = 50000; // ns + localparam period_lb_clk = 20; + localparam period_adc_clk = 10; + + reg free_lb_clk=0; + wire lb_clk; + always begin free_lb_clk = ~free_lb_clk; #(period_lb_clk/2); end + + reg free_adc_clk=0; + wire adc_clk; + always begin free_adc_clk = ~free_adc_clk; #(period_adc_clk/2); end + + reg pll_lock_emu=0; + + // Testbench control + initial begin + if ($test$plusargs("vcd")) begin + $dumpfile("etrig_bridge.vcd"); + $dumpvars(5, etrig_bridge_tb); + end + + while ($time < SIM_TIME) @(posedge lb_clk); + if (!fail) begin + $display("WARNING: Not a self-checking testbench. Will always PASS."); + $finish(0); + end else begin + $display("FAIL"); + $stop(0); + end + end + + etrig_bridge UUT ( + .lb_clk(lb_clk), .adc_clk(adc_clk), + .trign_0(j5_24v), + .trign_1(j4_24v), + .trign_2(de9_rxd&de9_dsr), + .sel(etrig_sel), .period(etrig_period), .delay(etrig_delay), + .etrig_pulse_cnt(etrig_pulse_cnt), .etrig_pulse(etrig_pulse), + .etrig_pulse_delayed(etrig_pulse_delayed) + ); + +// trigger loop +always begin + if (!pll_lock_emu) begin + #(($urandom(seed_int)%20)*period_lb_clk); + pll_lock_emu <= 1'b1; + end + + #(($urandom(seed_int)%20)*20); + {j4_24v, j5_24v, de9_rxd, de9_dsr} <= $urandom(seed_int)%16; + @(posedge adc_clk); + + #(($urandom(seed_int)%20)*200); + {j4_24v, j5_24v, de9_rxd, de9_dsr} <= (1<<4)-1; + etrig_delay <= etrig_delay + 1; + @(posedge adc_clk); +end + +always @(posedge adc_clk) + etrig_sel <= etrig_sel + etrig_pulse; + +// clocking +assign lb_clk = (pll_lock_emu) ? free_lb_clk : 1'b0; +assign adc_clk = (pll_lock_emu) ? free_adc_clk : 1'b0; + +endmodule diff --git a/dsp/hosted/rules.mk b/dsp/hosted/rules.mk index 5bd1cbdb3..390312a32 100644 --- a/dsp/hosted/rules.mk +++ b/dsp/hosted/rules.mk @@ -4,7 +4,7 @@ VFLAGS_DEP += -I. -y . -y$(DSP_DIR) -y$(CORDIC_DIR) VFLAGS += -I. -y . -y$(DSP_DIR) -y$(CORDIC_DIR) -I$(AUTOGEN_DIR) -TEST_BENCH = lp_tb lp_2notch_tb lp_notch_tb phs_avg_tb mp_proc_tb +TEST_BENCH = lp_tb lp_2notch_tb lp_notch_tb phs_avg_tb mp_proc_tb etrig_bridge_tb TGT_ := $(TEST_BENCH) From c945bc1eb19c7405d02dc27709d58e18fcf5c48b Mon Sep 17 00:00:00 2001 From: Qiang Du Date: Fri, 11 Oct 2024 17:54:27 -0700 Subject: [PATCH 39/75] Update soc marble.h / zest.h to support monitoring --- board_support/marble_soc/firmware/marble.c | 18 +++---- board_support/marble_soc/firmware/marble.h | 32 ++++++------ board_support/zest_soc/firmware/zest.c | 57 +++++++++++++--------- board_support/zest_soc/firmware/zest.h | 20 ++++++++ 4 files changed, 78 insertions(+), 49 deletions(-) diff --git a/board_support/marble_soc/firmware/marble.c b/board_support/marble_soc/firmware/marble.c index adfa79ab1..1b67044cb 100644 --- a/board_support/marble_soc/firmware/marble.c +++ b/board_support/marble_soc/firmware/marble.c @@ -35,7 +35,7 @@ marble_dev_t marble = { .module_present = false, .page_select = 0, .i2c_mux_sel = I2C_SEL_QSFP2, .i2c_addr = I2C_ADR_QSFP}, .adn4600 = { - .i2c_mux_sel = I2C_SEL_CLK, .i2c_addr = I2C_ADR_ADN4600}, + .i2c_mux_sel = I2C_SEL_CLK, .i2c_addr = I2C_ADR_ADN4600, .refdes = "U2"}, .si570 = { .f_reset_hz = 0, .rfreq = 0ULL, .i2c_mux_sel = I2C_SEL_APPL, .i2c_addr = I2C_ADR_SI570_NBB} @@ -108,20 +108,20 @@ void get_qsfp_info(qsfp_info_t *qsfp_param) { marble_i2c_read(qsfp_param->i2c_addr, 3, &qsfp_param->chan_stat_los, 1); marble_i2c_read(qsfp_param->i2c_addr, 22, buf, 2); - qsfp_param->temperature = (uint16_t)(buf[0] << 8 | buf[1]) >> 8; // C + qsfp_param->temperature = (int16_t)(buf[0] << 8 | buf[1]) >> 8; // C marble_i2c_read(qsfp_param->i2c_addr, 26, buf, 2); - qsfp_param->voltage = (int16_t)(buf[0] << 8 | buf[1]) / 10; // mV + qsfp_param->voltage = (uint16_t)(buf[0] << 8 | buf[1]) / 10; // mV marble_i2c_read(qsfp_param->i2c_addr, 42, buf, 8); for (i=0; i < 4; i++) { - qsfp_param->bias_current[i] = (int16_t)(buf[2*i] << 8 | buf[2*i+1]) * 2; // microA + qsfp_param->bias_current[i] = (uint16_t)(buf[2*i] << 8 | buf[2*i+1]) * 2; // microA } marble_i2c_read(qsfp_param->i2c_addr, 50, buf, 8); for (i=0; i < 4; i++) { - qsfp_param->tx_power[i] = (int16_t)(buf[2*i] << 8 | buf[2*i+1]) / 10; // microW + qsfp_param->tx_power[i] = (uint16_t)(buf[2*i] << 8 | buf[2*i+1]) / 10; // microW } marble_i2c_read(qsfp_param->i2c_addr, 34, buf, 8); for (i=0; i < 4; i++) { - qsfp_param->rx_power[i] = (int16_t)(buf[2*i] << 8 | buf[2*i+1]) / 10; // microW + qsfp_param->rx_power[i] = (uint16_t)(buf[2*i] << 8 | buf[2*i+1]) / 10; // microW } } @@ -368,11 +368,11 @@ void print_marble_status(void) { printf(" %s: QSFP%1u Serial : %.16s\n", __func__, i+1, qsfp[i].serial_num); printf(" %s: QSFP%1u TXRX_LOS: %#8X\n", __func__, i+1, qsfp[i].chan_stat_los); printf(" %s: QSFP%1u Temp : %8d C\n", __func__, i+1, qsfp[i].temperature); - printf(" %s: QSFP%1u Volt : %8d mV\n", __func__, i+1, qsfp[i].voltage); + printf(" %s: QSFP%1u Volt : %8u mV\n", __func__, i+1, qsfp[i].voltage); for (unsigned j=0; j < 4; j++) { - printf(" %s: QSFP%1u TxBias %u: %8d " MICRO "A\n", __func__, + printf(" %s: QSFP%1u TxBias %u: %8u " MICRO "A\n", __func__, i+1, j, qsfp[i].bias_current[j]); - printf(" %s: QSFP%1u TxPwr %u: %8d " MICRO "W\n", __func__, + printf(" %s: QSFP%1u TxPwr %u: %8u " MICRO "W\n", __func__, i+1, j, qsfp[i].tx_power[j]); printf(" %s: QSFP%1u RxPwr %d: %8u " MICRO "W\n", __func__, i+1, j, qsfp[i].rx_power[j]); diff --git a/board_support/marble_soc/firmware/marble.h b/board_support/marble_soc/firmware/marble.h index 57db91754..26039c130 100644 --- a/board_support/marble_soc/firmware/marble.h +++ b/board_support/marble_soc/firmware/marble.h @@ -3,6 +3,11 @@ #include #include +#define MARBLE_VAR_MARBLE_V1_2 0 +#define MARBLE_VAR_MARBLE_V1_3 1 +#define MARBLE_VAR_MARBLE_V1_4 2 +#define MARBLE_VAR_UNKNOWN 3 + typedef union _DataDword { uint32_t value; unsigned char bytes[4]; @@ -33,16 +38,8 @@ typedef struct { t_reg8 *regmap; } marble_init_byte_t; -// # marble_v1_2 = 0, marble_v1_3 = 1, marble_v1_4 = 2 and so on.. -typedef enum { - MARBLE_VAR_MARBLE_V1_2, - MARBLE_VAR_MARBLE_V1_3, - MARBLE_VAR_MARBLE_V1_4, - MARBLE_VAR_UNKNOWN -} MARBLE_VAR; - typedef struct marble_init_t { - MARBLE_VAR marble_variant; + uint8_t marble_variant; marble_init_word_t ina219_fmc1_data; marble_init_word_t ina219_fmc2_data; marble_init_word_t ina219_12v_data; @@ -51,6 +48,7 @@ typedef struct marble_init_t { marble_init_byte_t adn4600_data; uint64_t si570_freq_hz; bool enable_evr_gtx; + bool enable_poll_status; } marble_init_t; typedef struct ina219_info_t { @@ -83,9 +81,7 @@ typedef struct adn4600_info_t { const uint8_t i2c_mux_sel; const uint8_t i2c_addr; /** schematic refdes */ - const unsigned char refdes[4]; - /** function name */ - const unsigned char name[4]; + const unsigned char refdes[6]; uint8_t xpt_status[8]; } adn4600_info_t; @@ -130,18 +126,18 @@ typedef struct si570_info_t { const uint8_t i2c_mux_sel; /** I2C device address */ uint8_t i2c_addr; - /** start address */ - uint8_t start_addr; + unsigned char regs[6]; /** f_xtal, fixed, 0.09 ppb */ uint64_t f_xtal_hz; - unsigned char regs[6]; /** 38-bit fractional multiplier */ uint64_t rfreq; - uint8_t hs_div; - uint8_t n1; uint64_t f_reset_hz; uint64_t f_dco_hz; uint64_t f_out_hz; + /** start address */ + uint8_t start_addr; + uint8_t hs_div; + uint8_t n1; } si570_info_t; /** @@ -149,7 +145,7 @@ typedef struct si570_info_t { * @brief Structure holding marble board info */ typedef struct marble_dev_t { - MARBLE_VAR variant; + uint8_t variant; ina219_info_t ina219_12v; ina219_info_t ina219_fmc1; ina219_info_t ina219_fmc2; diff --git a/board_support/zest_soc/firmware/zest.c b/board_support/zest_soc/firmware/zest.c index c28039e81..bf54d5b5e 100644 --- a/board_support/zest_soc/firmware/zest.c +++ b/board_support/zest_soc/firmware/zest.c @@ -37,6 +37,8 @@ const uint8_t g_zest_adcs[] = { ZEST_DEV_AD9653B }; +zest_status_t zest = {0}; + bool get_spi_ready(void) { return !CHECK_BIT(SPI_GET_STATUS(g_base_spi), BIT_CIPO); } @@ -366,7 +368,7 @@ uint32_t read_zest_reg(zest_dev_t dev, uint32_t addr) { switch (dev) { case ZEST_DEV_LMK01801: // Not supported - printf("read_zest_reg: LMK01801 reading not supported.\n"); + debug_printf("read_zest_reg: LMK01801 reading not supported.\n"); return 0; case ZEST_DEV_AD9653A: case ZEST_DEV_AD9653B: @@ -384,7 +386,7 @@ uint32_t read_zest_reg(zest_dev_t dev, uint32_t addr) { << g_devinfo.data_len; break; default: - printf("read_zest_reg: Invalid Device.\n"); + debug_printf("read_zest_reg: Invalid Device.\n"); return 0; } SPI_SET_DAT_BLOCK( g_base_spi, inst ); @@ -539,44 +541,55 @@ void select_zest_addr(uint32_t base) { g_base_awg = base + ZEST_BASE2_AWG; } -void read_amc7823_adcs(void) { +void get_zest_status(zest_status_t *zest) { + for (size_t ix=0; ix<4; ix++) { + zest->zest_frequencies[ix] = read_zest_fcnt(ix); + } + for (size_t ix=0; ix<3; ix++) { + zest->zest_phases[ix] = read_clk_div_ph(ix); + } + for (size_t ix=0; ix<9; ix++) { + zest->amc7823_adcs[ix] = read_zest_reg(ZEST_DEV_AMC7823, ix); + } + for (size_t ix=0; ix<6; ix++) { + zest->ad7794_adcs[ix] = read_ad7794_channel(ix); + } +} + +void print_zest_status(void) { + printf("ZEST Frequencies:\n"); + for (size_t ix=0; ix<4; ix++) { + printf(" Fclk %8s: ", zest_fcnt_names[ix]); + print_udec_fix(zest.zest_frequencies[ix]*125, FCNT_WIDTH, 3); + printf(" MHz\n"); + } + // AM7823 ADC, 12 bits: // ADC5: LO = +2 dBm regx*2.5 // ADC6: Curr = 0.7 A regx*2.5 // ADC7: Volt = 3.3/2 V regx*2.5 // ADC8: Temp = 25 C regx*2.6*0.61 - 273 - uint16_t adc_vals[9]; - unsigned int ix; - for (ix=0; ix<9; ix++) { - adc_vals[ix] = read_zest_reg(ZEST_DEV_AMC7823, ix); - } - printf("ZEST AMC7823 ADC:\n"); - for (ix=0; ix<9; ix++) { - printf(" ADC %u Val: %#06x", ix, adc_vals[ix]); + for (size_t ix=0; ix<9; ix++) { + printf(" ADC %u Val: %#06x", ix, zest.amc7823_adcs[ix]); if (ix == 8) { - // printf(" Temp: %.3f [C]\n", (adc_vals[ix] & 0xfff) * 2.6 * 0.61 - 273); + // printf(" Temp: %.3f [C]\n", (adc_vals[ix] & 0xfff) * 2.6 * 0.61 - 273) / 0x3ff; printf(" Temp:"); - print_dec_fix((adc_vals[ix] & 0xfff)*50 - 8736, 5, 3); + print_dec_fix((zest.amc7823_adcs[ix] & 0xfff)*50 - 8736, 5, 3); printf("[C]\n"); } else { // printf(" Volt: %.3f [V]\n", (adc_vals[ix] & 0xfff) * 2.5 / 0xfff); printf(" Volt:"); - print_dec_fix((adc_vals[ix] & 0xfff) * 2.5, 12, 3); + print_dec_fix((zest.amc7823_adcs[ix] & 0xfff) * 2.5, 12, 3); printf("[V]\n"); } } -} -void read_ad7794_adcs(void) { - uint32_t adc_vals[6]; - unsigned int ix; printf("ZEST AD7794 ADC:\n"); - for (ix=0; ix<6; ix++) { - adc_vals[ix] = read_ad7794_channel(ix); - printf(" AIN %u: %#x", ix+1, adc_vals[ix]); + for (size_t ix=0; ix<6; ix++) { + printf(" AIN %u: %#x", ix+1, zest.ad7794_adcs[ix]); printf(" Volt:"); - print_dec_fix((adc_vals[ix]) * 1.17, 24, 3); // internal 1.17V ref + print_dec_fix((zest.ad7794_adcs[ix]) * 1.17, 24, 3); // internal 1.17V ref printf("[V]\n"); } } diff --git a/board_support/zest_soc/firmware/zest.h b/board_support/zest_soc/firmware/zest.h index e7ce1bac9..57194d9a0 100644 --- a/board_support/zest_soc/firmware/zest.h +++ b/board_support/zest_soc/firmware/zest.h @@ -82,6 +82,7 @@ typedef struct { uint32_t *fcnt_exp; // expected ADC0_DIV, ADC1_DIV, DAC_DCO, DSP_CLK int8_t *phs_center; // expected ADC0_DIV, ADC1_DIV, DAC_DCO uint8_t *ad9781_smp; // expected AD9781_SMP values + bool enable_poll_status; } zest_init_t; typedef struct { @@ -92,6 +93,15 @@ typedef struct { uint32_t data_mask; } zest_devinfo_t; +typedef struct zest_status_t +{ + uint32_t zest_frequencies[4]; // ADC0, ADC1, DAC_DCO, DSP_CLK + int16_t zest_phases[3]; // ADC0, ADC1, DAC_DCO + uint16_t amc7823_adcs[9]; + uint32_t ad7794_adcs[6]; +} zest_status_t; + + /***************************************************************************//** * @brief SYNC both A&B banks by writing R5 when SYNC0_AUTO high *******************************************************************************/ @@ -279,6 +289,16 @@ bool align_adc_clk_phase(uint8_t ch, int8_t center); *******************************************************************************/ bool check_ad9781_bist(void); +/***************************************************************************//** + * @brief Get zest status +*******************************************************************************/ +void get_zest_status(zest_status_t *zest); + +/***************************************************************************//** + * @brief Print zest status +*******************************************************************************/ +void print_zest_status(void); + /***************************************************************************//** * @brief Test function. * @param base - base address From e0a6d54981602babd25c5462369178379e7a3040 Mon Sep 17 00:00:00 2001 From: sdmurthy Date: Wed, 16 Oct 2024 09:23:51 -0700 Subject: [PATCH 40/75] Apply patch from Larry to jit_rad_gateway.v. Parameterize lb_odata and xfer_odata so it can be used for multiple reg banks --- localbus/jit_rad_gateway.v | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/localbus/jit_rad_gateway.v b/localbus/jit_rad_gateway.v index a2079ce7c..f71fdd50e 100644 --- a/localbus/jit_rad_gateway.v +++ b/localbus/jit_rad_gateway.v @@ -9,13 +9,14 @@ // and bmb7_kintex/jxj_gate have such an output. module jit_rad_gateway #( + parameter dw = 32, parameter passthrough = 1 ) ( // basic localbus hookup input lb_clk, input [3:0] lb_addr, input lb_strobe, - output [31:0] lb_odata, + output [dw-1:0] lb_odata, // control input lb_prefill, output lb_error, @@ -25,7 +26,7 @@ module jit_rad_gateway #( output xfer_snap, output xfer_strobe, output [3:0] xfer_addr, - input [31:0] xfer_odata + input [dw-1:0] xfer_odata ); generate if (passthrough) begin : thru @@ -60,7 +61,7 @@ end else begin : buffer app_running_r <= app_running; end assign xfer_addr = addr1; - dpram #(.aw(4), .dw(32)) buff( + dpram #(.aw(4), .dw(dw)) buff( .clka(app_clk), .addra(addr2), .wena(buff_we), .dina(xfer_odata), .clkb(lb_clk), .addrb(lb_addr), .doutb(lb_odata)); // From e0e94acf86e930822e029c4a8da6f45e1a2b14bd Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Wed, 16 Oct 2024 19:58:59 -0700 Subject: [PATCH 41/75] Tiny build system tweaks selftest.sh: print nmigen version localbus/Makefile: remove tgen_tb in a make clean --- localbus/Makefile | 2 +- selftest.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/localbus/Makefile b/localbus/Makefile index d07138e33..cb962f198 100644 --- a/localbus/Makefile +++ b/localbus/Makefile @@ -39,7 +39,7 @@ live: Vjit_rad_gateway_demo tgen_tb: tgen.v dpram.v clean: - rm -f jit_rad_gateway_demo_badger jit_rad_gateway_demo_qf2 + rm -f jit_rad_gateway_demo_badger jit_rad_gateway_demo_qf2 *_tb rm -f jit_rad_gateway_demo_cdc.txt jit_rad_gateway_demo_yosys.json rm -f Vjit_rad_gateway_demo xfer_demo.vcd jit_rad_gateway_tb *.vcd rm -rf obj_dir diff --git a/selftest.sh b/selftest.sh index 9bd338410..fc0aa4f3d 100644 --- a/selftest.sh +++ b/selftest.sh @@ -39,7 +39,7 @@ yosys -V echo 'puts "tclsh [info patchlevel]"' | tclsh flake8 --version if [ "$1" = "more" ]; then -python3 -c 'import nmigen; print("nmigen found")' +python3 -c 'import nmigen; print("nmigen found", nmigen.__version__)' riscv64-unknown-elf-gcc --version fi From 1e39b9eee7a0b02f239ccf0df932402f6fbe3ff8 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Fri, 18 Oct 2024 09:37:24 -0700 Subject: [PATCH 42/75] jit_rad.md: updates --- localbus/jit_rad.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/localbus/jit_rad.md b/localbus/jit_rad.md index 7c06d9fbc..4860fa82f 100644 --- a/localbus/jit_rad.md +++ b/localbus/jit_rad.md @@ -1,7 +1,7 @@ # jit_rad: Just In Time Readback Across Domains -Demo of an idea for efficiently making data from another clock domain -available to local bus readout, without violating CDC checks +A module for efficiently making data from another clock domain +available to local bus readout, without violating CDC rules The simple localbus used in bedrock and lcls2_llrf makes a lot of things easy at the Verilog source level, with minimal FPGA fabric footprint. @@ -15,13 +15,13 @@ to begin with, that's not a problem. Reading results from clock domains other than the primary is harder, because the memory gateway requires a synthesis-time choice of the exact number of -clock cycles latency. Our typical practice is to just ignore CDC problems, +clock cycles latency. One typical practice is to just ignore CDC problems, and hope that registers in domain B are not corrupted when read in domain A. -This module attempts to address that design flaw. +Converting such code to use this module will address that design flaw. We have a fair amount of warning at the beginning of a LASS UDP packet before any actual read cycles happen. Our strategy is to copy 16 words -from the app_clk domain into a 16x32 (distributed) dpram. Then those +from the app_clk domain into a 16x32 dpram. Then those data are trivially available to read out in the local bus domain. In a QF2-pre, we get about 300 ns warning, because cycles are slow (20 ns), @@ -35,7 +35,7 @@ Unlike the existing (broken CDC) case, it's not possible to repeatedly poll a signal within the same packet. Well, you can, but you're guaranteed to get the same answer each time. Unlike our slow-readout scheme, the data read is not a single-time atomic snapshot. On the plus side, -its hardware footprint is pretty small, and I claim it can be dropped in +its hardware footprint is pretty small, and it has been dropped in to lcls2_llrf without requiring any changes to high-level code. If you really want or need atomic capture, a hook is provided that lets you @@ -69,18 +69,19 @@ The other ports are - xfer_snap (supporting atomic capture use cases) - lb_error (output bit which might detect violations in the timing assumptions). -A full demo of this system is in jit_rad_gateway_demo.v. That consists -of a production local bus controller (jxj_gate or mem_gateway, preprocessor- -selectable), an instantiation of jit_rad_gateway, the external multiplexer -in the xfer_clk domain, and some minimal localbus implementation so you can -see activity. +A full demo of this system is in jit_rad_gateway_demo.v. That consists of +a production local bus controller (jxj_gate or mem_gateway, +preprocessor-selectable), an instantiation of jit_rad_gateway, +the external multiplexer in the xfer_clk domain, +and some minimal localbus implementation so you can see activity. A Verilator driver for jit_rad_gateway_demo is in xfer_sim.cpp, that can put the simulated chip on a live localhost UDP socket. A WIP iverilog test bench is in jit_rad_gateway_tb.v. -Most of the other files here (besides this one, and the Makefile) are copies -of files from scattered locations in bedrock, maybe with a few mods. +This Verilog program depends on a few files from other parts of bedrock, +as listed in the Makefile: dpram.v flag_xdomain.v reg_tech_cdc.v. +The testbench additionally depends on files from Packet Badger. ## Prerequisites and usage @@ -119,7 +120,6 @@ gtkwave xfer_demo.vcd xfer_demo.gtkw # To do: -- clean up this documentation +- expand and clean up this documentation - document acceptable relationship between lb_clk and app_clk - finish up the regression check -- test it out for real in lcls2_llrf From 9e69ca330634176564d0474c0b0aaed2b9719265 Mon Sep 17 00:00:00 2001 From: Keith Penney Date: Fri, 18 Oct 2024 10:52:01 -0700 Subject: [PATCH 43/75] Fixed a bug interpreting register names as a literal address in hexadecimal when they happen to contain all hex characters. --- projects/common/leep/Makefile | 6 +++++- projects/common/leep/raw.py | 10 ++++++---- projects/common/leep/test/test_raw.py | 26 ++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/projects/common/leep/Makefile b/projects/common/leep/Makefile index 55317abad..c9acd5a0b 100644 --- a/projects/common/leep/Makefile +++ b/projects/common/leep/Makefile @@ -6,11 +6,15 @@ PYTHON=python3 LEEP_CORE=base.py raw.py ca.py file.py logic.py -all: test_cli +all: test_cli test_raw test_cli: $(LEEP_CORE) cli.py PYTHONPATH="$(THIS_DIR)/..:$(BUILD_DIR)" $(PYTHON) -m leep.test.test_cli test +.PHONY: test_raw +test_raw: raw.py + @PYTHONPATH="$(THIS_DIR)/.." $(PYTHON) -m leep.test.test_raw + # This is a test target currently only used for manual testing. Development is in progress # for including this in automated regression tests. server: $(LEEP_CORE) cli.py diff --git a/projects/common/leep/raw.py b/projects/common/leep/raw.py index 28faefc86..3fbbd712a 100644 --- a/projects/common/leep/raw.py +++ b/projects/common/leep/raw.py @@ -111,11 +111,13 @@ def _int(s): return int(s) except ValueError: pass - bases = (2, 16, 10) - for base in bases: + if hasattr(s, 'startswith'): try: - return int(s, base) - except (TypeError, ValueError): + if s.startswith('0x'): + return int(s, 16) + elif s.startswith('0b'): + return int(s, 2) + except ValueError: pass return None diff --git a/projects/common/leep/test/test_raw.py b/projects/common/leep/test/test_raw.py index 21b2f329d..6c15f8df8 100644 --- a/projects/common/leep/test/test_raw.py +++ b/projects/common/leep/test/test_raw.py @@ -189,3 +189,29 @@ def test_array(self): self.assertEqual(self.serv.data[101], 0xdeadbeef) self.assertEqual(self.serv.data[102], 0x12345679) self.assertEqual(self.serv.data[103], 0xdeadbeef) + + +def test_raw_int(): + from leep.raw import _int + tests = { + "foo": None, + "123": 123, + "0x100": 0x100, + "0b1000": 0b1000, + "0xreg": None, + "0bentry": None, + } + for key, val in tests.items(): + if val != _int(key): + raise Exception("Test failed _int({}) = {} != {}".format(key, _int(key), val)) + return True + + +def doTests(): + test_raw_int() + print("PASS") + return + + +if __name__ == "__main__": + doTests() From 4ae8da692e866721646d5516090541addfe455da Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Tue, 22 Oct 2024 13:13:18 -0700 Subject: [PATCH 44/75] projects/oscope/common/llspi.v: synchronize with copy in lcls2_llrf Small lint reduction. Maybe someday the two can share a copy? Located in peripheral_drivers? --- projects/oscope/common/llspi.v | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/projects/oscope/common/llspi.v b/projects/oscope/common/llspi.v index a5793c0d4..b9636c8b5 100644 --- a/projects/oscope/common/llspi.v +++ b/projects/oscope/common/llspi.v @@ -7,7 +7,7 @@ module llspi #( parameter dbg = "false", parameter pace_set = 6, // Can override to 2 or 3 for testing - parameter infifo_aw=5 + parameter infifo_aw = 5 ) ( input clk, // timespec 5.3 ns // Physical FMC pins connected to digitizer board @@ -139,7 +139,7 @@ spi_eater eater(.clk(clk), .pace(pace), .empty(empty), // Read results get pushed into this FIFO wire [7:0] result_unlatched; -wire [3:0] result_count; +wire [4:0] result_count; shortfifo #(.dw(8), .aw(4)) output_fifo(.clk(clk), .we(result_we), .din(result), .re(result_re), .dout(result_unlatched), @@ -148,6 +148,8 @@ shortfifo #(.dw(8), .aw(4)) output_fifo(.clk(clk), always @(posedge clk) if (result_re) host_result <= result_unlatched; // Status register available for host polling -assign status = {3'b0, empty, result_count}; +// If you push 16 results into shortfifo, don't expect to get +// a useful result from this status register! +assign status = {3'b0, empty, result_count[3:0]}; endmodule From b0bb171cecff887e5b34d659ef7442757895fa55 Mon Sep 17 00:00:00 2001 From: Keith Penney Date: Tue, 29 Oct 2024 14:58:46 -0700 Subject: [PATCH 45/75] Hotfix for a bug introduced in leep_literal. Permissive register name mapping restored but not checked in CI. --- projects/common/leep/raw.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/common/leep/raw.py b/projects/common/leep/raw.py index 3fbbd712a..7305d75a2 100644 --- a/projects/common/leep/raw.py +++ b/projects/common/leep/raw.py @@ -179,7 +179,7 @@ def _decode(self, reg, instance=[]): _reg = _int(reg) if _reg is not None: return "0x{:x}".format(_reg), _reg, 1, info - if len(instance): + if instance is not None: reg = self.expand_regname(reg, instance=instance) info = self.get_reg_info(reg, instance=None) size = 2**info.get('addr_width', 0) From 12daf2251f0dcbbd65b8e9fc0192a72256377007 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Tue, 29 Oct 2024 17:05:47 -0700 Subject: [PATCH 46/75] Switch ODDR.v to an implementation that verilator and yosys understand Not actually used much --- badger/tests/kc705/ODDR.v | 13 +++++++------ fpga_family/xilinx/ODDR.v | 16 +++++++--------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/badger/tests/kc705/ODDR.v b/badger/tests/kc705/ODDR.v index 95c29833b..8062451ce 100644 --- a/badger/tests/kc705/ODDR.v +++ b/badger/tests/kc705/ODDR.v @@ -1,5 +1,5 @@ // pathetic model of Xilinx DDR output cell -// ignores set and reset inputs +// ignores set and reset inputs, and the SRTYPE and DDR_CLK_EDGE parameters module ODDR ( input S, input R, @@ -14,10 +14,11 @@ parameter DDR_CLK_EDGE = "SAME_EDGE"; parameter INIT = 0; parameter SRTYPE = "SYNC"; -reg qx=INIT, hold=INIT; -always @(posedge C) if (CE) qx <= D1; -always @(posedge C) if (CE) hold <= D2; -always @(negedge C) qx <= hold; -assign Q = qx; +reg hold1=INIT, hold2=INIT; +always @(posedge C) if (CE) begin + hold1 <= D1; + hold2 <= D2; +end +assign Q = C ? hold1 : hold2; endmodule diff --git a/fpga_family/xilinx/ODDR.v b/fpga_family/xilinx/ODDR.v index 4d25db75c..8062451ce 100644 --- a/fpga_family/xilinx/ODDR.v +++ b/fpga_family/xilinx/ODDR.v @@ -1,5 +1,5 @@ // pathetic model of Xilinx DDR output cell -// ignores set and reset inputs +// ignores set and reset inputs, and the SRTYPE and DDR_CLK_EDGE parameters module ODDR ( input S, input R, @@ -14,13 +14,11 @@ parameter DDR_CLK_EDGE = "SAME_EDGE"; parameter INIT = 0; parameter SRTYPE = "SYNC"; -// verilator lint_save -// verilator lint_off MULTIDRIVEN -reg qx=INIT, hold=INIT; -// verilator lint_restore -always @(negedge C) qx <= hold; -always @(posedge C) if (CE) qx <= D1; -always @(posedge C) if (CE) hold <= D2; -assign Q = qx; +reg hold1=INIT, hold2=INIT; +always @(posedge C) if (CE) begin + hold1 <= D1; + hold2 <= D2; +end +assign Q = C ? hold1 : hold2; endmodule From f1448e4755ad4e78baeccc5758f04f446872c01c Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Tue, 29 Oct 2024 17:06:49 -0700 Subject: [PATCH 47/75] fpga_family/iserdes/lvds_*.v: irrelevant changes to help yosys along Avoid triggering yosys' white-box detector --- fpga_family/iserdes/lvds_dco.v | 6 ++++++ fpga_family/iserdes/lvds_frame.v | 4 ++++ fpga_family/iserdes/lvds_iophy.v | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/fpga_family/iserdes/lvds_dco.v b/fpga_family/iserdes/lvds_dco.v index b921d51cf..a248dd038 100644 --- a/fpga_family/iserdes/lvds_dco.v +++ b/fpga_family/iserdes/lvds_dco.v @@ -49,5 +49,11 @@ assign clk_div_to_bufg = clk_div_bufr; `endif BUFG bufg_i(.I(clk_div_to_bufg), .O(clk_div_bufg)); +`else +// Does almost nothing except establish some causality, +// and keep yosys from thinking this module is a white box. +assign clk_div_bufg = dco_p; +assign clk_div_bufr = dco_p; +assign dco_clk_out = dco_p; `endif endmodule diff --git a/fpga_family/iserdes/lvds_frame.v b/fpga_family/iserdes/lvds_frame.v index 126bc9925..c49c17792 100644 --- a/fpga_family/iserdes/lvds_frame.v +++ b/fpga_family/iserdes/lvds_frame.v @@ -6,5 +6,9 @@ module lvds_frame #(parameter flip_frame=0) ( `ifndef SIMULATE IBUFDS #(.DIFF_TERM("TRUE")) ibufds_frame(.I(flip_frame ? frame_n : frame_p), .IB(flip_frame ? frame_p : frame_n), .O(frame)); +`else +// Does almost nothing except establish some causality, +// and keep yosys from thinking this module is a white box. +assign frame = frame_p ^ flip_frame; `endif endmodule diff --git a/fpga_family/iserdes/lvds_iophy.v b/fpga_family/iserdes/lvds_iophy.v index 87a268882..2fdbe1b09 100644 --- a/fpga_family/iserdes/lvds_iophy.v +++ b/fpga_family/iserdes/lvds_iophy.v @@ -90,6 +90,11 @@ always @ (posedge clk_div) begin dout[7]<=flip_d?~Q8:Q8; end +`else +// Does almost nothing except establish some causality, +// and keep yosys from thinking this module is a white box. +always @ (posedge clk_div) dout <= {8{d_p}}; // horribly stupid +assign idelay_value_out = 0; // theoretically in clk_div domain, also `endif // SIMULATE endmodule From b7a95d70ab8fb0aaf8b51a9b6723f5a9b2dca47e Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Tue, 29 Oct 2024 17:07:53 -0700 Subject: [PATCH 48/75] projects/oscope/common/digitizer_config.sv: pull in small updates from lcls2_llrf digitizer_config.v --- projects/oscope/common/digitizer_config.sv | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/projects/oscope/common/digitizer_config.sv b/projects/oscope/common/digitizer_config.sv index 1a64aa964..7522a011c 100644 --- a/projects/oscope/common/digitizer_config.sv +++ b/projects/oscope/common/digitizer_config.sv @@ -96,6 +96,7 @@ module digitizer_config( // lb_clk domain, but only because I flag_xdomain to adc_clk (* external, signal_type="single-cycle" *) input rawadc_trig, // external single-cycle + // newad-force clk1x domain (* external *) input [9:0] adc_downsample_ratio, // external @@ -219,6 +220,12 @@ assign clk_status = clk_status_r; flag_xdomain rawadc_trig_xdomain (.clk1(lb_clk), .flagin_clk1(rawadc_trig), .clk2(adc_clk), .flagout_clk2(rawadc_trig_x)); +// One more clock-domain change, so idelay_scanner can run in pure lb_clk domain +wire [127:0] permuted_data; // from banyan_mem +wire [15:0] scanner_adc_val = permuted_data[15:0]; +reg [15:0] scanner_adc_val_r=0; +always @(posedge lb_clk) scanner_adc_val_r <= scanner_adc_val; + // 16 idelay registers mapped to lb_addr 112-127 // See idelay_base in static_oscope_regmap.json wire scan_running; @@ -227,8 +234,6 @@ wire [4:0] hw_data; wire hw_strobe; wire [7:0] scanner_banyan_mask; wire [2:0] scanner_adc_num; // not used -wire [127:0] permuted_data; // from banyan_mem -wire [15:0] scanner_adc_val = permuted_data[15:0]; wire lb_idelay_write = lb_strobe & ~lb_rd & (lb_addr[23:4] == 20'h19007); idelay_scanner #(.use_decider(1)) scanner( .lb_clk(lb_clk), .lb_addr(lb_addr[3:0]), .lb_data(lb_dout[4:0]), @@ -240,7 +245,7 @@ idelay_scanner #(.use_decider(1)) scanner( .debug_sel(scanner_debug[4]), .debug_addr(scanner_debug[3:0]), .hw_addr(hw_addr), .hw_data(hw_data), .hw_strobe(hw_strobe), .banyan_mask(scanner_banyan_mask), .adc_num(scanner_adc_num), - .adc_clk(adc_clk), .adc_val(scanner_adc_val) + .adc_clk(lb_clk), .adc_val(scanner_adc_val_r) ); // process the output hw_ bus from idelay_scanner, sending to IDELAYE2 @@ -336,7 +341,9 @@ assign phase_status_U3 = 0; `define CONFIG_BANYAN `ifdef CONFIG_BANYAN -// Banyan-routed memory, simple one-shot fill for now +// Banyan-routed memory, that features a simple one-shot fill. +// Use rawadc_trig for a direct asynchronous fill, or rawadc_trig_req +// to start filling at the next external trigger (ext_trig). parameter banyan_aw = 14; // 8 blocks of RAM, each 16K x 16 reg banyan_run=0, banyan_run_d=0; wire rollover, full; From c9b04cfaac350797783e7fbee9fe43c425fe63f0 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Tue, 29 Oct 2024 17:08:30 -0700 Subject: [PATCH 49/75] projects/oscope/common/application_top.sv: fuss with usused features Either remove them entirely, or disable them more completely --- projects/oscope/common/application_top.sv | 67 ++++------------------- 1 file changed, 12 insertions(+), 55 deletions(-) diff --git a/projects/oscope/common/application_top.sv b/projects/oscope/common/application_top.sv index 444dd136d..30c8b3c85 100644 --- a/projects/oscope/common/application_top.sv +++ b/projects/oscope/common/application_top.sv @@ -56,7 +56,6 @@ module application_top( wire clk1x_clk, clk2x_clk, lb4_clk; (* external, signal_type="single-cycle" *) reg [0:0] lamp_test_trig = 0; // top-level single-cycle -(* external, signal_type="single-cycle" *) reg [0:0] ctrace_start = 0; // top-level single-cycle (* external *) reg [31:0] icc_cfg = 0; // top-level (* external *) reg [7:0] tag_now = 0; // top-level (* external *) reg [1:0] domain_jump_realign = 0; // top-level @@ -157,10 +156,8 @@ wire [27:0] frequency_adc; wire [27:0] frequency_4xout; wire [27:0] frequency_clkout3; wire [27:0] frequency_dac_dco; -wire [27:0] frequency_gtx_tx; -wire [27:0] frequency_gtx_rx; -wire [15:0] hist_dout; -wire [1:0] hist_status; +wire [15:0] hist_dout=0; +wire [1:0] hist_status=0; wire [15:0] phasex_dout; wire phasex_ready; wire phasex_present; @@ -173,12 +170,14 @@ wire [7:0] llspi_result; wire wave1_available, wave0_available; wire [7:0] rawadc_avail; wire [31:0] banyan_data; -wire [31:0] banyan_status; -wire [31:0] trace_data; -wire [31:0] trace_status1; -wire [31:0] trace_status2; -wire [7:0] slow_data; -wire [0:0] slow_data_ready; +// banyan status register was constructed without regard to clock domains - please revisit +wire [31:0] banyan_status_x; +reg [31:0] banyan_status; always @(posedge lb_clk) banyan_status <= banyan_status_x; +wire [31:0] trace_data=0; +wire [31:0] trace_status1=0; +wire [31:0] trace_status2=0; +wire [7:0] slow_data=0; +wire [0:0] slow_data_ready=0; wire [31:0] phase_status_U2; wire [31:0] phase_status_U3; reg [15:0] crc_errors=0; @@ -187,31 +186,8 @@ wire [7:0] scanner_result_val; wire [7:0] slow_chain_out; wire [19:0] icc_data_U50, icc_data_U32; wire [8:0] qsfp_result; -wire [31:0] ctrace_out; -wire [0:0] ctrace_running; -parameter ctrace_aw=12; -wire [ctrace_aw-1:0] ctrace_pc; -wire [ctrace_aw-0:0] ctrace_status = {ctrace_pc, ctrace_running}; -wire [31:0] ccr1_summary; -wire [31:0] ccr1_counts; -wire [31:0] ccr1_cavity0_status; -wire [31:0] ccr1_cavity1_status; -wire [31:0] ccr1_rev_id; -reg [15:0] cc1_latency=0; -wire [15:0] cct1_local_frame_counter; // output of chitchat_tx -wire signed [17:0] cavity0_detune; -wire signed [17:0] cavity1_detune; -reg [0:0] cct1_cavity0_detune_valid=0; -reg [0:0] cct1_cavity1_detune_valid=0; -wire cavity0_detune_stb; -wire cavity1_detune_stb; -wire [6:0] cavity0_sat_count; -wire [6:0] cavity1_sat_count; -wire [2:0] dtrace_status; -wire [21:0] telem_monitor; wire signed [13:0] fdbk_drive_lb_out; wire [25:0] freq_multi_count_out; -wire [1:0] dac_enabled; wire [31:0] U15_spi_addr_rdbk = {zif_cfg.U15_sdo_addr, zif_cfg.U15_spi_rdbk}; wire [1:0] U15_spi_status = {zif_cfg.U15_spi_ready, zif_cfg.U15_sdio_as_sdo}; wire [31:0] U18_spi_addr_rdbk = {zif_cfg.U18_sdo_addr, zif_cfg.U18_spi_rdbk}; @@ -281,10 +257,6 @@ always @(posedge lb_clk) begin 4'h1: reg_bank_1 <= U3dout_msb; 4'h2: reg_bank_1 <= idelay_value_out_U3_lsb; 4'h3: reg_bank_1 <= idelay_value_out_U3_msb; - 4'ha: reg_bank_1 <= dtrace_status; - 4'hc: reg_bank_1 <= ctrace_status; // alias: ctrace_running - 4'hd: reg_bank_1 <= frequency_gtx_tx; - 4'he: reg_bank_1 <= frequency_gtx_rx; 4'hf: reg_bank_1 <= hist_status; default: reg_bank_1 <= 32'hfaceface; endcase @@ -310,16 +282,9 @@ always @(posedge lb_clk) begin case (lb_addr[3:0]) 4'h0: reg_bank_3 <= phase_status_U3; // alias: clk_phase_diff_out_U3 4'h1: reg_bank_3 <= crc_errors; - 4'h2: reg_bank_3 <= cavity0_detune; - 4'h3: reg_bank_3 <= cavity1_detune; - 4'h4: reg_bank_3 <= cavity0_sat_count; - 4'h5: reg_bank_3 <= cavity1_sat_count; - 4'h6: reg_bank_3 <= dac_enabled; // xxxx37 unused 4'h8: reg_bank_3 <= U15_spi_addr_rdbk; // alias: U15_spi_rdbk 4'h9: reg_bank_3 <= U15_spi_status; - 4'ha: reg_bank_3 <= cct1_cavity0_detune_valid; - 4'hb: reg_bank_3 <= cct1_cavity1_detune_valid; 4'hc: reg_bank_3 <= U18_spi_addr_rdbk; // alias: U18_spi_rdbk 4'hd: reg_bank_3 <= U18_spi_status; // xxxx3e unused @@ -332,18 +297,10 @@ always @(posedge lb_clk) begin 4'h4: reg_bank_4 <= trace_status1; 4'h5: reg_bank_4 <= trace_status2; 4'h7: reg_bank_4 <= slow_data_ready; - 4'h8: reg_bank_4 <= telem_monitor; default: reg_bank_4 <= 32'hfaceface; endcase case (lb_addr[3:0]) - // Most of these are in the wrong clock domain - 4'h0: reg_bank_5 <= ccr1_summary; - 4'h1: reg_bank_5 <= ccr1_counts; - 4'h2: reg_bank_5 <= ccr1_cavity0_status; - 4'h3: reg_bank_5 <= ccr1_cavity1_status; - 4'h4: reg_bank_5 <= ccr1_rev_id; - 4'h5: reg_bank_5 <= cc1_latency; - 4'h6: reg_bank_5 <= cct1_local_frame_counter; + 4'h1: reg_bank_5 <= 1; default: reg_bank_5 <= 32'hfaceface; endcase // All of the following rhs have had one stage of decode pipeline; @@ -383,7 +340,7 @@ digitizer_config digitizer_config // auto .rawadc_trig_x(rawadc_trig_x), .adc_clk(adc_clk), .adc_data(adc_data), - .banyan_status(banyan_status), + .banyan_status(banyan_status_x), .phasex_dout(phasex_dout), .phase_status_U2(phase_status_U2), .phase_status_U3(phase_status_U3), From f2d52f8426562829ac9b46f47ddeac13cf766347 Mon Sep 17 00:00:00 2001 From: Vamsi Vytla Date: Wed, 30 Oct 2024 12:48:44 -0700 Subject: [PATCH 50/75] build-tools/parser.py: This should bring newad-force feature into yosys-based newad --- build-tools/parser.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build-tools/parser.py b/build-tools/parser.py index e17bbcedc..414118b65 100644 --- a/build-tools/parser.py +++ b/build-tools/parser.py @@ -416,6 +416,7 @@ def parse_vfile_yosys(self, stack, fin, fd, dlist, clk_domain, cd_indexed): for port, (net_info, port_info) in parsed_mod['external_nets'].items(): signal_type = net_info['attributes']['signal_type'] if 'signal_type' in net_info['attributes'] else None + port_cd = net_info['attributes']['cd'] if 'cd' in net_info['attributes'] else clk_domain signed = 'signed' if 'signed' in net_info else None direction = port_info['direction'] if 'direction' in port_info else None p = Port(port, @@ -425,7 +426,7 @@ def parse_vfile_yosys(self, stack, fin, fd, dlist, clk_domain, cd_indexed): signed, this_mod, signal_type, - clk_domain, + port_cd, cd_indexed, port_info != {}, **attributes) @@ -441,7 +442,7 @@ def parse_vfile_yosys(self, stack, fin, fd, dlist, clk_domain, cd_indexed): None, this_mod, 'plus-we-VOID', - clk_domain, + port_cd, cd_indexed, port_info != {}, **attributes) From 9e62e347f56bcc15bb8f357f8ee8cd53dda2a43e Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Wed, 30 Oct 2024 13:39:46 -0700 Subject: [PATCH 51/75] oscope_top.sv: connect dangling ports of marble_base: si570 clk62 cfg_clk --- projects/oscope/marble_family/oscope_top.sv | 32 +++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/projects/oscope/marble_family/oscope_top.sv b/projects/oscope/marble_family/oscope_top.sv index b865e6c27..c30b03e58 100644 --- a/projects/oscope/marble_family/oscope_top.sv +++ b/projects/oscope/marble_family/oscope_top.sv @@ -171,6 +171,14 @@ assign Pmod1 = LED; assign LD16 = 1; assign LD17 = 1; +wire BOOT_CCLK; +wire cfg_clk; // Just for fun, so we can measure its frequency +`ifndef SIMULATE +STARTUPE2 set_cclk(.USRCCLKO(BOOT_CCLK), .USRCCLKTS(1'b0), .CFGMCLK(cfg_clk)); +`else +assign cfg_clk = 0; +`endif + // vestiges of CERN FMC tester support wire old_scl1, old_scl2, old_sda1, old_sda2; // placeholders @@ -181,6 +189,25 @@ wire [1:0] FMC2_CK_N; wire [23:0] FMC2_HA_P; wire [23:0] FMC2_HA_N; +wire si570; +`ifdef USE_SI570 +// Single-ended clock derived from programmable xtal oscillator +ds_clk_buf #( + .GTX (1)) +i_ds_gtrefclk1 ( + .clk_p (GTREFCLK_P), + .clk_n (GTREFCLK_N), + .clk_out (si570) +); +`else +assign si570 = 0; +`endif + +// Works +reg bad_slow_clock=0; +always @(posedge tx_clk) bad_slow_clock <= ~bad_slow_clock; +wire clk62 = bad_slow_clock; + // Real, portable implementation // Consider pulling 3-state drivers out of this marble_base #( @@ -192,11 +219,12 @@ marble_base #( .vgmii_tx_en(vgmii_tx_en), .vgmii_tx_er(vgmii_tx_er), .vgmii_rx_clk(vgmii_rx_clk), .vgmii_rxd(vgmii_rxd), .vgmii_rx_dv(vgmii_rx_dv), .vgmii_rx_er(vgmii_rx_er), - .phy_rstn(PHY_RSTN), .clk_locked(clk_locked), + .phy_rstn(PHY_RSTN), .clk_locked(clk_locked), .si570(si570), .boot_clk(BOOT_CCLK), .boot_cs(BOOT_CS_B), .boot_mosi(BOOT_MOSI), .boot_miso(BOOT_MISO), .cfg_d02(CFG_D02), .mmc_int(MMC_INT), .ZEST_PWR_EN(ZEST_PWR_EN), - .aux_clk(SYSCLK_P), .GPS(4'b0), + .aux_clk(SYSCLK_P), .clk62(clk62), .cfg_clk(cfg_clk), + .GPS(4'b0), .SCLK(SCLK), .CSB(CSB), .MOSI(MOSI), .MISO(MISO), .FPGA_RxD(FPGA_RxD), .FPGA_TxD(FPGA_TxD), .twi_scl({dum_scl, old_scl1, old_scl2, TWI_SCL}), From c6239607a4532da6778dd81c159e085696eab7f8 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Wed, 30 Oct 2024 13:40:05 -0700 Subject: [PATCH 52/75] projects/oscope/marble_family/Makefile: first try at sv2v and cdc_snitch Only (potentially) helpful if you have sv2v installed --- projects/oscope/marble_family/Makefile | 35 ++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/projects/oscope/marble_family/Makefile b/projects/oscope/marble_family/Makefile index c0334cb4a..24d619f3d 100644 --- a/projects/oscope/marble_family/Makefile +++ b/projects/oscope/marble_family/Makefile @@ -6,7 +6,8 @@ XILINX_TOOL := VIVADO include ../../../dir_list.mk -OSCOPE_COMMON_DIR=../common +OSCOPE_COMMON_DIR = ../common +MARBLE_FAMILY_DIR = ../../test_marble_family APP_NAME = oscope @@ -16,7 +17,7 @@ include $(BUILD_DIR)/newad_top_rules.mk include $(OSCOPE_COMMON_DIR)/rules.mk -VFLAGS_DEP += -y$(DSP_DIR) -y$(BOARD_SUPPORT_DIR)/marblemini -y$(BOARD_SUPPORT_DIR)/zest -y$(FPGA_FAMILY_DIR) -y$(FPGA_FAMILY_DIR)/xilinx -y$(FPGA_FAMILY_DIR)/iserdes -y$(ISERDES_DIR) -y$(XILINX_DIR) -y$(SERIAL_IO_DIR) -y. -y$(PERIPH_DRIVERS_DIR) -y$(PERIPH_DRIVERS_DIR)/idelay_scanner -y$(OSCOPE_COMMON_DIR) -y$(HOMELESS_DIR) -y$(BADGER_DIR) -y$(BADGER_DIR)/tests -y$(BADGER_DIR)/tests/kc705 -y../../test_marble_family/ -y../../test_marble_family/pps_lock -y$(PERIPH_DRIVERS_DIR)/i2cbridge -y$(HOMELESS_DIR)/freq_demo -DSIMULATE +VFLAGS_DEP += -y$(DSP_DIR) -y$(BOARD_SUPPORT_DIR)/marblemini -y$(BOARD_SUPPORT_DIR)/zest -y$(FPGA_FAMILY_DIR) -y$(FPGA_FAMILY_DIR)/xilinx -y$(FPGA_FAMILY_DIR)/iserdes -y$(SERIAL_IO_DIR) -y. -y$(PERIPH_DRIVERS_DIR) -y$(PERIPH_DRIVERS_DIR)/idelay_scanner -y$(OSCOPE_COMMON_DIR) -y$(HOMELESS_DIR) -y$(BADGER_DIR) -y$(BADGER_DIR)/tests -y$(BADGER_DIR)/tests/kc705 -y$(MARBLE_FAMILY_DIR) -y$(MARBLE_FAMILY_DIR)/pps_lock -y$(PERIPH_DRIVERS_DIR)/i2cbridge -y$(HOMELESS_DIR)/freq_demo -DSIMULATE LB_AW = 23 NEWAD_DIRS += $(OSCOPE_COMMON_DIR) @@ -47,10 +48,33 @@ zest_connector.csv: remap_gen.py system_top.xdc: $(BOARD_SUPPORT_DIR)/$(HARDWARE)/Marble.xdc $(BOARD_SUPPORT_DIR)/$(HARDWARE)/pin_map.csv zest_connector.csv oscope_rules.csv $(PYTHON) $(BADGER_DIR)/tests/meta-xdc.py $^ > $@ -oscope_top.sv: $(AUTOGEN_DIR)/config_romx.v $(RTEFI_V) application_top_auto $(AUTOGEN_DIR)/moving_average.v oscope_marble2_features +oscope_top.sv: $(AUTOGEN_DIR)/config_romx.v $(RTEFI_V) $(AUTOGEN_DIR)/application_top_auto.vh $(AUTOGEN_DIR)/addr_map_application_top.vh $(AUTOGEN_DIR)/moving_average.v oscope_marble2_features oscope_top.bit: $(AUTOGEN_DIR)/config_romx.v +# ===== +# highly experimental and still somewhat messy +# sv2v not supplied; see https://github.com/zachjs/sv2v +UPPER_SV = oscope_top.sv $(OSCOPE_COMMON_DIR)/application_top.sv $(BOARD_SUPPORT_DIR)/zest/zest_cfg_if.sv $(BOARD_SUPPORT_DIR)/zest/zest_if.sv $(BOARD_SUPPORT_DIR)/zest/zest_wrap.sv $(OSCOPE_COMMON_DIR)/digitizer_config.sv +oscope_prep.v: $(AUTOGEN_DIR)/application_top_auto.vh $(AUTOGEN_DIR)/addr_map_application_top.vh oscope_marble2_features + sv2v -DSIMULATE -DVERILATOR -I $(AUTOGEN_DIR) $(UPPER_SV) > $@ + wc -l $@ +oscope_pure_v.d: oscope_prep.v $(AUTOGEN_DIR)/config_romx.v $(RTEFI_V) $(AUTOGEN_DIR)/moving_average.v + $(VERILOG) -Wno-timescale -o /dev/null $< -y$(AUTOGEN_DIR) $(VFLAGS_DEP) -M$@.$$$$ && sort -u < $@.$$$$ | tr '\n' ' ' | sed -e 's/^/oscope_pure_v_check oscope_prep_yosys.json oscope_pure_v.d: /' -e 's/ $$//' > $@ && rm $@.$$$$ +# might try to disable this include if we're "just" doing a make clean +include oscope_pure_v.d +.PHONY: oscope_pure_v_check +# default VERILATOR includes -Wall, and I don't want that (yet?) +# dependencies from oscope_pure_v.d +oscope_pure_v_check: + verilator --lint-only -Wno-WIDTH -Wno-TIMESCALEMOD -Wno-PINMISSING -Wno-CASEINCOMPLETE -DSIMULATE $^ +OSCOPE_PURE_V = $(shell cat oscope_pure_v.d) +YOSYS_JSON_OPTION += -DSIMULATE +# most dependencies from oscope_pure_v.d +oscope_prep_yosys.json: $(FPGA_FAMILY_DIR)/xilinx/IBUFGDS.v +# exercise with make oscope_prep_cdc.txt +# ===== + $(AUTOGEN_DIR)/config_romx.v: $(BUILD_DIR)/build_rom.py $(APP_NAME)_regmap.json $(PYTHON) $< -v $@ -j $(APP_NAME)_regmap.json @@ -71,12 +95,13 @@ $(APP_NAME)_regmap.json: $(AUTOGEN_DIR)/regmap_application_top.json scalar_$(APP $(PYTHON) $(OSCOPE_COMMON_DIR)/shorten_names.py -o $@ -i $(APP_NAME)_regmap_long.json download: - openocd -f ../../test_marble_family/marble.cfg -c "transport select jtag; init; xc7_program xc7.tap; pld load 0 oscope_top.bit; exit" + openocd -f $(MARBLE_FAMILY_DIR)/marble.cfg -c "transport select jtag; init; xc7_program xc7.tap; pld load 0 oscope_top.bit; exit" include $(BUILD_DIR)/bottom_rules.mk CLEAN += *.bit *.bin *.prm $(APP_NAME)_regmap*.json scalar_$(APP_NAME)_regmap.json *_features*.json *_features*.vh oscope_marble*_features -CLEAN += system_top.xdc zest_connector.csv $(RTEFI_CLEAN) +CLEAN += system_top.xdc zest_connector.csv $(RTEFI_CLEAN) foo.gtkw +CLEAN += oscope_prep.v oscope_prep_yosys.json oscope_prep_cdc.txt oscope_pure_v.d CLEAN_DIRS += _xilinx .Xil ifneq (,$(findstring bit,$(MAKECMDGOALS))) From 0da0d0ba95adb2dd04b92c6469866a3763df0a8d Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Wed, 30 Oct 2024 14:22:03 -0700 Subject: [PATCH 53/75] projects/oscope/marble_family/Makefile: keep new features from interfering with old Don't make bitfile generation depend on sv2v Requires explicit dependency generation step for new features --- projects/oscope/marble_family/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/oscope/marble_family/Makefile b/projects/oscope/marble_family/Makefile index 24d619f3d..b2b36ea4b 100644 --- a/projects/oscope/marble_family/Makefile +++ b/projects/oscope/marble_family/Makefile @@ -60,9 +60,9 @@ oscope_prep.v: $(AUTOGEN_DIR)/application_top_auto.vh $(AUTOGEN_DIR)/addr_map_ap sv2v -DSIMULATE -DVERILATOR -I $(AUTOGEN_DIR) $(UPPER_SV) > $@ wc -l $@ oscope_pure_v.d: oscope_prep.v $(AUTOGEN_DIR)/config_romx.v $(RTEFI_V) $(AUTOGEN_DIR)/moving_average.v - $(VERILOG) -Wno-timescale -o /dev/null $< -y$(AUTOGEN_DIR) $(VFLAGS_DEP) -M$@.$$$$ && sort -u < $@.$$$$ | tr '\n' ' ' | sed -e 's/^/oscope_pure_v_check oscope_prep_yosys.json oscope_pure_v.d: /' -e 's/ $$//' > $@ && rm $@.$$$$ -# might try to disable this include if we're "just" doing a make clean -include oscope_pure_v.d + $(VERILOG) -Wno-timescale -o /dev/null $< -y$(AUTOGEN_DIR) $(VFLAGS_DEP) -M$@.$$$$ && sort -u < $@.$$$$ | tr '\n' ' ' | sed -e 's/^/oscope_pure_v_check oscope_prep_yosys.json: /' -e 's/ $$//' > $@ && rm $@.$$$$ +# make this dependency file first, explicitly, if you are doing sv2v/cdc_snitch work +-include oscope_pure_v.d .PHONY: oscope_pure_v_check # default VERILATOR includes -Wall, and I don't want that (yet?) # dependencies from oscope_pure_v.d From f1ca1b1bfbdbb637e5dbe11d84fff47fca3670a3 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Wed, 30 Oct 2024 14:56:38 -0700 Subject: [PATCH 54/75] oscope_top.sv: fix setup of BOOT_CCLK and cfg_clk for synthesis --- projects/oscope/marble_family/oscope_top.sv | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/projects/oscope/marble_family/oscope_top.sv b/projects/oscope/marble_family/oscope_top.sv index c30b03e58..65b8dc170 100644 --- a/projects/oscope/marble_family/oscope_top.sv +++ b/projects/oscope/marble_family/oscope_top.sv @@ -149,9 +149,12 @@ gmii_to_rgmii #(.in_phase_tx_clk(in_phase_tx_clk)) gmii_to_rgmii_i( ); wire BOOT_CCLK; +wire cfg_clk; // Just for fun, so we can measure its frequency `ifndef SIMULATE -STARTUPE2 set_cclk(.USRCCLKO(BOOT_CCLK), .USRCCLKTS(1'b0)); -`endif // `ifndef SIMULATE +STARTUPE2 set_cclk(.USRCCLKO(BOOT_CCLK), .USRCCLKTS(1'b0), .CFGMCLK(cfg_clk)); +`else +assign cfg_clk = 0; +`endif // Placeholders wire ZEST_PWR_EN; @@ -171,14 +174,6 @@ assign Pmod1 = LED; assign LD16 = 1; assign LD17 = 1; -wire BOOT_CCLK; -wire cfg_clk; // Just for fun, so we can measure its frequency -`ifndef SIMULATE -STARTUPE2 set_cclk(.USRCCLKO(BOOT_CCLK), .USRCCLKTS(1'b0), .CFGMCLK(cfg_clk)); -`else -assign cfg_clk = 0; -`endif - // vestiges of CERN FMC tester support wire old_scl1, old_scl2, old_sda1, old_sda2; // placeholders From 123230302d57023cc164926ac19d6e874d83778a Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Fri, 1 Nov 2024 14:01:03 -0700 Subject: [PATCH 55/75] projects/oscope/common/*.sv: work on clock domains --- projects/oscope/common/application_top.sv | 27 ++++++++++++------ projects/oscope/common/digitizer_config.sv | 33 +++++++++++----------- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/projects/oscope/common/application_top.sv b/projects/oscope/common/application_top.sv index 30c8b3c85..b98d7ac26 100644 --- a/projects/oscope/common/application_top.sv +++ b/projects/oscope/common/application_top.sv @@ -55,10 +55,11 @@ module application_top( // Needs placing before usage of any top-level registers wire clk1x_clk, clk2x_clk, lb4_clk; -(* external, signal_type="single-cycle" *) reg [0:0] lamp_test_trig = 0; // top-level single-cycle +// Note: the syntax for these top-level registers is not quite compatible with "old" newad (* external *) reg [31:0] icc_cfg = 0; // top-level -(* external *) reg [7:0] tag_now = 0; // top-level (* external *) reg [1:0] domain_jump_realign = 0; // top-level +// newad-force clk1x domain +(* external, cd="clk1x" *) reg [7:0] tag_now = 0; // top-level `AUTOMATIC_decode @@ -207,15 +208,25 @@ wire [31:0] hello_1 = "o wo"; wire [31:0] hello_2 = "rld!"; wire [31:0] hello_3 = 32'h0d0a0d0a; wire [31:0] ffffffff = 32'hffffffff; -wire [31:0] U2dout_lsb = zif_cfg.U2_dout[31:0]; -wire [31:0] U2dout_msb = zif_cfg.U2_dout[63:32]; -wire [31:0] U3dout_lsb = zif_cfg.U3_dout[31:0]; -wire [31:0] U3dout_msb = zif_cfg.U3_dout[63:32]; wire [19:0] idelay_value_out_U2_lsb = zif_cfg.U2_idelay_value_out[19:0]; wire [19:0] idelay_value_out_U2_msb = zif_cfg.U2_idelay_value_out[39:20]; wire [19:0] idelay_value_out_U3_lsb = zif_cfg.U3_idelay_value_out[19:0]; wire [19:0] idelay_value_out_U3_msb = zif_cfg.U3_idelay_value_out[39:20]; +// Only useful if the ADC data is static, which is the plan when +// configured to emit a test pattern during initial setup. +// Maybe just get rid of this, and use the real data capture in banyan memory. +reg [31:0] U2dout_lsb = 0; +reg [31:0] U2dout_msb = 0; +reg [31:0] U3dout_lsb = 0; +reg [31:0] U3dout_msb = 0; +always @(posedge lb_clk) begin + U2dout_lsb <= zif_cfg.U2_dout[31:0]; + U2dout_msb <= zif_cfg.U2_dout[63:32]; + U3dout_lsb <= zif_cfg.U3_dout[31:0]; + U3dout_msb <= zif_cfg.U3_dout[63:32]; +end + // Very basic pipelining of read process reg [23:0] lb_addr_r=0; always @ (posedge lb_clk) begin @@ -327,8 +338,8 @@ always @(posedge lb_clk) begin end wire rawadc_trig_x; -(* lb_automatic *) -digitizer_config digitizer_config // auto +(* lb_automatic, cd="clk1x" *) +digitizer_config digitizer_config // auto clk1x ( .lb_clk(lb_clk), .lb_strobe(lb_strobe), diff --git a/projects/oscope/common/digitizer_config.sv b/projects/oscope/common/digitizer_config.sv index 7522a011c..a71db76bc 100644 --- a/projects/oscope/common/digitizer_config.sv +++ b/projects/oscope/common/digitizer_config.sv @@ -45,22 +45,15 @@ module digitizer_config( output [1:0] clk_status, // software-settable + // adc_clk domain (* external *) input [31:0] periph_config, // external (* external *) input [15:0] bitslip, // external (* external *) - input [1:0] U15_spi_read_and_start_r, // external - //input U15_spi_read_r, // external - (* external *) input [31:0] U15_spi_data_addr_r, // external - //input [15:0] U15_spi_addr_r, // external - (* external *) - input [1:0] U18_spi_read_and_start_r, // external - //input U18_spi_read_r, // external (* external *) input [31:0] U18_spi_data_addr_r, // external - //input [7:0] U18_spi_addr_r, // external (* external *) input U2_clk_reset_r, // external (* external *) @@ -77,30 +70,36 @@ module digitizer_config( input mmcm_reset_r, // external (* external *) input idelayctrl_reset_r, // external + // lb_clk domain - (* external *) + // newad-force lb domain + (* external, cd="lb" *) + input [1:0] U15_spi_read_and_start_r, // external + (* external, cd="lb" *) + input [1:0] U18_spi_read_and_start_r, // external + (* external, cd="lb" *) input [7:0] banyan_mask, // external - (* external, signal_type="single-cycle" *) + (* external, signal_type="single-cycle", cd="lb" *) input phasex_trig, // external single-cycle - (* external, signal_type="we-strobe" *) + (* external, signal_type="we-strobe", cd="lb" *) input llspi_we, // external we-strobe input llspi_re, // -- external strobe - (* external, signal_type="we-strobe" *) + (* external, signal_type="we-strobe", cd="lb" *) input clk_status_we, // external we-strobe - (* external *) + (* external, cd="lb" *) input [4:0] scanner_debug, // external input autoset_enable, // -- external input scan_trigger, // -- external single-cycle - (* external, signal_type="we-strobe" *) + (* external, signal_type="we-strobe", cd="lb" *) input scan_trigger_we, // external we-strobe // lb_clk domain, but only because I flag_xdomain to adc_clk - (* external, signal_type="single-cycle" *) + (* external, signal_type="single-cycle", cd="lb" *) input rawadc_trig, // external single-cycle + + // adc_clk domain // newad-force clk1x domain (* external *) input [9:0] adc_downsample_ratio, // external - - // adc_clk domain (* external *) input [9:0] sync_ad7794_cset, // external (* external *) From ecd1e4ea1169495946d3a4b5e6a6bb8105bcca82 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Sat, 2 Nov 2024 08:19:18 -0700 Subject: [PATCH 56/75] Scattered trivial clean-up, including spelling No change to function Reduced warnings when processing code with yosys and verilator --- board_support/zest/zest_if.sv | 7 ++++--- board_support/zest_soc/vita_57.1_pinout.txt | 6 +++--- fpga_family/xilinx/MMCME2_BASE.v | 1 + projects/test_marble_family/first_readout.sh | 2 +- selfclean.sh | 1 + soc/picorv32/gateware/uart_fifo_pack.v | 2 ++ 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/board_support/zest/zest_if.sv b/board_support/zest/zest_if.sv index 9011453ad..a333502f4 100644 --- a/board_support/zest/zest_if.sv +++ b/board_support/zest/zest_if.sv @@ -35,7 +35,8 @@ interface zest_if ( assign {U2_D1NA, U2_D1NB, U2_D1NC, U2_D1ND} = {U2[14], U2[4], U2[26], U2[11]}; assign {U2_D1PA, U2_D1PB, U2_D1PC, U2_D1PD} = {U2[17], U2[8], U2[5], U2[12]}; assign {U2_DCON, U2_DCOP, U2_FCON, U2_FCOP} = {U2[9], U2[15], U2[10], U2[6]}; - assign {U3[10], U2[22], U4[26]} = {U2_PDWN, U2_CSB, U2_SCLK}; + assign {U2[22], U4[26]} = {U2_CSB, U2_SCLK}; + // don't set U3[10] to U2_PDWN, since it's set to U3_PDWN below wire U3_D0NA, U3_D0NB, U3_D0NC, U3_D0ND, U3_D0PA, U3_D0PB, U3_D0PC, U3_D0PD, U3_D1NA, U3_D1NB, U3_D1NC, U3_D1ND, U3_D1PA, U3_D1PB, U3_D1PC, U3_D1PD, @@ -77,9 +78,9 @@ interface zest_if ( wire U18_DOUT_RDY = U18[1]; assign {U18[0], U18[2], U18[3], U18[4]} = {U18_CLK, U18_CS, U18_DIN, U18_SCLK}; - // NOTE: Semantics of PMOD and HDMI connectors are application-dependent and + // NOTE: Semantics of Pmod and HDMI connectors are application-dependent and // thus not handled here - // PMOD - J18, J17 + // Pmod - J18, J17 // J19: HDMI // U33U1: TPS62110 DC-DC converter diff --git a/board_support/zest_soc/vita_57.1_pinout.txt b/board_support/zest_soc/vita_57.1_pinout.txt index b2f2d6665..00219af80 100644 --- a/board_support/zest_soc/vita_57.1_pinout.txt +++ b/board_support/zest_soc/vita_57.1_pinout.txt @@ -1,6 +1,6 @@ -#from https://fmchub.github.io/appendix/VITA57_FMC_HPC_LPC_SIGNALS_AND_PINOUT.html -# compactible with KC705 UG810 Appendix B -# compactible with FMC116_112_user_manual.pdf Table 8. +# from https://fmchub.github.io/appendix/VITA57_FMC_HPC_LPC_SIGNALS_AND_PINOUT.html +# compatible with KC705 UG810 Appendix B +# compatible with FMC116_112_user_manual.pdf Table 8 CLK0_M2C_N H5 CLK0_M2C_P H4 diff --git a/fpga_family/xilinx/MMCME2_BASE.v b/fpga_family/xilinx/MMCME2_BASE.v index 8af0a748c..28055ee55 100644 --- a/fpga_family/xilinx/MMCME2_BASE.v +++ b/fpga_family/xilinx/MMCME2_BASE.v @@ -56,6 +56,7 @@ module MMCME2_BASE #( assign CLKOUT0 = CLKIN1; assign CLKOUT1 = CLKIN1; +assign LOCKED = 1; // verilator lint_restore endmodule // MMCME2_BASE diff --git a/projects/test_marble_family/first_readout.sh b/projects/test_marble_family/first_readout.sh index 8288ce30b..bf607bf9f 100644 --- a/projects/test_marble_family/first_readout.sh +++ b/projects/test_marble_family/first_readout.sh @@ -9,7 +9,7 @@ echo "Reading kintex 7 internal temperature for $IP using XADC" python3 -m xadctemp -a $IP -p 803 echo "Reading kintex 7 DNA for $IP" python3 -m leep.cli leep://$IP:803 reg dna_high dna_low -echo "Connect Digilent 8 LED board to PMOD J12 and check if all them blink at different rate" +echo "Connect Digilent 8 LED board to Pmod J12 and check if all them blink at different rate" python3 -m leep.cli leep://$IP:803 reg led_user_mode=2 tt=$(mktemp /tmp/quick_XXXXXX) python3 -m spi_test --ip $IP --udp 804 --otp --pages=1 --dump $tt diff --git a/selfclean.sh b/selfclean.sh index f353a7eee..642accd82 100644 --- a/selfclean.sh +++ b/selfclean.sh @@ -27,3 +27,4 @@ make -C serial_io/chitchat clean make -C serial_io/EVG_EVR clean make -C soc/picorv32/test clean make -C fpga_family/xilinx clean +rm -r $(find * -name "__pycache__") diff --git a/soc/picorv32/gateware/uart_fifo_pack.v b/soc/picorv32/gateware/uart_fifo_pack.v index eb942b3dc..e1922df63 100644 --- a/soc/picorv32/gateware/uart_fifo_pack.v +++ b/soc/picorv32/gateware/uart_fifo_pack.v @@ -137,7 +137,9 @@ always @(posedge clk) begin if (|mem_wstrb && (mem_short_addr==UART_BAUDRATE)) begin if (mem_wstrb[0]) uprescale[ 7:0] <= mem_wdata[ 7:0]; if (mem_wstrb[1]) uprescale[15:8] <= mem_wdata[15:8]; +`ifndef YOSYS $display("new UART prescale value = 0x%04x", mem_wdata); +`endif end // ------------- // --- Reads --- From 1984639c65e026485462104bea004d82d801819e Mon Sep 17 00:00:00 2001 From: Shreeharshini Murthy Date: Thu, 7 Nov 2024 11:50:35 -0800 Subject: [PATCH 57/75] Unify phase difference modules --- board_support/zest_soc/zest.v | 17 +++-- dsp/phase_diff.gtkw | 33 +++++++++ dsp/phase_diff.v | 60 +++++++--------- dsp/{phasex_tb.v => phase_diff_tb.v} | 21 +++--- dsp/phaset.gtkw | 30 ++++++++ dsp/phaset.v | 12 ++-- dsp/phaset_tb.v | 80 ++++++++++++++++++++++ dsp/phasex.gtkw | 59 ---------------- dsp/phasex.v | 4 +- dsp/rules.mk | 2 +- projects/oscope/common/digitizer_config.sv | 22 +++--- 11 files changed, 203 insertions(+), 137 deletions(-) create mode 100644 dsp/phase_diff.gtkw rename dsp/{phasex_tb.v => phase_diff_tb.v} (83%) create mode 100644 dsp/phaset.gtkw create mode 100644 dsp/phaset_tb.v delete mode 100644 dsp/phasex.gtkw diff --git a/board_support/zest_soc/zest.v b/board_support/zest_soc/zest.v index 25e92ae2e..9fde85f49 100644 --- a/board_support/zest_soc/zest.v +++ b/board_support/zest_soc/zest.v @@ -245,7 +245,7 @@ assign PWR_EN = ~pwr_en_b; // ADC0_DIV, ADC1_DIV, DAC_DCO wire signed [PH_DIFF_DW-1:0] phdiff [N_ADC:0]; -wire [N_ADC:0] phdiff_val; +wire [N_ADC:0] phdiff_err; // DSP_CLK, ADC0_DIV, ADC1_DIV, DAC_DCO wire [27:0] f_clks [N_ADC+1:0]; wire pll_locked; @@ -318,14 +318,13 @@ generate for (ix=0; ix=16 + if (&track.cnt[4:0]) begin phase_err = phase_diff - phase_expect; phase_pass = $abs(phase_err)/FULL_RANGE < err_bar; // $display("cc: %d, phase_err: %d, pass: %d", cc, phase_err, phase_pass); diff --git a/dsp/phaset.gtkw b/dsp/phaset.gtkw new file mode 100644 index 000000000..12212e5d3 --- /dev/null +++ b/dsp/phaset.gtkw @@ -0,0 +1,30 @@ +[timestart] 0 +[size] 1000 600 +[pos] 0 0 +*-25.448893 12500000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] phaset_tb. +[sst_width] 213 +[signals_width] 211 +[sst_expanded] 1 +[sst_vpaned_height] 154 +@28 +phaset_tb.track.div +phaset_tb.track.msb +phaset_tb.track.nsb +phaset_tb.track.move +phaset_tb.track.dn +phaset_tb.track.up +@8024 +phaset_tb.track.phase[13:0] +@20000 +- +@28 +phaset_tb.fault +@8420 +phaset_tb.phase_unw +@20000 +- +@28 +phaset_tb.fail +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/dsp/phaset.v b/dsp/phaset.v index 8ed93c7a1..49fc57420 100644 --- a/dsp/phaset.v +++ b/dsp/phaset.v @@ -11,12 +11,11 @@ module phaset #( parameter order=1, parameter dw=14, parameter adv=3861, - parameter delta=264, // 8*33 - parameter ext_div_en=0 + parameter delta=16 ) ( input uclk, + input uclkg, input sclk, - input ext_div, output [dw-1:0] phase, output fault // single cycle ); @@ -24,14 +23,12 @@ module phaset #( // _Still_ draw analogy to the AD9901 // Generalize to a Johnson counter reg [order-1:0] ishr=0; -always @(posedge uclk) ishr <= (ishr << 1) | {{order-1{1'b0}},~ishr[order-1]}; -wire div = ishr[0]; -//reg div=0; always @(posedge uclk) div <= ~div; +always @(posedge uclk) if (uclkg) ishr <= (ishr << 1) | {{order-1{1'b0}},~ishr[order-1]}; +wire capture; reg_tech_cdc capture_cdc(.I(ishr[0]), .C(sclk), .O(capture)); // Test bench fails for some initial phase_r values between 14900 and 15050. // In that case the fault output signals the problem. reg [dw-1:0] osc=0, acc=0, phase_r=0; -reg capture=0; reg fault_r=0; wire msb = acc[dw-1]; wire nsb = acc[dw-2]; @@ -41,7 +38,6 @@ wire dir = ~nsb; wire dn = move & dir; wire up = move & ~dir; always @(posedge sclk) begin - capture <= ext_div_en ? ext_div : div; if (move) phase_r <= phase_r + (dir ? -delta : delta); fault_r <= move & peak; osc <= osc + adv; diff --git a/dsp/phaset_tb.v b/dsp/phaset_tb.v new file mode 100644 index 000000000..5b3cfd698 --- /dev/null +++ b/dsp/phaset_tb.v @@ -0,0 +1,80 @@ +`timescale 1ns / 1ps + +module phaset_tb; + +// In real life, this clock is not coherent with the unknown clock +reg sclk; // 200 MHz +integer cc; +reg glitch; +reg fail=0; +initial begin + if ($test$plusargs("vcd")) begin + $dumpfile("phaset.vcd"); + $dumpvars(5,phaset_tb); + end + glitch = $test$plusargs("glitch"); + for (cc=0; cc<24000; cc=cc+1) begin + sclk=0; #2.5; + sclk=1; #2.5; + end + $display("%s", fail ? "FAIL" : "PASS"); + if (fail) $stop(0); + $finish(0); +end + +// 94.286 MHz + epsilon +// divide by 33 +// 174.9 +reg uclk1; +always begin + uclk1=0; #5.301; + uclk1=1; #5.301; +end + +// Device under test +wire [13:0] phaset_out; +wire fault; +// round(2**14*1320/14/2/200) = 3862 is the DDS frequency +// delta kinda sets the gain and resolution of the phase tracking loop +phaset #(.dw(14), .adv(3862), .delta(16)) track( + .uclk(uclk1), .uclkg(1'b1), .sclk(sclk), + .phase(phaset_out), .fault(fault)); + +// Demonstration that changing internal divider state (not the uclk1 phase +// itself) will also toggle the msb of phaset_out. That bit should therefore +// be ignored. To exercise this feature, +// make phaset_view VCD_ARGS_phaset.vcd=+glitch +initial @(cc==3000) if (glitch) track.ishr[0] = ~track.ishr[0]; + +// Unwrapped phase +integer phase_unw=0, phase_diff, phase0; +reg [13:0] phaset_d=0; +reg first=1, rate_ok; +real rate, rate_want=1.42199585; // see below +integer t0=3000, tlen=20000; +always @(posedge sclk) if (cc>1000) begin + phaset_d <= phaset_out; + phase_diff = phaset_out - phaset_d; + if (phase_diff < -8192) phase_diff = phase_diff + 16384; + if (~first && (phase_diff > 16) || (phase_diff < -16)) fail = 1; + if (first) phase_unw = phaset_out; + else phase_unw <= phase_unw + phase_diff; + if (fault & ~glitch) fail = 1; + if (cc==t0) phase0 = phase_unw; + if (cc==(t0+tlen+1)) begin + $display("Delta phase %d bits / %d cycles", + phase_unw - phase0, tlen); + rate = (phase_unw - phase0) * 1.0 / tlen; + rate_ok = $abs(rate - rate_want) < 0.001*rate_want; + $display("Rate %.5f bits/cycle vs. theory %.5f %s", + rate, rate_want, rate_ok ? " OK" : "BAD"); + if (!glitch && !rate_ok) fail = 1; + end + first = 0; +end +// 3862/2**14*200 MHz = 47.143555 MHz DDS "local oscillator" +// 1/(2*5.301 ns)/2 = 47.160913 MHz input to be measured +// 1/(2*5.301e-9)/2 - 3862/2**14*200e6 = 17358.35 Hz offset +// 17358.35 Hz * 16384 / 200 MHz = 1.42199585 bits/cycle + +endmodule diff --git a/dsp/phasex.gtkw b/dsp/phasex.gtkw deleted file mode 100644 index 4916c3813..000000000 --- a/dsp/phasex.gtkw +++ /dev/null @@ -1,59 +0,0 @@ -[timestart] 0 -[size] 1150 707 -[pos] -1 -1 -*-23.233957 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -[treeopen] phasex_tb. -[treeopen] phasex_tb.track. -[sst_width] 210 -[signals_width] 219 -[sst_expanded] 1 -[sst_vpaned_height] 191 -@28 -phasex_tb.trig -phasex_tb.ready -phasex_tb.done -phasex_tb.f -@24 -phasex_tb.raddr[5:0] -@22 -phasex_tb.dout[15:0] -@8024 -phasex_tb.phase_diff[12:0] -@20000 -- -@420 -phasex_tb.vfreq_out[13:0] -@200 --dut -@28 -phasex_tb.dut.invalid -phasex_tb.dut.run -phasex_tb.dut.ready_r -@22 -phasex_tb.dut.count[8:0] -@28 -phasex_tb.dut.div2 -phasex_tb.dut.div1 -@22 -phasex_tb.dut.shiftr[15:0] -@28 -phasex_tb.dut.wen -@22 -phasex_tb.dut.waddr[5:0] -@200 --trackers -@8024 -phasex_tb.track.phaset_out1[13:0] -@20000 -- -@28 -phasex_tb.track.fault1 -@8024 -phasex_tb.track.phaset_out2[13:0] -@20000 -- -@28 -phasex_tb.track.fault2 -phasex_tb.track.tick -[pattern_trace] 1 -[pattern_trace] 0 diff --git a/dsp/phasex.v b/dsp/phasex.v index e5ecfdf2b..6efc3084a 100644 --- a/dsp/phasex.v +++ b/dsp/phasex.v @@ -1,7 +1,7 @@ `timescale 1ns / 1ns // DMTD-inspired investigation into clock phasing -// No on-chip analysis, that could be added later once we see the captured patterns +// No on-chip analysis, but that could be added later once we see the captured patterns module phasex #( parameter aw=10 ) ( @@ -40,7 +40,7 @@ wire [aw-1:0] waddr = count[aw+2:3]; // Data flow logic, also in sclk domain reg [15:0] shiftr=0; -reg [1:0] snap=0; +(* ASYNC_REG = "TRUE" *) reg [1:0] snap=0; always @(posedge sclk) begin snap <= {div2, div1}; // safely crosses clock domain if (run) shiftr <= {shiftr[13:0], snap}; diff --git a/dsp/rules.mk b/dsp/rules.mk index bd6b21c8f..3bd71f498 100644 --- a/dsp/rules.mk +++ b/dsp/rules.mk @@ -5,7 +5,7 @@ include $(CORDIC_DIR)/rules.mk VFLAGS_DEP += -I. -y . -y$(DSP_DIR) -y$(CORDIC_DIR) VFLAGS += -I. -y . -y$(DSP_DIR) -y$(CORDIC_DIR) -I$(AUTOGEN_DIR) -TEST_BENCH = data_xdomain_tb upconv_tb half_filt_tb complex_mul_tb tt800_tb rot_dds_tb mon_12_tb xy_pi_clip_tb iq_chain4_tb cordic_mux_tb timestamp_tb afterburner_tb ssb_out_tb banyan_tb banyan_mem_tb biquad_tb iirFilter_tb circle_buf_tb cic_multichannel_tb cic_wave_recorder_tb circle_buf_serial_tb iq_deinterleaver_tb serializer_multichannel_tb complex_freq_tb iq_trace_tb second_if_out_tb cpxmul_fullspeed_tb dpram_tb host_averager_tb cic_simple_us_tb phasex_tb complex_mul_flat_tb fwashout_tb lpass1_tb slew_xarray_tb isqrt_tb freq_count_tb +TEST_BENCH = data_xdomain_tb upconv_tb half_filt_tb complex_mul_tb tt800_tb rot_dds_tb mon_12_tb xy_pi_clip_tb iq_chain4_tb cordic_mux_tb timestamp_tb afterburner_tb ssb_out_tb banyan_tb banyan_mem_tb biquad_tb iirFilter_tb circle_buf_tb cic_multichannel_tb cic_wave_recorder_tb circle_buf_serial_tb iq_deinterleaver_tb serializer_multichannel_tb complex_freq_tb iq_trace_tb second_if_out_tb cpxmul_fullspeed_tb dpram_tb host_averager_tb cic_simple_us_tb phase_diff_tb phaset_tb complex_mul_flat_tb fwashout_tb lpass1_tb slew_xarray_tb isqrt_tb freq_count_tb TGT_ := $(TEST_BENCH) diff --git a/projects/oscope/common/digitizer_config.sv b/projects/oscope/common/digitizer_config.sv index a71db76bc..c2e6153ee 100644 --- a/projects/oscope/common/digitizer_config.sv +++ b/projects/oscope/common/digitizer_config.sv @@ -319,20 +319,16 @@ assign zif_cfg.U2_dco_clk_in = zif_cfg.U2_dco_clk_out; `define CONFIG_PHASE_DIFF `ifdef CONFIG_PHASE_DIFF +wire err_ff_U2, err_ff_U3; +wire [12:0] phdiff_out_U2, phdiff_out_U3; +wire [13:0] vfreq_out_U2, vfreq_out_U3; // Measure the phases of the two BUFR outputs relative to adc_clk (U2's BUFR after MMCM and BUFG) -wire [12:0] clk_phase_diff_out_U2, clk_phase_diff_out_U3; -wire [13:0] clk_phase_diff_freq_U2, clk_phase_diff_freq_U3; -wire clk_phase_diff_locked_U2, clk_phase_diff_locked_U3; -phase_diff phase_diff_U2(.uclk1(zif_cfg.U2_clk_div_bufg), .uclk2(zif_cfg.U2_clk_div_bufr), .sclk(clk200), - .rclk(lb_clk), .phdiff_out(clk_phase_diff_out_U2), - .ext_div1(1'b0), .ext_div2(1'b0), - .vfreq_out(clk_phase_diff_freq_U2), .locked(clk_phase_diff_locked_U2)); -assign phase_status_U2 = {~clk_phase_diff_locked_U2, clk_phase_diff_freq_U2,4'b0, clk_phase_diff_out_U2}; -phase_diff phase_diff_U3(.uclk1(zif_cfg.U2_clk_div_bufg), .uclk2(zif_cfg.U3_clk_div_bufr), .sclk(clk200), - .rclk(lb_clk), .phdiff_out(clk_phase_diff_out_U3), - .ext_div1(1'b0), .ext_div2(1'b0), - .vfreq_out(clk_phase_diff_freq_U3), .locked(clk_phase_diff_locked_U3)); -assign phase_status_U3 = {~clk_phase_diff_locked_U3,clk_phase_diff_freq_U3,4'b0,clk_phase_diff_out_U3}; +phase_diff #(.delta(33)) phase_diff_U2(.uclk1(zif_cfg.U2_clk_div_bufg), .uclk2(zif_cfg.U2_clk_div_bufr), .uclk2g(1'b1), .sclk(clk200), + .rclk(lb_clk), .phdiff_out(phdiff_out_U2), .vfreq_out(vfreq_out_U2), .err_ff(err_ff_U2)); +phase_diff #(.delta(33)) phase_diff_U3(.uclk1(zif_cfg.U2_clk_div_bufg), .uclk2(zif_cfg.U3_clk_div_bufr), .uclk2g(1'b1), .sclk(clk200), + .rclk(lb_clk), .phdiff_out(phdiff_out_U3), .vfreq_out(vfreq_out_U3), .err_ff(err_ff_U3)); +assign phase_status_U2 = {err_ff_U2, vfreq_out_U2, 4'b0, phdiff_out_U2}; +assign phase_status_U3 = {err_ff_U3, vfreq_out_U3, 4'b0, phdiff_out_U3}; `else assign phase_status_U2 = 0; assign phase_status_U3 = 0; From 5213cfb48c3e5a78e4b5017906c5ef38aa0e9a60 Mon Sep 17 00:00:00 2001 From: Lucas Russo Date: Thu, 7 Nov 2024 16:42:23 -0800 Subject: [PATCH 58/75] Dockerfile: install litex using litex-meta.sh script --- Dockerfile | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Dockerfile b/Dockerfile index af52d593b..57a64c312 100644 --- a/Dockerfile +++ b/Dockerfile @@ -114,3 +114,19 @@ RUN apt-get update && \ libidn12 && \ rm -rf /var/lib/apt/lists/* && \ ln -s libidn.so.12 /usr/lib/x86_64-linux-gnu/libidn.so.11 + +# Install litex +RUN apt-get update && \ + apt-get install -y \ + ninja-build \ + gcc-aarch64-linux-gnu \ + ghdl && \ + rm -rf /var/lib/apt/lists/* && \ + pip3 install \ + meson + +COPY build-tools/litex_meta.sh / + +RUN mkdir /litex && \ + cd /litex && \ + sh /litex_meta.sh From 82e328c3b02374ce2d3407521f5a7efecda841b4 Mon Sep 17 00:00:00 2001 From: Lucas Russo Date: Thu, 7 Nov 2024 16:49:41 -0800 Subject: [PATCH 59/75] Dockerfile: add LITEX_INSTALL_PATH as environment variable --- Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 57a64c312..61fbb2442 100644 --- a/Dockerfile +++ b/Dockerfile @@ -127,6 +127,8 @@ RUN apt-get update && \ COPY build-tools/litex_meta.sh / -RUN mkdir /litex && \ - cd /litex && \ +ENV LITEX_INSTALL_PATH=/litex + +RUN mkdir ${LITEX_INSTALL_PATH} && \ + cd ${LITEX_INSTALL_PATH} && \ sh /litex_meta.sh From da020568f81a98c5bd618f8d7eba29a356ab9dea Mon Sep 17 00:00:00 2001 From: Lucas Russo Date: Thu, 7 Nov 2024 16:55:15 -0800 Subject: [PATCH 60/75] .gitlab: avoid rebuilding litex every time by using the Dockerfile install --- .gitlab/ci/oscope.gitlab-ci.yml | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/.gitlab/ci/oscope.gitlab-ci.yml b/.gitlab/ci/oscope.gitlab-ci.yml index 854e258dd..9f46854f9 100644 --- a/.gitlab/ci/oscope.gitlab-ci.yml +++ b/.gitlab/ci/oscope.gitlab-ci.yml @@ -29,17 +29,15 @@ oscope_top_marble: paths: - projects/oscope/marble_family/oscope_top.bit +# LITEX_INSTALL_PATH is defined in the Docker image marble_ddr3_test: stage: synthesis before_script: - - apt-get update && apt-get install -y ninja-build && pip3 install meson==0.64.1 - - mkdir /litex_setup_dir - - (BD=$PWD && cd /litex_setup_dir && sh $BD/build-tools/litex_meta.sh) - - cd /litex_setup_dir/litex-boards/litex_boards/targets + - cd $LITEX_INSTALL_PATH/litex-boards/litex_boards/targets script: - XILINXD_LICENSE_FILE=$XILINXD_LICENSE_FILE PATH=$XILINX_VIVADO/bin:$PATH && python3 berkeleylab_marble.py --build - echo $CI_PROJECT_DIR - - cp /litex_setup_dir/litex-boards/litex_boards/targets/build/berkeleylab_marble/gateware/berkeleylab_marble.bit $CI_PROJECT_DIR/ + - cp $LITEX_INSTALL_PATH/litex-boards/litex_boards/targets/build/berkeleylab_marble/gateware/berkeleylab_marble.bit $CI_PROJECT_DIR/ artifacts: name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME" expire_in: 1 week @@ -50,9 +48,6 @@ marble_ddr3_test: litex_trigger_capture: stage: synthesis before_script: - - apt-get update && apt-get install -y ninja-build && pip3 install meson==0.64.1 - - mkdir /litex_setup_dir - - (BD=$PWD && cd /litex_setup_dir && sh $BD/build-tools/litex_meta.sh) - cd projects/trigger_capture script: XILINXD_LICENSE_FILE=$XILINXD_LICENSE_FILE PATH=$XILINX_VIVADO/bin:$PATH && make marble.bit From 7f1137df4a58cad1b64484771ed700070b32fa4b Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Mon, 11 Nov 2024 12:49:24 -0800 Subject: [PATCH 61/75] projects/oscope/marble_family/Makefile: more cdc_snitch work Fixes bug where yosys couldn't find top-level on its own --- projects/oscope/marble_family/Makefile | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/projects/oscope/marble_family/Makefile b/projects/oscope/marble_family/Makefile index b2b36ea4b..d31522b24 100644 --- a/projects/oscope/marble_family/Makefile +++ b/projects/oscope/marble_family/Makefile @@ -27,7 +27,7 @@ RTEFI_EXTRA_V = spi_flash_engine.v include $(BADGER_DIR)/rules.mk $(AUTOGEN_DIR)/moving_average.v: $(DSP_DIR)/moving_average/moving_average.py - $(PYTHON) $(DSP_DIR)/moving_average/moving_average.py > $(AUTOGEN_DIR)/moving_average.v + $(PYTHON) $(DSP_DIR)/moving_average/moving_average.py | grep -v '(* top' > $@ oscope_features: $(BUILD_DIR)/gen_features.py oscope_features.yaml $(PYTHON) $< -i $(filter %.yaml, $^) -c marble_v2 --split @@ -62,17 +62,20 @@ oscope_prep.v: $(AUTOGEN_DIR)/application_top_auto.vh $(AUTOGEN_DIR)/addr_map_ap oscope_pure_v.d: oscope_prep.v $(AUTOGEN_DIR)/config_romx.v $(RTEFI_V) $(AUTOGEN_DIR)/moving_average.v $(VERILOG) -Wno-timescale -o /dev/null $< -y$(AUTOGEN_DIR) $(VFLAGS_DEP) -M$@.$$$$ && sort -u < $@.$$$$ | tr '\n' ' ' | sed -e 's/^/oscope_pure_v_check oscope_prep_yosys.json: /' -e 's/ $$//' > $@ && rm $@.$$$$ # make this dependency file first, explicitly, if you are doing sv2v/cdc_snitch work +dep: oscope_pure_v.d -include oscope_pure_v.d -.PHONY: oscope_pure_v_check -# default VERILATOR includes -Wall, and I don't want that (yet?) +.PHONY: oscope_pure_v_check dep # dependencies from oscope_pure_v.d +# sv2v tends to make a lot of VARHIDDEN +# I don't like the 33 x UNDRIVEN +VLATOR_LINT_IGNORE += -Wno-UNUSED -Wno-VARHIDDEN -Wno-DECLFILENAME -Wno-CASEINCOMPLETE +VLATORFLAGS += -DSIMULATE oscope_pure_v_check: - verilator --lint-only -Wno-WIDTH -Wno-TIMESCALEMOD -Wno-PINMISSING -Wno-CASEINCOMPLETE -DSIMULATE $^ -OSCOPE_PURE_V = $(shell cat oscope_pure_v.d) + $(VERILATOR_LINT) YOSYS_JSON_OPTION += -DSIMULATE # most dependencies from oscope_pure_v.d oscope_prep_yosys.json: $(FPGA_FAMILY_DIR)/xilinx/IBUFGDS.v -# exercise with make oscope_prep_cdc.txt +# exercise with make dep && make oscope_prep_cdc.txt # ===== $(AUTOGEN_DIR)/config_romx.v: $(BUILD_DIR)/build_rom.py $(APP_NAME)_regmap.json @@ -100,7 +103,7 @@ download: include $(BUILD_DIR)/bottom_rules.mk CLEAN += *.bit *.bin *.prm $(APP_NAME)_regmap*.json scalar_$(APP_NAME)_regmap.json *_features*.json *_features*.vh oscope_marble*_features -CLEAN += system_top.xdc zest_connector.csv $(RTEFI_CLEAN) foo.gtkw +CLEAN += system_top.xdc zest_connector.csv $(RTEFI_CLEAN) foo.gtkw foo.vcd CLEAN += oscope_prep.v oscope_prep_yosys.json oscope_prep_cdc.txt oscope_pure_v.d CLEAN_DIRS += _xilinx .Xil From 7403e0a347f76fffa7ecc2264c1881f1e82cff45 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Mon, 11 Nov 2024 13:53:49 -0800 Subject: [PATCH 62/75] Maybe improve reliability of gige_sfp_ac701_run CI job Specify USB serial number, and insert sleep between program and ping Also sneak in another check into projects/test_marble_family/Makefile --- .gitlab/ci/comms_top.gitlab-ci.yml | 2 +- projects/comms_top/gige_eth/Makefile | 2 +- projects/test_marble_family/Makefile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab/ci/comms_top.gitlab-ci.yml b/.gitlab/ci/comms_top.gitlab-ci.yml index 47f124952..1c87bb98a 100644 --- a/.gitlab/ci/comms_top.gitlab-ci.yml +++ b/.gitlab/ci/comms_top.gitlab-ci.yml @@ -40,4 +40,4 @@ gige_sfp_ac701_run: dependencies: - gige_sfp_ac701 script: - - cd projects/comms_top/gige_eth && make hwload_ac701 && make hwtest_ac701 + - cd projects/comms_top/gige_eth && make hwload_ac701 SERIAL_NUM_OPT="-s 210203356870" && sleep 7 && make hwtest_ac701 diff --git a/projects/comms_top/gige_eth/Makefile b/projects/comms_top/gige_eth/Makefile index 88d8fa574..f7c187235 100644 --- a/projects/comms_top/gige_eth/Makefile +++ b/projects/comms_top/gige_eth/Makefile @@ -22,7 +22,7 @@ all: gen $(APP_NAME).bit $(APP_NAME).bit: $(IP_TCL) hwload_ac701: - xc3sprog -c jtaghs1_fast $(BITFILE) + xc3sprog -c jtaghs1_fast $(SERIAL_NUM_OPT) $(BITFILE) hwtest_ac701: ping -c2 $(SFP_IP) && cd ../test && python3 comms_top_test.py -t $(SFP_IP) -cf mem_test.cf diff --git a/projects/test_marble_family/Makefile b/projects/test_marble_family/Makefile index 602e2189b..9791dd4bb 100644 --- a/projects/test_marble_family/Makefile +++ b/projects/test_marble_family/Makefile @@ -41,7 +41,7 @@ vpath %.c $(BADGER_DIR)/tests $(BUILD_DIR) include $(HOMELESS_DIR)/freq_demo/freq_demo_rules.mk # This must go in front of include $(BADGER_DIR)/rules.mk -all: lb_marble_slave_tb marble_base_tb no_multiple_drivers_check marble_base_lint gps_test_tb ltm_sync_tb Vmarble_base dna_check +all: lb_marble_slave_tb marble_base_tb no_multiple_drivers_check marble_base_lint gps_test_tb ltm_sync_tb Vmarble_base dna_check mmc_mailbox_check # ===== # gps_test, too simple to need testing ... right From ca85a1a1268d36cae62a2e1db0e8228a10e709a9 Mon Sep 17 00:00:00 2001 From: Lucas Russo Date: Tue, 12 Nov 2024 15:47:51 -0800 Subject: [PATCH 63/75] Dockerfile: add sv2v to image --- Dockerfile | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 61fbb2442..56e5f7f03 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:bookworm-slim as testing_base_bookworm +FROM debian:bookworm-slim AS testing_base_bookworm # Vivado needs libtinfo5, at least for Artix? RUN apt-get update && \ @@ -132,3 +132,15 @@ ENV LITEX_INSTALL_PATH=/litex RUN mkdir ${LITEX_INSTALL_PATH} && \ cd ${LITEX_INSTALL_PATH} && \ sh /litex_meta.sh + +# Install sv2v +RUN apt-get update && \ + apt-get install -y \ + haskell-stack && \ + rm -rf /var/lib/apt/lists/* && \ + git clone https://github.com/zachjs/sv2v /sv2v && \ + cd /sv2v && \ + git checkout 7808819c48c167978aeb5ef34c6e5ed416e90875 && \ + make && \ + rm -rf $HOME/.stack && \ + cp bin/sv2v /usr/local/bin/ From e029f54471ed475c7981269403da3c7e7ff27665 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Wed, 13 Nov 2024 11:02:16 -0800 Subject: [PATCH 64/75] Put sv2v to work in oscope --- .gitlab/ci/oscope.gitlab-ci.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.gitlab/ci/oscope.gitlab-ci.yml b/.gitlab/ci/oscope.gitlab-ci.yml index 9f46854f9..a3885ee10 100644 --- a/.gitlab/ci/oscope.gitlab-ci.yml +++ b/.gitlab/ci/oscope.gitlab-ci.yml @@ -5,6 +5,20 @@ oscope_top_test: script: - make Voscope_top_tb && make Voscope_top_leep && make clean +# We know the design doesn't yet get evaluated as CDC-clean, at least in part +# due to Verilog inout ports being poorly supported by our tools. +# Please take out the error bypass (echo) if this ever gets fixed. +oscope_cdc: + before_script: + - cd projects/oscope/marble_family + stage: test + script: + - make dep && make oscope_prep_yosys.json && (make oscope_prep_cdc.txt || echo "Found CDC violation, as expected; continuing") + artifacts: + expire_in: 1 week + paths: + - projects/oscope/marble_family/oscope_prep_cdc.txt + oscope_top_bmb7: before_script: - cd projects/oscope/bmb7_cu && ls /non-free From c39f28414327617dbcef89d09c76d8a3a43e5d39 Mon Sep 17 00:00:00 2001 From: Lucas Russo Date: Wed, 13 Nov 2024 12:54:44 -0800 Subject: [PATCH 65/75] Use debian point release --- .gitlab/ci/build.gitlab-ci.yml | 1 + Dockerfile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab/ci/build.gitlab-ci.yml b/.gitlab/ci/build.gitlab-ci.yml index e801342f4..91fc1f723 100644 --- a/.gitlab/ci/build.gitlab-ci.yml +++ b/.gitlab/ci/build.gitlab-ci.yml @@ -15,6 +15,7 @@ build: -t $CONTAINER_IMAGE:$CI_PROJECT_NAME-$CI_COMMIT_SHORT_SHA \ -t $CONTAINER_IMAGE:latest \ . + docker run --rm $CONTAINER_IMAGE bash -c 'echo -n "Debian version: "; cat "/etc/debian_version"' docker push $CONTAINER_IMAGE:$CI_COMMIT_REF_NAME docker push $CONTAINER_IMAGE:$CI_PROJECT_NAME-$CI_COMMIT_SHORT_SHA docker push $CONTAINER_IMAGE:latest diff --git a/Dockerfile b/Dockerfile index 56e5f7f03..99e2ac481 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:bookworm-slim AS testing_base_bookworm +FROM debian:12.8-slim AS testing_base_bookworm # Vivado needs libtinfo5, at least for Artix? RUN apt-get update && \ From 679339f6607acb2d85c2d15f21da343383a28c0b Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Wed, 13 Nov 2024 13:34:40 -0800 Subject: [PATCH 66/75] Maybe improve reliability of badger_ac701_run CI job Specify USB serial number for bitfile load --- .gitlab/ci/badger.gitlab-ci.yml | 2 +- badger/tests/teststand_ac701.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab/ci/badger.gitlab-ci.yml b/.gitlab/ci/badger.gitlab-ci.yml index 09e881e53..ae5cbd874 100644 --- a/.gitlab/ci/badger.gitlab-ci.yml +++ b/.gitlab/ci/badger.gitlab-ci.yml @@ -25,4 +25,4 @@ badger_ac701_run: dependencies: - badger_ac701 script: - - cd badger/tests && test -r ac701_rgmii_vtest.bit && sh teststand_ac701.sh + - cd badger/tests && test -r ac701_rgmii_vtest.bit && SERIAL_NUM_OPT="-s 210203356870" sh teststand_ac701.sh diff --git a/badger/tests/teststand_ac701.sh b/badger/tests/teststand_ac701.sh index 48272720b..3b7841ad3 100644 --- a/badger/tests/teststand_ac701.sh +++ b/badger/tests/teststand_ac701.sh @@ -4,7 +4,7 @@ # Tested useful for the CI test stand (mohs) at LBNL. # Can also act as a template for other use cases. set -e -xc3sprog -c jtaghs1_fast ac701_rgmii_vtest.bit +xc3sprog -c jtaghs1_fast $SERIAL_NUM_OPT ac701_rgmii_vtest.bit echo "So far so good" sleep 8 echo "Hope links are up" From 14c81477d0e8a17138666b8c5f2cd535ff092b8c Mon Sep 17 00:00:00 2001 From: Lucas Russo Date: Thu, 14 Nov 2024 10:07:03 -0800 Subject: [PATCH 67/75] .gitlab-ci.yml: use repo-specific name for bedrock Docker image --- .gitlab-ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7caf17870..ae8072452 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,8 +8,7 @@ stages: variables: XILINX_VIVADO: /non-free/Xilinx/Vivado/2020.2 CI_REGISTRY: mohs.dhcp.lbl.gov - CONTAINER_IMAGE: $CI_REGISTRY/testing_base_bookworm - # CONTAINER_IM_IMAGE: $CI_REGISTRY/riscv_bloat + CONTAINER_IMAGE: $CI_REGISTRY/bedrock_testing_base_bookworm DOCKER_HOST: tcp://docker:2375/ DOCKER_DRIVER: overlay2 @@ -19,7 +18,6 @@ services: - name: mohs.dhcp.lbl.gov/docker:20.10.12-dind command: ["--insecure-registry", "mohs.dhcp.lbl.gov"] alias: docker -# entrypoint: ["dockerd-entrypoint.sh"] include: - local: .gitlab/ci/badger.gitlab-ci.yml From 2028c7f67768c2776ce304117ff50a6b41a21107 Mon Sep 17 00:00:00 2001 From: Shreeharshini Murthy Date: Fri, 15 Nov 2024 13:42:15 -0800 Subject: [PATCH 68/75] Refactor test_marble_family python scripts --- projects/test_marble_family/config_si570.py | 40 ++++++++++----------- projects/test_marble_family/testcase.py | 2 +- projects/test_marble_family/xadctemp.py | 6 ++-- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/projects/test_marble_family/config_si570.py b/projects/test_marble_family/config_si570.py index 3ebcae12d..0f194dc92 100644 --- a/projects/test_marble_family/config_si570.py +++ b/projects/test_marble_family/config_si570.py @@ -16,7 +16,7 @@ from time import sleep -def decode_settings(mbox, verbose): +def decode_settings(mbox, verbose=False): for page in range(7): subset = mbox[page*16:page*16+16] if verbose: @@ -164,19 +164,19 @@ def hw_write_prog(si570_addr, start_addr, reg): # check if the final output frequency is <= 50 ppm -def check(fin): - ppm = ((fin)*(1/args.new_freq) - 1.0)*1e6 +def check(fin, new_freq): + ppm = ((fin)*(1/new_freq) - 1.0)*1e6 if abs(ppm) >= 50: raise ValueError('SI570 final frequency measurement is not correct, out of spec by %i ppm' % ppm) -def compute_si570(addr, key, verbose): +def compute_si570(addr, key, verbose=False, debug=False): mbox = addr.reg_read(["spi_mbox"])[0] # using keyword just to keep print consistent _, si570_addr, polarity, config_addr, _ = decode_settings(mbox, verbose) prog = hw_test_prog(si570_addr, polarity, config_addr) - result = testcase.run_testcase(addr, prog, result_len=359, debug=args.debug, verbose=verbose) - if args.debug: + result = testcase.run_testcase(addr, prog, result_len=359, debug=debug, verbose=verbose) + if debug: print(" ".join(["%2.2x" % p for p in prog])) print("") for jx in range(16): @@ -195,7 +195,7 @@ def compute_si570(addr, key, verbose): # keep everything in MHz fdco = default * n1 * hs_div fxtal = fdco / rfreq - if args.verbose: + if verbose: print('%s SI570 settings:' % key) print('REFREQ: %4.4f' % rfreq) print('N1: %3d' % n1) @@ -208,15 +208,15 @@ def compute_si570(addr, key, verbose): return si570_addr, config_addr, fxtal, default -def config_si570(addr, verbose): - if args.new_freq: - si570_addr, config_addr, fxtal, default = compute_si570(addr, "Measured", verbose) +def config_si570(addr, new_freq, verbose=False, debug=False): + if new_freq: + si570_addr, config_addr, fxtal, default = compute_si570(addr, "Measured", verbose, debug) # if first measured frequency and new output frequency are < 10 ppm don't change/update - if abs(((default)*(1/args.new_freq) - 1.0)*1e6) < 10: + if abs(((default)*(1/new_freq) - 1.0)*1e6) < 10: pass else: print("#######################################") - print("Changing output frequency to %4.4f MHz" % args.new_freq) + print("Changing output frequency to %4.4f MHz" % new_freq) # DCO frequency range: 4850 - 5670MHz # HSDIV values: 4, 5, 6, 7, 9 or 11 (subtract 4 to store) # N1 values: 1, 2, 4, 6, 8...128 @@ -227,7 +227,7 @@ def config_si570(addr, verbose): if i == 0: n1_i = 1 for hsdiv_i in [4, 5, 6, 7, 9, 11]: - fdco_i = args.new_freq * n1_i * hsdiv_i + fdco_i = new_freq * n1_i * hsdiv_i if (fdco_i > 4850.0) and (fdco_i < 5670.0): # print(n1_i-1, hsdiv_i-4, fdco_i) if fdco_i < best[2]: @@ -236,7 +236,7 @@ def config_si570(addr, verbose): if best[2] > 5700.0: raise Exception('Could not find appropriate settings for your new target frequency') - if args.debug: + if debug: print('New best option is:') print(best[0]-1, best[1]-4, best[2]) @@ -261,8 +261,8 @@ def config_si570(addr, verbose): # write new registers reg = [reg7, reg8, reg9, reg10, reg11, reg12] chg = hw_write_prog(si570_addr, config_addr, reg) - result1 = testcase.run_testcase(addr, chg, result_len=359, debug=args.debug, verbose=verbose) - if args.debug: + result1 = testcase.run_testcase(addr, chg, result_len=359, debug=debug, verbose=verbose) + if debug: print(" ".join(["%2.2x" % p for p in chg])) print("") for jx in range(16): @@ -272,11 +272,11 @@ def config_si570(addr, verbose): sleep(1) # read final values and output frequency? print("#######################################") - _, _, _, freq = compute_si570(addr, "Final", verbose) - check(freq) + _, _, _, freq = compute_si570(addr, "Final", verbose, debug) + check(freq, new_freq) else: # read only current settings if you don't want to change anything print("#######################################") - compute_si570(addr, "Measured", verbose) + compute_si570(addr, "Measured", verbose, debug) if __name__ == "__main__": @@ -297,7 +297,7 @@ def config_si570(addr, verbose): # dev = lbus_access.lbus_access(args.addr, port=args.port, timeout=3.0, allow_burst=False) - config_si570(addr, args.verbose) + config_si570(addr, args.new_freq, args.verbose, args.debug) # usage: # To read current output frequency: diff --git a/projects/test_marble_family/testcase.py b/projects/test_marble_family/testcase.py index 721643a45..a46a14cd0 100644 --- a/projects/test_marble_family/testcase.py +++ b/projects/test_marble_family/testcase.py @@ -5,7 +5,6 @@ sys.path.append(bedrock_dir + "peripheral_drivers/i2cbridge") sys.path.append(bedrock_dir + "badger") sys.path.append(bedrock_dir + "projects/common") -import leep from c2vcd import produce_vcd from fmc_test_l import fmc_decode @@ -352,6 +351,7 @@ def print_result(result, args, board_type, si570_dfreq, poll_only=False): # OK, setup is finished, start the actual work # dev = lbus_access.lbus_access(addr, port=port, timeout=3.0, allow_burst=False) + import leep leep_addr = "leep://" + addr + ":" + str(port) print(leep_addr) dev = leep.open(leep_addr, timeout=5.0) diff --git a/projects/test_marble_family/xadctemp.py b/projects/test_marble_family/xadctemp.py index 8a00945da..5fd7ab0c2 100644 --- a/projects/test_marble_family/xadctemp.py +++ b/projects/test_marble_family/xadctemp.py @@ -1,7 +1,11 @@ #!/usr/bin/python3 # Convert xadc internal temperature register value (leep xadc_internal_temperature) # to degrees Celsius. +import sys import re +bedrock_dir = "../../" +sys.path.append(bedrock_dir + "projects/common") +import leep def _allhex(s): @@ -102,13 +106,11 @@ def doLeep(ipaddr, port): if __name__ == "__main__": - import sys import argparse parser = argparse.ArgumentParser( description="Utility to read internal temperature of ") parser.add_argument('-a', '--addr', required=True, help='IP address (required)') parser.add_argument('-p', '--port', type=int, default=803, help='Port number (default 803)') - import leep args = parser.parse_args() sys.exit(doLeep(args.addr, args.port)) From 944927087bf3f7eea95c837374a69fd364095c9e Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Fri, 15 Nov 2024 15:04:45 -0800 Subject: [PATCH 69/75] More consistency in makefiles --- badger/doc/Makefile | 5 +++-- badger/tests/Makefile | 5 ++--- board_support/bmb7_kintex/jxj_gate.mk | 2 +- board_support/sp605/Makefile | 12 ++++++------ build-tools/Makefile | 3 ++- build-tools/top_rules.mk | 4 +++- cmoc/Makefile | 2 +- fpga_family/spartan6/rules.mk | 2 +- projects/common/leep/Makefile | 6 +++--- projects/comms_top/gige_eth/Makefile | 2 +- projects/oscope/bmb7_cu/Makefile | 2 +- projects/oscope/common/llspi.mk | 2 +- projects/oscope/marble_family/Makefile | 14 +++++++++++--- projects/test_marble_family/i2c/Makefile | 10 +++++----- projects/trigger_capture/Makefile | 7 ++++--- soc/picorv32/rules.mk | 11 ++++++----- soc/picorv32/test/badger_lwip/Makefile | 2 +- 17 files changed, 52 insertions(+), 39 deletions(-) diff --git a/badger/doc/Makefile b/badger/doc/Makefile index 46599cc92..88a2ae5bc 100644 --- a/badger/doc/Makefile +++ b/badger/doc/Makefile @@ -1,6 +1,7 @@ # Commentary in ../tests/Makefile XCIRCUIT = xcircuit XVFB = xvfb-run -a -s "-screen 0 1440x900x24" +PANDOC = pandoc all: svg .PHONY: svg html @@ -14,10 +15,10 @@ html: ../index.html ../status.html echo "page load $<; svg; exit" > .xcircuitrc; $(XVFB) $(XCIRCUIT); rm .xcircuitrc ../index.html: ../README.md - pandoc -t html $< | sed -e 's,status\.md,status.html,g' > $@ + $(PANDOC) -t html $< | sed -e 's,status\.md,status.html,g' > $@ ../status.html: ../status.md - pandoc -t html -o $@ $< + $(PANDOC) -t html -o $@ $< clean: rm -f *.svg *.html diff --git a/badger/tests/Makefile b/badger/tests/Makefile index 9c52d38b6..dabc92699 100644 --- a/badger/tests/Makefile +++ b/badger/tests/Makefile @@ -38,7 +38,6 @@ VLATOR_LINT_IGNORE += -Wno-UNUSED -Wno-DECLFILENAME # Configuration not covered (yet?) by Bedrock's top_rules.mk VCD_ARGS = $(VCD_ARGS_$@) VVP_FLAGS = ${VVP_FLAGS_$@} ${VCD_ARGS_$@} -PERL = perl XCIRCUIT = xcircuit # XXX consider converting this to something more compatible with Bedrock's VIVADO_SYNTH. VIVADOEXEC = vivado @@ -89,10 +88,10 @@ crc_selfcheck: crc_selfcheck.o crc32.o derive_tb: crc_genguts.vh crc_genguts.vh: crc_derive - ./$^ 16 0x1021 32 > $@ + ./$< 16 0x1021 32 > $@ crc8e_guts.vh: crc_derive - ./$^ -lsb 32 0x04C11DB7 8 > $@ + ./$< -lsb 32 0x04C11DB7 8 > $@ # New feature compared to PSPEPS: no include file (or path) needed! # crc8e_guts.v is pre-filled in. The following steps give its derivation diff --git a/board_support/bmb7_kintex/jxj_gate.mk b/board_support/bmb7_kintex/jxj_gate.mk index 243a0bff4..ffff9f83f 100644 --- a/board_support/bmb7_kintex/jxj_gate.mk +++ b/board_support/bmb7_kintex/jxj_gate.mk @@ -23,7 +23,7 @@ COMMON_HDL_DIR = submodules/common-hdl $(VVP) $< $(VFLAGS) %.dat: %_tb - vvp $< > $@ + $(VVP) $< > $@ all: jxj_gate_tb diff --git a/board_support/sp605/Makefile b/board_support/sp605/Makefile index 4d73ebb93..87960d181 100644 --- a/board_support/sp605/Makefile +++ b/board_support/sp605/Makefile @@ -1,26 +1,26 @@ ether_mc_sp605.bit: ether_mc_sp605.v $(ETH_MC_DEPS) $(FPGA_DIR)/sp60x_clocks.v config_romx_sp605.v sp605_gmii_base.ucf - PART=xc6slx45t-fgg484-3 $(SYNTH) ether_mc $^ + PART=xc6slx45t-fgg484-3 $(SYNTH) ether_mc $^ mv _xilinx/ether_mc.bit $@ ether_fllrf_sp605.bit: ether_fllrf_sp605.v $(BUILD_v_fllrf) $(FPGA_DIR)/sp60x_clocks.v config_romx_sp605.v sp605_gmii_base.ucf - PART=xc6slx45t-fgg484-3 $(SYNTH) ether_fllrf $^ + PART=xc6slx45t-fgg484-3 $(SYNTH) ether_fllrf $^ mv _xilinx/ether_fllrf.bit $@ ether_mgt_sp605_tb: ether_gtp_sp605_tb.v $(S6GTP_SUPPORT) BUFG.v IBUFDS.v $(S6GTP_XILINX_SIM_MODULE) ## mgt support on Spartan 6 ether_mgt_sp605.bit: ether_mgt_sp605.v $(S6GTP_SUPPORT) $(FPGA_DIR)/sp60x_clocks.v config_romx_sp605.v sp605_mgt_base.ucf $(ETH_MGT_DEPS) - PART=xc6slx45t-fgg484-3 $(SYNTH) ether_mgt $^ + PART=xc6slx45t-fgg484-3 $(SYNTH) ether_mgt $^ mv _xilinx/ether_mgt.bit $@ ether_both_sp605.bit: ether_both_sp605.v $(S6GTP_SUPPORT) $(ETH_MC_DEPS) $(FPGA_DIR)/sp60x_clocks.v config_romx_sp605.v $(COMMON_HDL_DIR)/data_xdomain.v $(COMMON_HDL_DIR)/flag_xdomain.v sp605_mgt_gmii_base.ucf $(ETH_MGT_DEPS) $(TXU) - PART=xc6slx45t-fgg484-3 $(SYNTH) ether_both_sp605 $^ + PART=xc6slx45t-fgg484-3 $(SYNTH) ether_both_sp605 $^ mv _xilinx/ether_both_sp605.bit $@ ether_fmc_mgt_sp605.bit: ether_fmc_mgt_sp605.v ether_fmc_mgt.vh $(S6GTP_SUPPORT) $(ETH_MC_DEPS) $(FPGA_DIR)/sp60x_clocks.v config_romx_sp605.v sp605_mgt_fmc.ucf $(FMC_SUPPORT) $(DDR_SUPPORT) - PART=xc6slx45t-fgg484-3 $(SYNTH) ether_fmc_mgt $^ + PART=xc6slx45t-fgg484-3 $(SYNTH) ether_fmc_mgt $^ mv _xilinx/ether_fmc_mgt.bit $@ ether_fmc_mc_sp605.bit: ether_fmc_mc_sp605.v ether_fmc_mc.vh $(FPGA_DIR)/sp60x_clocks.v config_romx_sp605.v sp605_gmii_fmc.ucf $(FMC_SUPPORT) $(DDR_SUPPORT) - PART=xc6slx45t-fgg484-3 $(SYNTH) ether_fmc_mc $^ + PART=xc6slx45t-fgg484-3 $(SYNTH) ether_fmc_mc $^ mv _xilinx/ether_fmc_mc.bit $@ diff --git a/build-tools/Makefile b/build-tools/Makefile index 1c319ad78..e3d5988ed 100644 --- a/build-tools/Makefile +++ b/build-tools/Makefile @@ -4,6 +4,7 @@ XCIRCUIT = xcircuit XVFB = xvfb-run -a -s "-screen 0 1440x900x24" +PANDOC = pandoc # Kind of weird to use xcircuit's rc file for this purpose, # but it does work. @@ -15,7 +16,7 @@ all: cdc_snitch.html # We can generate a quick preview with pandoc. cdc_snitch.md is also # checked compatible with sphinx, gitlab, and github. cdc_snitch.html: cdc_snitch.md cdc_BAD.svg cdc_OK1.svg cdc_OKX.svg - pandoc -t html $< > $@ + $(PANDOC) -t html $< > $@ clean: rm -f cdc_snitch.html diff --git a/build-tools/top_rules.mk b/build-tools/top_rules.mk index 96ec2b70f..9adfcecc9 100644 --- a/build-tools/top_rules.mk +++ b/build-tools/top_rules.mk @@ -18,8 +18,10 @@ VERILATOR = verilator -Wall -Wno-fatal GTKWAVE = gtkwave VPIEXT = vpi PYTHON = python3 +PERL = perl AWK = awk XCIRCUIT = xcircuit +SV2V = sv2v YOSYS = yosys YOSYS_QUIET = -q YOSYS_JSON_OPTION = -DBUGGY_FORLOOP @@ -224,4 +226,4 @@ COMMA := , dot -Tps $< -o $@ %_support.vh: $(BS_HARDWARE_DIR)/%_support.in - perl $(BUILD_DIR)/regmap_proc.pl $< > $@ + $(PERL) $(BUILD_DIR)/regmap_proc.pl $< > $@ diff --git a/cmoc/Makefile b/cmoc/Makefile index e7bb10443..2befd6445 100644 --- a/cmoc/Makefile +++ b/cmoc/Makefile @@ -38,7 +38,7 @@ fdbk_core.vcd: $(AUTOGEN_DIR)/regmap_fdbk_core_tb.json fdbk_core.vcd: fdbk_core_tb fdbk_core_test.py $(PYTHON) fdbk_core_test.py fdbk_core_check: fdbk_core.vcd - @ echo DONE + @echo DONE cryomodule_in.dat: cryomodule_test_setup.py $(AUTOGEN_DIR)/regmap_cryomodule.json $(PYTHON) cryomodule_test_setup.py | sed -e 's/ *#.*//' | grep . > $@ diff --git a/fpga_family/spartan6/rules.mk b/fpga_family/spartan6/rules.mk index 9d3e1e776..3f04f12b0 100644 --- a/fpga_family/spartan6/rules.mk +++ b/fpga_family/spartan6/rules.mk @@ -1,4 +1,4 @@ s6_gtp_params.vh: - perl $(BUILD_DIR)/ucf2par $(FPGA_FAMILY_DIR)/$(FPGA_FAMILY)/s6gtp.ucf > $@ + $(PERL) $(BUILD_DIR)/ucf2par $(FPGA_FAMILY_DIR)/$(FPGA_FAMILY)/s6gtp.ucf > $@ CLEAN += s6_gtp_params.vh diff --git a/projects/common/leep/Makefile b/projects/common/leep/Makefile index c9acd5a0b..c74922b37 100644 --- a/projects/common/leep/Makefile +++ b/projects/common/leep/Makefile @@ -2,9 +2,9 @@ THIS_DIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))) include $(THIS_DIR)/../../../dir_list.mk -PYTHON=python3 +PYTHON = python3 -LEEP_CORE=base.py raw.py ca.py file.py logic.py +LEEP_CORE = base.py raw.py ca.py file.py logic.py all: test_cli test_raw @@ -20,7 +20,7 @@ test_raw: raw.py server: $(LEEP_CORE) cli.py PYTHONPATH="$(THIS_DIR)/..:$(BUILD_DIR)" $(PYTHON) -m leep.test.test_cli server -CLEANS=test.json +CLEANS = test.json clean: rm -rf $(CLEANS) diff --git a/projects/comms_top/gige_eth/Makefile b/projects/comms_top/gige_eth/Makefile index f7c187235..f49bab27c 100644 --- a/projects/comms_top/gige_eth/Makefile +++ b/projects/comms_top/gige_eth/Makefile @@ -25,7 +25,7 @@ hwload_ac701: xc3sprog -c jtaghs1_fast $(SERIAL_NUM_OPT) $(BITFILE) hwtest_ac701: - ping -c2 $(SFP_IP) && cd ../test && python3 comms_top_test.py -t $(SFP_IP) -cf mem_test.cf + ping -c 2 $(SFP_IP) && cd ../test && $(PYTHON) comms_top_test.py -t $(SFP_IP) -cf mem_test.cf ifneq (,$(findstring bit,$(MAKECMDGOALS))) ifneq (,$(findstring bits,$(MAKECMDGOALS))) diff --git a/projects/oscope/bmb7_cu/Makefile b/projects/oscope/bmb7_cu/Makefile index afd967198..28c2669f3 100644 --- a/projects/oscope/bmb7_cu/Makefile +++ b/projects/oscope/bmb7_cu/Makefile @@ -57,7 +57,7 @@ Voscope_top_leep: Voscope_top_tb $(APP_NAME)_regmap.json @echo "----- Oscope leep list self-test -----" timeout 20 ./$< & PYTHONPATH=$(PROJECTS_DIR)/common/ $(PYTHON) -m leep.cli leep://localhost:3010 list > leep_list.txt - awk -F'"' '/ {/{print $$2}' $(APP_NAME)_regmap.json | cmp leep_list.txt - + $(AWK) -F'"' '/ {/{print $$2}' $(APP_NAME)_regmap.json | cmp leep_list.txt - Voscope_top_live: Voscope_top_tb $(APP_NAME)_regmap.json @echo "----- Oscope build rom live test -----" diff --git a/projects/oscope/common/llspi.mk b/projects/oscope/common/llspi.mk index 5ebb1378d..0515843ae 100644 --- a/projects/oscope/common/llspi.mk +++ b/projects/oscope/common/llspi.mk @@ -23,7 +23,7 @@ PYTHON = python3 $(VVP) $< $(VFLAGS) %.dat: %_tb - vvp $< > $@ + $(VVP) $< > $@ all: llspi_tb diff --git a/projects/oscope/marble_family/Makefile b/projects/oscope/marble_family/Makefile index d31522b24..4ec3dab28 100644 --- a/projects/oscope/marble_family/Makefile +++ b/projects/oscope/marble_family/Makefile @@ -53,11 +53,15 @@ oscope_top.sv: $(AUTOGEN_DIR)/config_romx.v $(RTEFI_V) $(AUTOGEN_DIR)/applicatio oscope_top.bit: $(AUTOGEN_DIR)/config_romx.v # ===== -# highly experimental and still somewhat messy -# sv2v not supplied; see https://github.com/zachjs/sv2v +# Process code base with sv2v, verilator, yosys, and cdc_snitch +# Experimental and still somewhat messy +# Exposes weaknessess in our tools' handling of inout ports; see +# https://github.com/zachjs/sv2v/issues/295 +# https://github.com/YosysHQ/yosys/issues/4708 +# https://github.com/verilator/verilator/issues/2844 UPPER_SV = oscope_top.sv $(OSCOPE_COMMON_DIR)/application_top.sv $(BOARD_SUPPORT_DIR)/zest/zest_cfg_if.sv $(BOARD_SUPPORT_DIR)/zest/zest_if.sv $(BOARD_SUPPORT_DIR)/zest/zest_wrap.sv $(OSCOPE_COMMON_DIR)/digitizer_config.sv oscope_prep.v: $(AUTOGEN_DIR)/application_top_auto.vh $(AUTOGEN_DIR)/addr_map_application_top.vh oscope_marble2_features - sv2v -DSIMULATE -DVERILATOR -I $(AUTOGEN_DIR) $(UPPER_SV) > $@ + $(SV2V) -DSIMULATE -DVERILATOR -I $(AUTOGEN_DIR) $(UPPER_SV) > $@ wc -l $@ oscope_pure_v.d: oscope_prep.v $(AUTOGEN_DIR)/config_romx.v $(RTEFI_V) $(AUTOGEN_DIR)/moving_average.v $(VERILOG) -Wno-timescale -o /dev/null $< -y$(AUTOGEN_DIR) $(VFLAGS_DEP) -M$@.$$$$ && sort -u < $@.$$$$ | tr '\n' ' ' | sed -e 's/^/oscope_pure_v_check oscope_prep_yosys.json: /' -e 's/ $$//' > $@ && rm $@.$$$$ @@ -72,6 +76,10 @@ VLATOR_LINT_IGNORE += -Wno-UNUSED -Wno-VARHIDDEN -Wno-DECLFILENAME -Wno-CASEINCO VLATORFLAGS += -DSIMULATE oscope_pure_v_check: $(VERILATOR_LINT) +# exercise with make dep && make oscope_pure_v_check +# or make dep && make oscope_prep_lint +# same result, but different dependency list management +# YOSYS_JSON_OPTION += -DSIMULATE # most dependencies from oscope_pure_v.d oscope_prep_yosys.json: $(FPGA_FAMILY_DIR)/xilinx/IBUFGDS.v diff --git a/projects/test_marble_family/i2c/Makefile b/projects/test_marble_family/i2c/Makefile index e9ff48874..9616b851e 100644 --- a/projects/test_marble_family/i2c/Makefile +++ b/projects/test_marble_family/i2c/Makefile @@ -1,14 +1,14 @@ # A demo of Marble-specific I2C functionality -PYTHON=python3 +PYTHON = python3 -TARGETS=prog.dat prog.vh prog.h prog.json +TARGETS = prog.dat prog.vh prog.h prog.json .PHONY: all all: $(TARGETS) # ======= Build a program for i2c_chunk -PROG_FILE=demo_marble_i2c.py +PROG_FILE = demo_marble_i2c.py prog.dat: $(PROG_FILE) $(PYTHON) $< > $@ @@ -25,13 +25,13 @@ prog.json: $(PROG_FILE) $(PYTHON) $< j 0x800 > $@ # ======= Test a bunch of assembler violations -BAD_FILE=demo_i2c_baddy.py +BAD_FILE = demo_i2c_baddy.py .PHONY: test test: $(BAD_FILE) $(PYTHON) $< # ======= Decode a program in marble context -DECODE_FILE=marble_i2c_decoder.py +DECODE_FILE = marble_i2c_decoder.py .PHONY: decode decode: prog.dat $(PYTHON) $(DECODE_FILE) $< diff --git a/projects/trigger_capture/Makefile b/projects/trigger_capture/Makefile index 75b41c0b9..938967993 100644 --- a/projects/trigger_capture/Makefile +++ b/projects/trigger_capture/Makefile @@ -1,11 +1,12 @@ +PYTHON = python3 marble.bit: echo "dummy" > firmware/app.bin - python3 marble.py --no-compile-gateware --csr-csv csr.csv --cpu-type picorv32 --uart-name crossover + $(PYTHON) marble.py --no-compile-gateware --csr-csv csr.csv --cpu-type picorv32 --uart-name crossover make -C firmware clean all - python3 marble.py --build --csr-csv csr.csv --cpu-type picorv32 --uart-name crossover+uartbone + $(PYTHON) marble.py --build --csr-csv csr.csv --cpu-type picorv32 --uart-name crossover+uartbone load: - python3 marble.py --load --no-compile-gateware --no-compile-software + $(PYTHON) marble.py --load --no-compile-gateware --no-compile-software clean: rm -rf build diff --git a/soc/picorv32/rules.mk b/soc/picorv32/rules.mk index 20a1f4697..71ea876ae 100644 --- a/soc/picorv32/rules.mk +++ b/soc/picorv32/rules.mk @@ -41,8 +41,7 @@ LDFLAGS = $(CLFLAGS) -Wl,--strip-debug,--print-memory-usage,-Bstatic,-Map,$*.map %_load: %32.hex $(PYTHON) $(COMMON_DIR)/boot_load.py $< $(BOOTLOADER_SERIAL) --baud_rate $(BOOTLOADER_BAUDRATE) -# All testbenches use $stop, eliminating the `awk` dependency -%_check: %_tb +# All testbenches use $stop, eliminating the old `awk` dependency %_check: %_tb $(VERILOG_SIM) @@ -57,10 +56,12 @@ LDFLAGS = $(CLFLAGS) -Wl,--strip-debug,--print-memory-usage,-Bstatic,-Map,$*.map chmod -x $@ %_synth.bit: %.v - vivado -nojou -mode batch -source $(filter %.tcl, $^) -tclargs $(basename $@) $(BLOCK_RAM_SIZE) $(filter %.v, $^) + $(VIVADO_CMD) -source $(filter %.tcl, $^) -tclargs $(basename $@) $(BLOCK_RAM_SIZE) $(filter %.v, $^) -%_config: - xc3sprog -c jtaghs1_fast $(patsubst %_config,%.bit,$@) +# No serial number is provided in this rule, so it's only useful when +# a single FTDI device is plugged into your workstation +%_config: %.bit + xc3sprog -c jtaghs1_fast $< CLEAN += $(TARGET).vcd $(TARGET)_tb $(TARGET).map $(TARGET).lst $(TARGET).elf pico.trace CLEAN += $(TARGET)8.hex $(TARGET)32.hex $(TARGET)32.dat $(TARGET).o $(OBJS) diff --git a/soc/picorv32/test/badger_lwip/Makefile b/soc/picorv32/test/badger_lwip/Makefile index 7d5c5ccee..2772ca907 100644 --- a/soc/picorv32/test/badger_lwip/Makefile +++ b/soc/picorv32/test/badger_lwip/Makefile @@ -51,7 +51,7 @@ CFLAGS += -DLWIP_DEBUG # builds an hardware emulator for running / debugging lwip # -DETHERNET_MODEL_DEBUG V$(TARGET): $(SRC_V) $(TARGET)_sim.cpp ethernet_model.c tap_alloc.c crc32.c - verilator --trace -cc --exe --top-module $(TARGET)_tb \ + $(VERILATOR) --trace -cc --exe --top-module $(TARGET)_tb \ -Wno-PINMISSING -Wno-WIDTH -Wno-CASEINCOMPLETE \ -DBLOCK_RAM_SIZE=$(BLOCK_RAM_SIZE) \ -CFLAGS "-I$(BADGER_DIR)/tests" \ From 529255cf7eb42345c5925fa9eeab6db6f2348a92 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Wed, 4 Dec 2024 16:37:16 -0800 Subject: [PATCH 70/75] rejigger boundary between freq_count and freq_gcount _No_ change to use of freq_count _Breaking_ change to instantiations of freq_gcount freq_gcount: replace internal (parameterized) reference divider with ref_strobe port promote localparam gw (Gray code width) to full parameter remove archaic glitch diagnostic ports add xcount, a raw per-sysclk cycle count of (gated) f_in events Various small adjustments and improvements to comments and test bench --- dsp/freq_count.gtkw | 7 +++-- dsp/freq_count.v | 58 ++++++++++++++++++++++++++++------- dsp/freq_count_tb.v | 3 +- dsp/freq_gcount.v | 73 +++++++++++++++++---------------------------- 4 files changed, 82 insertions(+), 59 deletions(-) diff --git a/dsp/freq_count.gtkw b/dsp/freq_count.gtkw index 26659afbd..6a16144bf 100644 --- a/dsp/freq_count.gtkw +++ b/dsp/freq_count.gtkw @@ -3,11 +3,12 @@ [pos] -1 -1 *-6.533834 3870 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 [treeopen] freq_count_tb. -[sst_width] 210 +[sst_width] 213 [signals_width] 174 [sst_expanded] 1 [sst_vpaned_height] 154 @28 +freq_count_tb.clk freq_count_tb.f_in @22 freq_count_tb.diff_stream[15:0] @@ -15,12 +16,14 @@ freq_count_tb.diff_stream[15:0] freq_count_tb.diff_stream_strobe @24 freq_count_tb.frequency[27:0] +@28 +freq_count_tb.mut.freq_strobe @22 freq_count_tb.mut.work.gray1[3:0] freq_count_tb.mut.work.gray3[3:0] @24 freq_count_tb.mut.work.diff1[3:0] -freq_count_tb.mut.work.refcnt[5:0] +freq_count_tb.mut.refcnt[5:0] freq_count_tb.mut.work.accum[27:0] [pattern_trace] 1 [pattern_trace] 0 diff --git a/dsp/freq_count.v b/dsp/freq_count.v index d07a5bd61..8f95b8b76 100644 --- a/dsp/freq_count.v +++ b/dsp/freq_count.v @@ -4,7 +4,7 @@ `timescale 1ns / 1ns module freq_count #( - // Default configuration useful for input frequencies < 96 MHz + // Default configuration useful for input frequencies < 2*sysclk parameter glitch_thresh=2, parameter refcnt_width=24, parameter freq_width=28, @@ -15,26 +15,64 @@ module freq_count #( input f_in, // unknown input // outputs in sysclk domain - output [freq_width-1:0] frequency, + output reg [freq_width-1:0] frequency, output freq_strobe, - output [15:0] diff_stream, - output diff_stream_strobe, + output reg [15:0] diff_stream, + output reg diff_stream_strobe, // glitch_catcher can be routed to a physical pin to trigger // a 'scope; see glitch_thresh parameter above - output glitch_catcher + output reg glitch_catcher ); +initial begin + frequency=initv; + diff_stream=0; + diff_stream_strobe=0; + glitch_catcher=0; +end + +// Reference counter +// may or may not be synchronized between instances +reg [refcnt_width-1:0] refcnt=0; +reg ref_strobe=0, stream_strobe=0; +always @(posedge sysclk) begin + {ref_strobe, refcnt} <= refcnt + 1; + stream_strobe <= refcnt[1:0] == 0; +end + +wire [3:0] xcount; // per-sysclk count of f_in edges +wire [freq_width-1:0] frequency_w; freq_gcount #( - .glitch_thresh(glitch_thresh), - .refcnt_width(refcnt_width), .freq_width(freq_width), .initv(initv) ) work ( .sysclk(sysclk), .f_in(f_in), .g_in(1'b1), // this is the whole point! - .frequency(frequency), .freq_strobe(freq_strobe), - .diff_stream(diff_stream), .diff_stream_strobe(diff_stream_strobe), - .glitch_catcher(glitch_catcher) + .ref_strobe(ref_strobe), + .frequency(frequency_w), .freq_strobe(freq_strobe), + .xcount(xcount) ); +// Nobody except some ancient USB debugging ever used this. +// It's harmless; if you don't attach to the diff_stream, +// diff_stream_strobe, or glitch_catcher ports, it will all +// just disappear in synthesis. +// +// Make xcount available to stream to host at 24 MByte/sec, which was +// especially interesting when reprogramming a AD9512 clock divider +// on a LLRF4 board. +// It might also be possible to histogram xcount. +reg [15:0] stream=0; +always @(posedge sysclk) begin + if (xcount > glitch_thresh) glitch_catcher <= ~glitch_catcher; + stream <= {stream[11:0], xcount}; // assumes freq_gcount gw=4 +end + +// Latch/pipeline one more time to perimeter of this module +always @(posedge sysclk) begin + diff_stream <= stream; + diff_stream_strobe <= stream_strobe; + frequency <= frequency_w; +end + endmodule diff --git a/dsp/freq_count_tb.v b/dsp/freq_count_tb.v index 1830deb0f..3cf0fad99 100644 --- a/dsp/freq_count_tb.v +++ b/dsp/freq_count_tb.v @@ -16,7 +16,8 @@ initial begin end // Simulated accumulation interval is 20*64 = 1280 ns // Should catch an average of 1280/6 = 213.33 f_in edges in that time - if (frequency>212 && frequency < 215) begin + $display("frequency = %d", frequency); + if (frequency > 212 && frequency < 215) begin $display("PASS"); $finish(0); end else begin diff --git a/dsp/freq_gcount.v b/dsp/freq_gcount.v index cf9b1b29c..183130d9e 100644 --- a/dsp/freq_gcount.v +++ b/dsp/freq_gcount.v @@ -1,40 +1,39 @@ // Copied from the old freq_count, but with new g_in (gate) input added // Read the new name as frequency (gated) count. +// +// This version delegates reference counter function to the caller, +// to allow synchronization and resource-sharing across multiple +// freq_gcount instances. Note that if you want a _lot_ of frequency +// counter instances, maybe you should look into multi_counter.v. +// +// It no longer includes the obscure glitch diagnostics. Those are +// still available in freq_count, just in case anyone wants them. `timescale 1ns / 1ns module freq_gcount #( - // Default configuration useful for input frequencies < 96 MHz - parameter glitch_thresh=2, - parameter refcnt_width=24, + parameter gw=4, // Gray code counter width parameter freq_width=28, - parameter initv=0 + parameter initv=0 // output value for frequency at start-up ) ( // input clocks input sysclk, // timespec 8.0 ns input f_in, // unknown input - input g_in, // gate (f_in clock domain) + + // control input in f_in domain + input g_in, // gate (wire to 1 to get a simple frequency counter) + + // control input in sysclk domain + input ref_strobe, // typically one pulse every 2^24 sysclk cycles // outputs in sysclk domain - output reg [freq_width-1:0] frequency, + output [freq_width-1:0] frequency, output freq_strobe, - output reg [15:0] diff_stream, - output reg diff_stream_strobe, - // glitch_catcher can be routed to a physical pin to trigger - // a 'scope; see glitch_thresh parameter above - output reg glitch_catcher + output [gw-1:0] xcount // cycle-by-cycle gated count of f_in ); -initial begin - frequency=initv; - diff_stream=0; - diff_stream_strobe=0; - glitch_catcher=0; -end - -// four-bit Gray code counter on the input signal +// four-bit (nominal) Gray code counter on the input signal // https://en.wikipedia.org/wiki/Gray_code -localparam gw=4; reg [gw-1:0] gray1=0; // The following three expressions compute the next Gray code based on @@ -57,7 +56,7 @@ end // verilator lint_save // verilator lint_off UNOPTFLAT -wire [gw-1:0] bin3 = gray3 ^ {1'b0, bin3[gw-1:1]}; // convert Gray to binary +wire [gw-1:0] bin3 = gray3 ^ {1'b0, bin3[gw-1:1]}; // Gray to binary // verilator lint_restore reg [gw-1:0] bin4=0, bin5=0, diff1=0; @@ -65,37 +64,19 @@ always @(posedge sysclk) begin bin4 <= bin3; bin5 <= bin4; diff1 <= bin4-bin5; - if (diff1 > glitch_thresh) glitch_catcher <= ~glitch_catcher; end -// It might also be possible to histogram diff1, -// but for now just accumulate it to get a traditional frequency counter. -// Also make it available to stream to host at 24 MByte/sec, might be -// especially interesting when reprogramming a clock divider like -// the AD9512 on a LLRF4 board. -// In that case a 48 MHz sysclk / 2^24 = 2.861 Hz update +// Accumulate diff1 to get a traditional frequency counter reg [freq_width-1:0] accum=0, result=initv; -reg [refcnt_width-1:0] refcnt=0; -reg ref_carry=0; -reg [15:0] stream=0; -reg stream_strobe=0; -always @(posedge sysclk) begin - {ref_carry, refcnt} <= refcnt + 1; - if (ref_carry) result <= accum; - accum <= (ref_carry ? 28'b0 : accum) + diff1; - stream <= {stream[11:0],diff1}; - stream_strobe <= refcnt[1:0] == 0; -end - -// Latch/pipeline one more time to perimeter of this module -// to make routing easier reg freq_strobe_r=0; always @(posedge sysclk) begin - frequency <= result; - freq_strobe_r <= ref_carry; - diff_stream <= stream; - diff_stream_strobe <= stream_strobe; + accum <= (ref_strobe ? {freq_width{1'b0}} : accum) + diff1; + if (ref_strobe) result <= accum; + freq_strobe_r <= ref_strobe; // high when new data is valid end + +assign frequency = result; // Don't over-register assign freq_strobe = freq_strobe_r; +assign xcount = diff1; endmodule From 796650afa1619d8b8730ffd35237db92de1b9fd2 Mon Sep 17 00:00:00 2001 From: Keith Penney Date: Wed, 4 Dec 2024 23:46:57 -0800 Subject: [PATCH 71/75] Resolving copied code between rot_dds.v and ph_acc.v --- dsp/ph_acc.v | 37 +++++++++++++++++++++++++++++++++++ dsp/rot_dds.v | 53 +++++++++------------------------------------------ dsp/rules.mk | 2 +- 3 files changed, 47 insertions(+), 45 deletions(-) diff --git a/dsp/ph_acc.v b/dsp/ph_acc.v index a696666b6..7d1172816 100644 --- a/dsp/ph_acc.v +++ b/dsp/ph_acc.v @@ -4,6 +4,43 @@ // Tuned to allow 32-bit control, divided 20-bit high and 12-bit low, // which gets merged to 32-bit binary when modulo is zero. // But also supports non-binary frequencies: see the modulo input port. + +// Note that phase_step_h and phase_step_l combined fit in a 32-bit word. +// This is intentional, to allow atomic updates of the two controls +// in 32-bit systems. Indeed, when modulo==0, those 32 bits can be considered +// a single phase step increment + +// The phase generation algorithm +// 0. The phase increments for dds are generated using a technique described +// in these 2 places: +// Section: PROGRAMMABLE MODULUS MODE in: +// https://www.analog.com/media/en/technical-documentation/data-sheets/ad9915.pdf +// (AND) https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm +// Basically, increment the phase step at a coarse resolution, accumulate the +// error on the side, and when that error accumulates to the lowest bit of +// the coarse counter, add an extra 1 to the following phase step. +// 1. phase_step_h is the coarse (20 bit) integer truncated phase increment for +// the cordic. There is a 1-bit increment of phase that comes from +// accumulating residue phase. +// 2. This residue phase is accumulating in steps of phase_step_l, in a 12-bit +// counter. +// 3. However, there will be an extra residue even for this 12-bit counter, +// which is the modulus, and this added as an offset when the counter crosses 0 + +// 12-bit modulo supports largest known periodicity in a suggested LLRF system, +// 1427 for JLab. For more normal periodicities, use a multiple to get finer +// granularity. +// Note that the downloaded modulo control is the 2's complement of the +// mathematical modulus. +// e.g., SSRF IF/F_s ratio 8/11, use +// modulo = 4096 - 372*11 = 4 +// phase_step_h = 2^20*8/11 = 762600 +// phase_step_l = (2^20*8%11)*372 = 2976 +// e.g., Argonne RIA test IF/F_s ratio 9/13, use +// modulo = 4096 - 315*13 = 1 +// phase_step_h = 2^20*9/13 = 725937 +// phase_step_l = (2^20*9%13)*315 = 945 + module ph_acc( input clk, // Rising edge clock input; all logic is synchronous in this domain input reset, // Active high, synchronous with clk diff --git a/dsp/rot_dds.v b/dsp/rot_dds.v index 9ab9e12b0..613fd3713 100644 --- a/dsp/rot_dds.v +++ b/dsp/rot_dds.v @@ -10,40 +10,6 @@ // 8/11 for SSRF // 9/13 for Argonne RIA // -// The phase generation algorithm -// 0. The phase increments for dds are generated using a technique described -// in these 2 places: -// Section: PROGRAMMABLE MODULUS MODE in: -// https://www.analog.com/media/en/technical-documentation/data-sheets/ad9915.pdf -// (AND) https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm -// Basically, increment the phase step at a coarse resolution, accumulate the -// error on the side, and when that error accumulates to the lowest bit of -// the coarse counter, add an extra 1 to the following phase step. -// 1. phase_step_h is the coarse (20 bit) integer truncated phase increment for -// the cordic. There is a 1-bit increment of phase that comes from -// accumulating residue phase. -// 2. This residue phase is accumulating in steps of phase_step_l, in a 12-bit -// counter. -// 3. However, there will be an extra residue even for this 12-bit counter, -// which is the modulus, and this added as an offset when the counter crosses 0 - -// 12-bit modulo supports largest known periodicity in a suggested LLRF system, -// 1427 for JLab. For more normal periodicities, use a multiple to get finer -// granularity. -// Note that the downloaded modulo control is the 2's complement of the -// mathematical modulus. -// e.g., SSRF IF/F_s ratio 8/11, use -// modulo = 4096 - 372*11 = 4 -// phase_step_h = 2^20*8/11 = 762600 -// phase_step_l = (2^20*8%11)*372 = 2976 -// e.g., Argonne RIA test IF/F_s ratio 9/13, use -// modulo = 4096 - 315*13 = 1 -// phase_step_h = 2^20*9/13 = 725937 -// phase_step_l = (2^20*9%13)*315 = 945 - -// TODO: -// Potentially, isolate phase generation into a separate module. -// Haha, turns out there is ph_acc.v (We should USE it). // Synthesizes to ??? slices at ??? MHz in XC3Sxxx-4 using XST-?? // @@ -65,19 +31,18 @@ parameter lo_amp = 18'd79590; // Sometimes we cheat and use slightly smaller values than above, // to make other computations fit better. +wire [18:0] phase_acc; +ph_acc ph_acc_i ( + .clk(clk), .reset(reset), .en(1'b1), // input + .phase_acc(phase_acc), // output [18:0] + .phase_step_h(phase_step_h), // input [19:0] + .phase_step_l(phase_step_l), // input [11:0] + .modulo(modulo) // input [11:0] +); // See rot_dds_config -reg carry=0, reset_d=0; -reg [19:0] phase_h=0, phase_step_hp=0; -reg [11:0] phase_l=0; -always @(posedge clk) begin - {carry, phase_l} <= reset ? 13'b0 : ((carry ? modulo : 12'b0) + phase_l + phase_step_l); - phase_step_hp <= phase_step_h; - reset_d <= reset; - phase_h <= reset_d ? 20'b0 : (phase_h + phase_step_hp + carry); -end cordicg_b22 #(.nstg(20), .width(18), .def_op(0)) trig(.clk(clk), .opin(2'b00), - .xin(lo_amp), .yin(18'd0), .phasein(phase_h[19:1]), + .xin(lo_amp), .yin(18'd0), .phasein(phase_acc), // 2^17/1.64676 = 79594, use a smaller value to keep CORDIC round-off // from overflowing the output .xout(cosa), .yout(sina)); diff --git a/dsp/rules.mk b/dsp/rules.mk index 3bd71f498..ae8631912 100644 --- a/dsp/rules.mk +++ b/dsp/rules.mk @@ -30,7 +30,7 @@ bits: $(BITS_) $(VVP) $< +trace $(PYTHON) $(word 2, $^) -f $* -rot_dds_tb: cordicg_b22.v +rot_dds_tb: cordicg_b22.v ph_acc.v mon_12_tb: cordicg_b22.v From f4977bf1d32532fac96ecf237821e6b2d236b584 Mon Sep 17 00:00:00 2001 From: Keith Penney Date: Fri, 6 Dec 2024 11:27:54 -0800 Subject: [PATCH 72/75] Adding comments to ports and explicit values to avoid assumed defaults --- dsp/freq_count.v | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dsp/freq_count.v b/dsp/freq_count.v index 8f95b8b76..919bb3c32 100644 --- a/dsp/freq_count.v +++ b/dsp/freq_count.v @@ -17,8 +17,8 @@ module freq_count #( // outputs in sysclk domain output reg [freq_width-1:0] frequency, output freq_strobe, - output reg [15:0] diff_stream, - output reg diff_stream_strobe, + output reg [15:0] diff_stream, // stream of last 4 4-bit counts of f_in + output reg diff_stream_strobe, // strobe at f_sysclk/4 // glitch_catcher can be routed to a physical pin to trigger // a 'scope; see glitch_thresh parameter above output reg glitch_catcher @@ -43,6 +43,7 @@ end wire [3:0] xcount; // per-sysclk count of f_in edges wire [freq_width-1:0] frequency_w; freq_gcount #( + .gw(4), .freq_width(freq_width), .initv(initv) ) work ( From ce378c6dd55835e29b36fa9285e13d7923dfef35 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Wed, 11 Dec 2024 18:08:46 -0800 Subject: [PATCH 73/75] Improve swap_gitid.tcl --- build-tools/vivado_tcl/swap_gitid.tcl | 69 ++++++++++++++++----------- 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/build-tools/vivado_tcl/swap_gitid.tcl b/build-tools/vivado_tcl/swap_gitid.tcl index dd7609b77..48a2ffa76 100644 --- a/build-tools/vivado_tcl/swap_gitid.tcl +++ b/build-tools/vivado_tcl/swap_gitid.tcl @@ -180,16 +180,16 @@ proc check_impl {} { proc check_bmem {pattern width} { set c [get_cells -hier -filter {PRIMITIVE_TYPE =~ BMEM.*.*} $pattern] - if {[llength $c] != 1} { - puts "ERROR: Unexpected number of $pattern!" - return 0 - } - set n [get_property READ_WIDTH_A $c] - if {$n != $width} { - puts "ERROR: Read Width of $pattern must be $width (not $n)!" - return 0 + set xc {} + foreach cc $c { + set n [get_property READ_WIDTH_A $cc] + if {$n == $width} { + lappend xc $cc + } else { + puts "Ignoring instance $cc where Read Width is $width (not $n)" + } } - return $c + return $xc } proc swap_gitid {old_commit new_commit rowwidth dry_run} { @@ -200,7 +200,16 @@ proc swap_gitid {old_commit new_commit rowwidth dry_run} { 8 { set c0 [check_bmem "*dxx_reg_0" 9] set c1 [check_bmem "*dxx_reg_1" 9] - if {$c0 == 0 || $c1 == 0} {return 0} + if {$c0 == {} && $c1 == {}} { + puts "no relevant 8Kx8 BRAM found" + return 0 + } + set lc0 [length $c0] + set lc1 [length $c1] + if {$lc0 != 1 || $lc1 != 1} { + puts "ERROR: swap_gitid can't handle case $rowwidth $lc0 $lc1 yet!" + return 0 + } set init0 [get_property INIT_00 $c0] set init1 [get_property INIT_00 $c1] set xx [gitid_proc $old_commit $new_commit $init0 $init1 $rowwidth] @@ -216,17 +225,23 @@ proc swap_gitid {old_commit new_commit rowwidth dry_run} { 16 { set c0 [check_bmem "*dxx_reg" 18] - if {$c0 == 0} {return 0} - set init0 [get_property INIT_00 $c0] - set init1 [get_property INIT_01 $c0] - set xx [gitid_proc $old_commit $new_commit $init0 $init1 $rowwidth] - if {[llength $xx] != 2} {return 0} - lassign $xx init0x init1x - if {$dry_run != 1} { - set_property INIT_00 $init0x $c0 - set_property INIT_01 $init1x $c0 - } else { - puts "Dry run only" + if {$c0 == {}} { + puts "no relevant 4Kx16 BRAM found" + return 0 + } + foreach cc $c0 { + puts "trying $cc" + set init0 [get_property INIT_00 $cc] + set init1 [get_property INIT_01 $cc] + set xx [gitid_proc $old_commit $new_commit $init0 $init1 $rowwidth] + if {[llength $xx] != 2} {return 0} + lassign $xx init0x init1x + if {$dry_run != 1} { + set_property INIT_00 $init0x $cc + set_property INIT_01 $init1x $cc + } else { + puts "Dry run only" + } } } @@ -282,18 +297,19 @@ proc is_git_dirty {gitid} { } } -# Generate 40 digits git commit id where the latest 16 digits -# are zeros in case of local modification +# Generate 40-hex-digit git commit id, where the last 16 digits +# are zeros in case of local modification. +# This result is normally headed for swap_gitid. proc generate_extended_git_id {git_id dirtiness} { if {[string length $git_id] < 40} { error "generate_extended_git_id error: [ ]received a git id shorter than 40 digits!" } + set rr $git_id if {$dirtiness} { - return [string range $git_id 0 23]0000000000000000 - } else { - return $git_id + set rr [string range $git_id 0 23]0000000000000000 } + return [string toupper $rr] } # Print git hash in huge and colored way @@ -310,7 +326,6 @@ proc get_git_context {} { # single-source-of-truth array set git_status [get_full_git_id] # everything else derived from that - set git_id [string range $git_status(id) 0 39] set git_id_short [string range $git_status(id) 0 7] set git_dirty [is_git_dirty $git_status(id)] set dirty_suffix "" From 3111a331fe8748aa10d9636ce8b586703c60c532 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Thu, 12 Dec 2024 09:14:20 -0800 Subject: [PATCH 74/75] swap_gitid.tcl: fix typo --- build-tools/vivado_tcl/swap_gitid.tcl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build-tools/vivado_tcl/swap_gitid.tcl b/build-tools/vivado_tcl/swap_gitid.tcl index 48a2ffa76..8595fb147 100644 --- a/build-tools/vivado_tcl/swap_gitid.tcl +++ b/build-tools/vivado_tcl/swap_gitid.tcl @@ -204,8 +204,8 @@ proc swap_gitid {old_commit new_commit rowwidth dry_run} { puts "no relevant 8Kx8 BRAM found" return 0 } - set lc0 [length $c0] - set lc1 [length $c1] + set lc0 [llength $c0] + set lc1 [llength $c1] if {$lc0 != 1 || $lc1 != 1} { puts "ERROR: swap_gitid can't handle case $rowwidth $lc0 $lc1 yet!" return 0 From 90903de30faccb80633c5d1be46f72b48a5eb653 Mon Sep 17 00:00:00 2001 From: Larry Doolittle Date: Fri, 20 Dec 2024 14:28:17 -0800 Subject: [PATCH 75/75] lp_notch_test.py: minor numpy usage cleanup Avoids DeprecationWarning: Conversion of an array with ndim > 0 to a scalar starting with NumPy 1.25 --- dsp/hosted/lp_notch_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/hosted/lp_notch_test.py b/dsp/hosted/lp_notch_test.py index 11094f076..64fbe18e4 100644 --- a/dsp/hosted/lp_notch_test.py +++ b/dsp/hosted/lp_notch_test.py @@ -97,7 +97,7 @@ def __init__( Abp_zn = cl0_bp.response(zn) # solve for the final gains mat = numpy.array([[Alp_dc, Abp_dc], [Alp_zn, Abp_zn]]) - target_gains = numpy.array([[self.gain], [self.ngain]]) + target_gains = numpy.array([self.gain, self.ngain]) raw_gains = numpy.linalg.inv(mat).dot(target_gains) # prevent the low-pass component from clipping if abs(raw_gains[0]) > 0.99: