diff --git a/j1_blinking.c b/j1_blinking.c index 5a4f363..b9407e6 100644 --- a/j1_blinking.c +++ b/j1_blinking.c @@ -21,6 +21,7 @@ /* This C design corresponds to the following Verilog: +TODO */ int main(int argc, char** argv) diff --git a/jtag_counter.c b/jtag_counter.c index 3ff9807..012da84 100644 --- a/jtag_counter.c +++ b/jtag_counter.c @@ -12,106 +12,7 @@ /* This C design corresponds to the following Verilog: - -// There are 5 registers -// 0x0 R Firmware version -// 0x1 RW Counter enable/disable, enable: 1, disable: 0 -// 0x2 RW Counter write enable, enable: 1, disable: 0 -// 0x3 RW Counter write Value -// 0x4 R Counter current value - -// LED1, on: stop counting, off: counting -// LED2, on: counter > 0, off: counter == 0 - -module counter(clk, led1, led2); - input clk; - output led1; - output led2; - - // synthesis attribute LOC clk "T8 | IOSTANDARD = LVCMOS33" - // synthesis attribute LOC led "R5 | SLEW = QUIETIO | DRIVE = 8" - - reg counter_start = 1'b0; - reg counter_we = 1'b0; - reg [31:0] counter = 32'd0; - reg [31:0] counter_set = 32'd0; - always @(posedge clk) - begin - if (counter_start == 1'b1) - counter <= counter + 1; - if (counter_we == 1'b1) - counter <= counter_set; - end - - assign led1 = ~counter_start; - assign led2 = counter; - - wire jt_capture, jt_drck, jt_reset, jt_sel; - wire jt_shift, jt_tck, jt_tdi, jt_update, jt_tdo; - - BSCAN_SPARTAN6 # (.JTAG_CHAIN(1)) jtag_blk ( - .CAPTURE(jt_capture), - .DRCK(jt_drck), - .RESET(jt_reset), - .RUNTEST(), - .SEL(jt_sel), - .SHIFT(jt_shift), - .TCK(jt_tck), - .TDI(jt_tdi), - .TDO(jt_tdo), - .TMS(), - .UPDATE(jt_update) - ); - - reg [37:0] dr; - reg [3:0] addr = 4'hF; - reg checksum; - wire checksum_valid = ~checksum; - wire jtag_we = dr[36]; - wire [3:0] jtag_addr = dr[35:32]; - - assign jt_tdo = dr[0]; - - always @ (posedge jt_tck) - begin - if (jt_reset == 1'b1) - begin - dr <= 38'd0; - end - else if (jt_capture == 1'b1) - begin - checksum <= 1'b1; - dr[37:32] <= 6'd0; - addr <= 4'hF; - case (addr) - 4'h0: dr[31:0] <= 32'h20120911; - 4'h1: dr[0] <= counter_start; - 4'h2: dr[0] <= counter_we; - 4'h3: dr[31:0] <= counter_set; - 4'h4: dr[31:0] <= counter; - - default: dr[31:0] <= 32'habcdef01; - endcase - end - else if (jt_shift == 1'b1) - begin - dr <= {jt_tdi, dr[37:1]}; - checksum <= checksum ^ jt_tdi; - end - else if (jt_update & checksum_valid) - begin - addr <= jtag_addr; - if (jtag_we) - begin - case (jtag_addr) - 4'h1: counter_start <= dr[0]; - 4'h2: counter_we <= dr[0]; - 4'h3: counter_set <= dr[31:0]; - endcase - end - end - end -endmodule +TODO */ int main(int argc, char** argv) diff --git a/libs/bit_frames.c b/libs/bit_frames.c index 45f0616..216bdeb 100644 --- a/libs/bit_frames.c +++ b/libs/bit_frames.c @@ -10,6 +10,8 @@ #include "control.h" #undef DBG_EXTRACT_T2 +#undef DBG_EXTRACT_LOGIC_SW +#undef DBG_EXTRACT_ROUTING_SW static uint8_t* get_first_minor(struct fpga_bits* bits, int row, int major) { @@ -80,7 +82,9 @@ struct sw_yxpos swidx_t idx; }; -#define MAX_YX_SWITCHES 1024 +// random value of about 10kk switches for now, meaning +// about 100MB memory usage +#define MAX_YX_SWITCHES 10*1024*1024 struct extract_state { @@ -89,7 +93,7 @@ struct extract_state // yx switches are fully extracted ones pointing into the // model, stored here for later processing into nets. int num_yx_pos; - struct sw_yxpos yx_pos[MAX_YX_SWITCHES]; // needs to be dynamically alloced... + struct sw_yxpos *yx_pos; }; static int find_es_switch(struct extract_state* es, int y, int x, swidx_t sw) @@ -675,6 +679,26 @@ fail: return rc; } +static int back_to_cout(struct fpga_model *model, int cin_y, int cin_x, + str16_t cin_str, int *cout_y, int *cout_x, str16_t *cout_str) +{ + int connpt_dests_o, num_dests, i; + + RC_CHECK(model); + if (fpga_connpt_find(model, cin_y, cin_x, cin_str, + &connpt_dests_o, &num_dests) == NO_CONN) + RC_FAIL(model, EINVAL); + RC_ASSERT(model, num_dests == 1 || num_dests == 2); + for (i = 0; i < num_dests; i++) { + fpga_conn_dest(model, cin_y, cin_x, connpt_dests_o+i, cout_y, cout_x, cout_str); + if (has_device(model, *cout_y, *cout_x, DEV_LOGIC)) + break; + } + if (i >= num_dests) + RC_FAIL(model, EINVAL); + RC_RETURN(model); +} + static int extract_logic(struct extract_state* es) { int row, row_pos, x, y, i, byte_off, last_minor, lut5_used, rc; @@ -1389,21 +1413,16 @@ static int extract_logic(struct extract_state* es) && (cfg_ml.a2d[LUT_A].out_mux == MUX_XOR || cfg_ml.a2d[LUT_A].ff_mux == MUX_XOR || cfg_ml.a2d[LUT_A].cy0)) { - int connpt_dests_o, num_dests, cout_y, cout_x; + + int cout_y, cout_x; str16_t cout_str; - if ((fpga_connpt_find(es->model, y, x, - dev_ml->pinw[LI_CIN], &connpt_dests_o, - &num_dests) == NO_CONN) - || num_dests != 1) { - HERE(); - } else { - fpga_conn_dest(es->model, y, x, connpt_dests_o, - &cout_y, &cout_x, &cout_str); - if (find_es_switch(es, cout_y, cout_x,fpga_switch_first( - es->model, cout_y, cout_x, cout_str, SW_TO))) - cfg_ml.precyinit = PRECYINIT_0; - } + rc = back_to_cout(es->model, y, x, dev_ml->pinw[LI_CIN], + &cout_y, &cout_x, &cout_str); + if (rc) FAIL(rc); + if (find_es_switch(es, cout_y, cout_x,fpga_switch_first( + es->model, cout_y, cout_x, cout_str, SW_TO))) + cfg_ml.precyinit = PRECYINIT_0; } // @@ -1561,6 +1580,7 @@ static int extract_routing_switches(struct extract_state* es, int y, int x) { struct fpga_tile* tile; swidx_t sw_idx; + str16_t from_str, to_str; int i, is_set, rc; RC_CHECK(es->model); @@ -1571,16 +1591,26 @@ static int extract_routing_switches(struct extract_state* es, int y, int x) if (rc) RC_FAIL(es->model, rc); if (!is_set) continue; - sw_idx = fpga_switch_lookup(es->model, y, x, - fpga_wire2str_i(es->model, es->model->sw_bitpos[i].from), - fpga_wire2str_i(es->model, es->model->sw_bitpos[i].to)); + from_str = fpga_wire2str_yx(es->model, es->model->sw_bitpos[i].from, y, x); + to_str = fpga_wire2str_yx(es->model, es->model->sw_bitpos[i].to, y, x); +#ifdef DBG_EXTRACT_ROUTING_SW + fprintf(stderr, "#D %s:%i y%i x%i from %i (%s) to %i (%s)\n", + __FILE__, __LINE__, y, x, + es->model->sw_bitpos[i].from, + strarray_lookup(&es->model->str, from_str), + es->model->sw_bitpos[i].to, + strarray_lookup(&es->model->str, to_str)); +#endif + sw_idx = fpga_switch_lookup(es->model, y, x, from_str, to_str); if (sw_idx == NO_SWITCH) RC_FAIL(es->model, EINVAL); // todo: es->model->sw_bitpos[i].bidir handling if (tile->switches[sw_idx] & SWITCH_BIDIRECTIONAL) - HERE(); + fprintf(stderr, "#E %s:%i BIDIR not supported yet\n", + __FILE__, __LINE__); if (tile->switches[sw_idx] & SWITCH_USED) - HERE(); + fprintf(stderr, "#E %s:%i switch already in use\n", + __FILE__, __LINE__); if (es->num_yx_pos >= MAX_YX_SWITCHES) { RC_FAIL(es->model, ENOTSUP); } es->yx_pos[es->num_yx_pos].y = y; @@ -1616,36 +1646,37 @@ static int extract_logic_switches(struct extract_state* es, int y, int x) if (frame_get_bit(u8_p + minor*FRAME_SIZE, byte_off*8 + XC6_ML_CIN_USED)) { struct fpga_device* dev; - int connpt_dests_o, num_dests, cout_y, cout_x; + int cout_y, cout_x; str16_t cout_str; swidx_t cout_sw; dev = fdev_p(es->model, y, x, DEV_LOGIC, DEV_LOG_M_OR_L); if (!dev) FAIL(EINVAL); - if ((fpga_connpt_find(es->model, y, x, - dev->pinw[LI_CIN], &connpt_dests_o, - &num_dests) == NO_CONN) - || num_dests != 1) { - HERE(); - } else { - fpga_conn_dest(es->model, y, x, connpt_dests_o, - &cout_y, &cout_x, &cout_str); - cout_sw = fpga_switch_first(es->model, cout_y, - cout_x, cout_str, SW_TO); - if (cout_sw == NO_SWITCH) HERE(); - else { - if (es->num_yx_pos >= MAX_YX_SWITCHES) - { FAIL(ENOTSUP); } - es->yx_pos[es->num_yx_pos].y = cout_y; - es->yx_pos[es->num_yx_pos].x = cout_x; - es->yx_pos[es->num_yx_pos].idx = cout_sw; - es->num_yx_pos++; + rc = back_to_cout(es->model, y, x, dev->pinw[LI_CIN], + &cout_y, &cout_x, &cout_str); + if (rc) FAIL(rc); +#ifdef DBG_EXTRACT_LOGIC_SW + fprintf(stderr, "#D %s:%i cin y%i x%i %s cout y%i x%i %s\n", + __FILE__, __LINE__, + y, x, strarray_lookup(&es->model->str, dev->pinw[LI_CIN]), + cout_y, cout_x, strarray_lookup(&es->model->str, cout_str)); +#endif - frame_clear_bit(u8_p + minor*FRAME_SIZE, - byte_off*8 + XC6_ML_CIN_USED); - } - } + cout_sw = fpga_switch_first(es->model, cout_y, + cout_x, cout_str, SW_TO); + if (cout_sw == NO_SWITCH) + FAIL(EINVAL); + + if (es->num_yx_pos >= MAX_YX_SWITCHES) + { FAIL(ENOTSUP); } + es->yx_pos[es->num_yx_pos].y = cout_y; + es->yx_pos[es->num_yx_pos].x = cout_x; + es->yx_pos[es->num_yx_pos].idx = cout_sw; + es->num_yx_pos++; + + frame_clear_bit(u8_p + minor*FRAME_SIZE, + byte_off*8 + XC6_ML_CIN_USED); } return 0; fail: @@ -2205,9 +2236,17 @@ static int construct_extract_state(struct extract_state* es, RC_CHECK(model); memset(es, 0, sizeof(*es)); es->model = model; + es->yx_pos = malloc(MAX_YX_SWITCHES * sizeof(*es->yx_pos)); + if (!es->yx_pos) { HERE(); return ENOMEM; } return 0; } +static void destruct_extract_state(struct extract_state *es) +{ + free(es->yx_pos); + es->yx_pos = 0; +} + int extract_model(struct fpga_model* model, struct fpga_bits* bits) { struct extract_state es; @@ -2219,28 +2258,32 @@ int extract_model(struct fpga_model* model, struct fpga_bits* bits) if (rc) RC_FAIL(model, rc); es.bits = bits; for (i = 0; i < sizeof(s_default_bits)/sizeof(s_default_bits[0]); i++) { - if (!get_bitp(bits, &s_default_bits[i])) - RC_FAIL(model, EINVAL); + if (!get_bitp(bits, &s_default_bits[i])) { + RC_SET(model, EINVAL); + goto out; + } clear_bitp(bits, &s_default_bits[i]); } rc = extract_switches(&es); - if (rc) RC_FAIL(model, rc); + if (rc) { RC_SET(model, rc); goto out; } rc = extract_type2(&es); - if (rc) RC_FAIL(model, rc); + if (rc) { RC_SET(model, rc); goto out; } rc = extract_logic(&es); - if (rc) RC_FAIL(model, rc); + if (rc) { RC_SET(model, rc); goto out; } // turn switches into nets if (model->nets) HERE(); // should be empty here for (i = 0; i < es.num_yx_pos; i++) { rc = fnet_new(model, &net_idx); - if (rc) RC_FAIL(model, rc); + if (rc) { RC_SET(model, rc); goto out; } rc = fnet_add_sw(model, net_idx, es.yx_pos[i].y, es.yx_pos[i].x, &es.yx_pos[i].idx, 1); - if (rc) RC_FAIL(model, rc); + if (rc) { RC_SET(model, rc); goto out; } } +out: + destruct_extract_state(&es); RC_RETURN(model); } diff --git a/libs/bit_regs.c b/libs/bit_regs.c index e9d8859..3fa4c7c 100644 --- a/libs/bit_regs.c +++ b/libs/bit_regs.c @@ -1010,7 +1010,7 @@ static int dump_maj_macc(const uint8_t* bits, int row, int major) static int dump_bits(struct fpga_config* cfg) { int idcode, num_rows, row, major, off, rc; - struct xc_die* die_info; + const struct xc_die* die_info; if (cfg->idcode_reg == -1) FAIL(EINVAL); idcode = cfg->reg[cfg->idcode_reg].int_v; diff --git a/libs/control.c b/libs/control.c index 9c458e5..6be8d1c 100644 --- a/libs/control.c +++ b/libs/control.c @@ -1000,8 +1000,12 @@ int fpga_connpt_find(struct fpga_model* model, int y, int x, if (tile->conn_point_names[i*2+1] == name_i) break; } - if (i >= tile->num_conn_point_names) - { HERE(); goto fail; } + if (i >= tile->num_conn_point_names) { + fprintf(stderr, "#E %s:%i cannot find y%i x%i connpt %s\n", + __FILE__, __LINE__, y, x, + strarray_lookup(&model->str, name_i)); + goto fail; + } if (num_dests) { *num_dests = (i < tile->num_conn_point_names-1) ? tile->conn_point_names[(i+1)*2] diff --git a/libs/helper.h b/libs/helper.h index 384b7fc..b125538 100644 --- a/libs/helper.h +++ b/libs/helper.h @@ -30,6 +30,7 @@ #define RC_CHECK(model) do { if ((model)->rc) RC_RETURN(model); } while (0) #define RC_ASSERT(model, what) do { RC_CHECK(model); if (!(what)) RC_FAIL(model, EINVAL); } while (0) +#define RC_SET(model, code) do { HERE(); if (!(model)->rc) (model)->rc = (code); } while (0) #define RC_FAIL(model, code) do { HERE(); if (!(model)->rc) (model)->rc = (code); RC_RETURN(model); } while (0) #define RC_RETURN(model) return (model)->rc diff --git a/libs/model.h b/libs/model.h index 2a0c4c0..f7353ed 100644 --- a/libs/model.h +++ b/libs/model.h @@ -133,6 +133,7 @@ enum fpga_tile_type #define HALF_ROW 8 #define HCLK_POS 8 // hclk pos in row #define LAST_POS_IN_ROW 16 // including hclk at 8 +#define LAST_REGULAR_ROW_POS 15 // without hclk #define ROW_SIZE (HALF_ROW+1+HALF_ROW) #define CENTER_X_PLUS_1 1 // routing col adjacent to center @@ -1056,6 +1057,8 @@ enum extra_wires { const char *fpga_connpt_str(struct fpga_model *model, enum extra_wires wire, int y, int x, int dest_y, int dest_x); +str16_t fpga_wire2str_yx(struct fpga_model *model, enum extra_wires wire, + int y, int x); const char* fpga_wire2str(enum extra_wires wire); str16_t fpga_wire2str_i(struct fpga_model* model, enum extra_wires wire); enum extra_wires fpga_str2wire(const char* str); diff --git a/libs/model_helper.c b/libs/model_helper.c index 596984a..caa8776 100644 --- a/libs/model_helper.c +++ b/libs/model_helper.c @@ -1580,11 +1580,38 @@ const char *fpga_connpt_str(struct fpga_model *model, enum extra_wires wire, "REGR_%s", fpga_wire2str(wire)); else HERE(); } else HERE(); - } else HERE(); + } else { + fprintf(stderr, "#E %s:%i fpga_connpt_str() wire %i unsupported\n", __FILE__, __LINE__, wire); + sprintf(buf[last_buf], "UNSUP_%i", wire); + } return buf[last_buf]; } -const char* fpga_wire2str(enum extra_wires wire) +str16_t fpga_wire2str_yx(struct fpga_model *model, enum extra_wires wire, + int y, int x) +{ + char buf[MAX_WIRENAME_LEN]; + int str_i, row_num, row_pos; + + if (wire >= GCLK0 && wire <= GCLK15) { + is_in_row(model, y, &row_num, &row_pos); + if (row_pos != LAST_POS_IN_ROW + || (!row_num && !is_atx(X_FABRIC_BRAM_ROUTING_COL|X_FABRIC_MACC_ROUTING_COL, model, x)) + || (row_num == model->die->num_rows/2 && is_atx(X_LEFT_IO_ROUTING_COL|X_RIGHT_IO_ROUTING_COL, model, x))) + return fpga_wire2str_i(model, wire); + + snprintf(buf, sizeof(buf), "%s_BRK", fpga_wire2str(wire)); + } else + return fpga_wire2str_i(model, wire); + str_i = strarray_find(&model->str, buf); + if (OUT_OF_U16(str_i)) { + HERE(); + str_i = STRIDX_NO_ENTRY; + } + return str_i; +} + +const char *fpga_wire2str(enum extra_wires wire) { enum { NUM_BUFS = 8, BUF_SIZE = MAX_WIRENAME_LEN }; static char buf[NUM_BUFS][BUF_SIZE];