bug fixing
This commit is contained in:
parent
e8433414f0
commit
90f5cfe84f
|
@ -21,6 +21,7 @@
|
|||
|
||||
/*
|
||||
This C design corresponds to the following Verilog:
|
||||
TODO
|
||||
*/
|
||||
|
||||
int main(int argc, char** argv)
|
||||
|
|
101
jtag_counter.c
101
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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue
Block a user