continued on blinking_led.c
This commit is contained in:
parent
6a0f623028
commit
cf4a88fbb3
19
README
19
README
|
@ -5,16 +5,13 @@ Introduction
|
||||||
block ram and multiply-accumulate devices.
|
block ram and multiply-accumulate devices.
|
||||||
The long-term goals of fpgatools are:
|
The long-term goals of fpgatools are:
|
||||||
|
|
||||||
*) reach the maximum physical performance of the chip
|
*) reach maximum physical chip performance
|
||||||
*) fast development cycles
|
*) fast development cycles
|
||||||
*) independent toolchain that only depends on other free software
|
*) independent toolchain that only depends on other free software
|
||||||
*) bootstrap on chip, i.e. program the fpga from a softcore running
|
*) reconfigure on-chip
|
||||||
on the same fpga
|
*) include get-started tools such as jtag, debugging, parts data
|
||||||
*) complete package including all tools to get started such as jtag,
|
and designs for prototyping hardware
|
||||||
debugging, parts data and designs for prototyping hardware
|
*) design flow that includes asic manufacturing
|
||||||
*) work towards a design flow that includes later manufacturing
|
|
||||||
in different ASIC processes, include information about ASIC
|
|
||||||
processes, libraries, GDS generation, etc.
|
|
||||||
*) lightweight C implementation without GUI
|
*) lightweight C implementation without GUI
|
||||||
*) supported platform: Linux
|
*) supported platform: Linux
|
||||||
*) license: public domain
|
*) license: public domain
|
||||||
|
@ -59,13 +56,9 @@ Design Principles
|
||||||
TODO
|
TODO
|
||||||
|
|
||||||
short-term (1 month):
|
short-term (1 month):
|
||||||
* add lut_encoding autotest for lut6 and lut5 in a-d position
|
|
||||||
of x(m), x(l), l and m devs
|
|
||||||
* more cases in logic_cfg test
|
|
||||||
* example: blinking_led
|
* example: blinking_led
|
||||||
* example: counter (including clock, jtag)
|
* example: counter (including clock, jtag)
|
||||||
* support reading iologic switches
|
* autotest: fix bugs in lut_encoding, logic_cfg, routing_sw, io_sw tests
|
||||||
* autotest: fix roundtrip issues in routing_sw test
|
|
||||||
* autotest: protect stderr of diff executable in autotest log
|
* autotest: protect stderr of diff executable in autotest log
|
||||||
* 3 Debian packages: libfpga, libfpga-doc, fpgatools
|
* 3 Debian packages: libfpga, libfpga-doc, fpgatools
|
||||||
|
|
||||||
|
|
16
autotest.c
16
autotest.c
|
@ -957,6 +957,22 @@ static int test_iob_config(struct test_state* tstate)
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}}
|
}}
|
||||||
|
// enum all iobs
|
||||||
|
{
|
||||||
|
const char* name;
|
||||||
|
for (i = 0; (name = fpga_enum_iob(tstate->model, i, &iob_y,
|
||||||
|
&iob_x, &iob_type_idx)); i++) {
|
||||||
|
if (tstate->dry_run)
|
||||||
|
printf("IOB %s y%02i x%02i i%i\n", name,
|
||||||
|
iob_y, iob_x, iob_type_idx);
|
||||||
|
rc = fdev_iob_IMUX(tstate->model, iob_y, iob_x,
|
||||||
|
iob_type_idx, IMUX_I);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
if ((rc = diff_printf(tstate))) FAIL(rc);
|
||||||
|
fdev_delete(tstate->model, iob_y, iob_x,
|
||||||
|
DEV_IOB, iob_type_idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -22,43 +22,73 @@
|
||||||
assign led = counter[14];
|
assign led = counter[14];
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
struct fpga_model model;
|
struct fpga_model model;
|
||||||
int iob_inA_y, iob_inA_x, iob_inA_type_idx;
|
int iob_clk_y, iob_clk_x, iob_clk_type_idx;
|
||||||
int iob_inB_y, iob_inB_x, iob_inB_type_idx;
|
int iob_led_y, iob_led_x, iob_led_type_idx;
|
||||||
int iob_out_y, iob_out_x, iob_out_type_idx;
|
|
||||||
int logic_y, logic_x, logic_type_idx;
|
int logic_y, logic_x, logic_type_idx;
|
||||||
|
struct fpgadev_logic logic_cfg;
|
||||||
net_idx_t inA_net, inB_net, out_net;
|
net_idx_t inA_net, inB_net, out_net;
|
||||||
int rc;
|
|
||||||
|
|
||||||
if ((rc = fpga_build_model(&model, XC6SLX9_ROWS, XC6SLX9_COLUMNS,
|
fpga_build_model(&model, XC6SLX9_ROWS, XC6SLX9_COLUMNS,
|
||||||
XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING))) FAIL(rc);
|
XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING);
|
||||||
|
|
||||||
if ((rc = fpga_find_iob(&model, "P45", &iob_inA_y, &iob_inA_x,
|
fpga_find_iob(&model, "P55", &iob_clk_y, &iob_clk_x, &iob_clk_type_idx);
|
||||||
&iob_inA_type_idx))) FAIL(rc);
|
fdev_iob_input(&model, iob_clk_y, iob_clk_x, iob_clk_type_idx,
|
||||||
if ((rc = fdev_iob_input(&model, iob_inA_y, iob_inA_x,
|
IO_LVCMOS33);
|
||||||
iob_inA_type_idx, IO_LVCMOS33))) FAIL(rc);
|
|
||||||
|
|
||||||
if ((rc = fpga_find_iob(&model, "P46", &iob_inB_y, &iob_inB_x,
|
fpga_find_iob(&model, "P48", &iob_led_y, &iob_led_x, &iob_led_type_idx);
|
||||||
&iob_inB_type_idx))) FAIL(rc);
|
fdev_iob_output(&model, iob_led_y, iob_led_x, iob_led_type_idx,
|
||||||
if ((rc = fdev_iob_input(&model, iob_inB_y, iob_inB_x,
|
IO_LVCMOS25);
|
||||||
iob_inB_type_idx, IO_LVCMOS33))) FAIL(rc);
|
fdev_iob_slew(&model, iob_led_y, iob_led_x, iob_led_type_idx,
|
||||||
|
SLEW_QUIETIO);
|
||||||
if ((rc = fpga_find_iob(&model, "P48", &iob_out_y, &iob_out_x,
|
fdev_iob_drive(&model, iob_led_y, iob_led_x, iob_led_type_idx,
|
||||||
&iob_out_type_idx))) FAIL(rc);
|
8);
|
||||||
if ((rc = fdev_iob_output(&model, iob_out_y, iob_out_x,
|
|
||||||
iob_out_type_idx, IO_LVCMOS33))) FAIL(rc);
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
logic_y = 68;
|
logic_y = 68;
|
||||||
logic_x = 13;
|
logic_x = 13;
|
||||||
logic_type_idx = DEV_LOG_X;
|
logic_type_idx = DEV_LOG_X;
|
||||||
if ((rc = fdev_logic_a2d_lut(&model, logic_y, logic_x, logic_type_idx,
|
if ((rc = fdev_logic_a2d_lut(&model, logic_y, logic_x, logic_type_idx,
|
||||||
LUT_D, 6, "A3*A5", ZTERM))) FAIL(rc);
|
LUT_D, 6, "A3*A5", ZTERM))) FAIL(rc);
|
||||||
|
|
||||||
|
memset(&logic_cfg, 0, sizeof(logic_cfg));
|
||||||
|
logic_cfg.a2d[LUT_A].lut6 = "(A6+~A6)*(~A5)";
|
||||||
|
logic_cfg.a2d[LUT_A].lut5 = "1";
|
||||||
|
logic_cfg.a2d[LUT_A].cy0 = CY0_O5;
|
||||||
|
logic_cfg.a2d[LUT_A].ff = FF_FF;
|
||||||
|
logic_cfg.a2d[LUT_A].ff_mux = MUX_XOR;
|
||||||
|
logic_cfg.a2d[LUT_A].ff_srinit = FF_SRINIT0;
|
||||||
|
logic_cfg.a2d[LUT_B].lut6 = "(A6+~A6)*(A5)";
|
||||||
|
logic_cfg.a2d[LUT_B].lut5 = "1";
|
||||||
|
logic_cfg.a2d[LUT_B].cy0 = CY0_O5;
|
||||||
|
logic_cfg.a2d[LUT_B].ff = FF_FF;
|
||||||
|
logic_cfg.a2d[LUT_B].ff_mux = MUX_XOR;
|
||||||
|
logic_cfg.a2d[LUT_B].ff_srinit = FF_SRINIT0;
|
||||||
|
logic_cfg.a2d[LUT_C].lut6 = "(A6+~A6)*(A5)";
|
||||||
|
logic_cfg.a2d[LUT_C].lut5 = "1";
|
||||||
|
logic_cfg.a2d[LUT_C].cy0 = CY0_O5;
|
||||||
|
logic_cfg.a2d[LUT_C].ff = FF_FF;
|
||||||
|
logic_cfg.a2d[LUT_C].ff_mux = MUX_XOR;
|
||||||
|
logic_cfg.a2d[LUT_C].ff_srinit = FF_SRINIT0;
|
||||||
|
logic_cfg.a2d[LUT_D].lut6 = "(A6+~A6)*(A5)";
|
||||||
|
logic_cfg.a2d[LUT_D].lut5 = "1";
|
||||||
|
logic_cfg.a2d[LUT_D].cy0 = CY0_O5;
|
||||||
|
logic_cfg.a2d[LUT_D].ff = FF_FF;
|
||||||
|
logic_cfg.a2d[LUT_D].ff_mux = MUX_XOR;
|
||||||
|
logic_cfg.a2d[LUT_D].ff_srinit = FF_SRINIT0;
|
||||||
|
|
||||||
|
logic_cfg.clk_inv = CLKINV_CLK;
|
||||||
|
logic_cfg.sync_attr = SYNCATTR_ASYNC;
|
||||||
|
logic_cfg.precyinit = PRECYINIT_0;
|
||||||
|
logic_cfg.cout_used = 1;
|
||||||
|
rc = fdev_logic_setconf(tstate->model, y, x, type_idx, logic_cfg);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
|
||||||
if ((rc = fnet_new(&model, &inA_net))) FAIL(rc);
|
if ((rc = fnet_new(&model, &inA_net))) FAIL(rc);
|
||||||
if ((rc = fnet_add_port(&model, inA_net, iob_inA_y, iob_inA_x,
|
if ((rc = fnet_add_port(&model, inA_net, iob_inA_y, iob_inA_x,
|
||||||
DEV_IOB, iob_inA_type_idx, IOB_OUT_I))) FAIL(rc);
|
DEV_IOB, iob_inA_type_idx, IOB_OUT_I))) FAIL(rc);
|
||||||
|
@ -79,9 +109,8 @@ int main(int argc, char** argv)
|
||||||
if ((rc = fnet_add_port(&model, out_net, iob_out_y, iob_out_x,
|
if ((rc = fnet_add_port(&model, out_net, iob_out_y, iob_out_x,
|
||||||
DEV_IOB, iob_out_type_idx, IOB_IN_O))) FAIL(rc);
|
DEV_IOB, iob_out_type_idx, IOB_IN_O))) FAIL(rc);
|
||||||
if ((rc = fnet_autoroute(&model, out_net))) FAIL(rc);
|
if ((rc = fnet_autoroute(&model, out_net))) FAIL(rc);
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((rc = write_floorplan(stdout, &model, FP_DEFAULT))) FAIL(rc);
|
write_floorplan(stdout, &model, FP_DEFAULT);
|
||||||
return EXIT_SUCCESS;
|
return fpga_free_model(&model);
|
||||||
fail:
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,7 @@ const char* fpga_iob_sitename(struct fpga_model* model, int y, int x,
|
||||||
|
|
||||||
if (y == TOP_OUTER_ROW) {
|
if (y == TOP_OUTER_ROW) {
|
||||||
for (i = 0; i < sizeof(xc6slx9_iob_top)/sizeof(xc6slx9_iob_top[0]); i++) {
|
for (i = 0; i < sizeof(xc6slx9_iob_top)/sizeof(xc6slx9_iob_top[0]); i++) {
|
||||||
if (xc6slx9_iob_right[i].xy == x) {
|
if (xc6slx9_iob_top[i].xy == x) {
|
||||||
if (idx < 0 || idx > 3) return 0;
|
if (idx < 0 || idx > 3) return 0;
|
||||||
return xc6slx9_iob_top[i].name[idx];
|
return xc6slx9_iob_top[i].name[idx];
|
||||||
}
|
}
|
||||||
|
@ -798,6 +798,60 @@ fail:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fdev_iob_IMUX(struct fpga_model* model, int y, int x,
|
||||||
|
int type_idx, int mux)
|
||||||
|
{
|
||||||
|
struct fpga_device* dev;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
dev = fdev_p(model, y, x, DEV_IOB, type_idx);
|
||||||
|
if (!dev) FAIL(EINVAL);
|
||||||
|
rc = reset_required_pins(dev);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
dev->u.iob.I_mux = mux;
|
||||||
|
dev->instantiated = 1;
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fdev_iob_slew(struct fpga_model* model, int y, int x,
|
||||||
|
int type_idx, int slew)
|
||||||
|
{
|
||||||
|
struct fpga_device* dev;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
dev = fdev_p(model, y, x, DEV_IOB, type_idx);
|
||||||
|
if (!dev) FAIL(EINVAL);
|
||||||
|
rc = reset_required_pins(dev);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
dev->u.iob.slew = slew;
|
||||||
|
dev->instantiated = 1;
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fdev_iob_drive(struct fpga_model* model, int y, int x,
|
||||||
|
int type_idx, int drive_strength)
|
||||||
|
{
|
||||||
|
struct fpga_device* dev;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
dev = fdev_p(model, y, x, DEV_IOB, type_idx);
|
||||||
|
if (!dev) FAIL(EINVAL);
|
||||||
|
rc = reset_required_pins(dev);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
dev->u.iob.drive_strength = drive_strength;
|
||||||
|
dev->instantiated = 1;
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static void scan_lut_digits(const char* s, int* digits)
|
static void scan_lut_digits(const char* s, int* digits)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -87,6 +87,12 @@ int fdev_iob_input(struct fpga_model* model, int y, int x,
|
||||||
int type_idx, const char* io_std);
|
int type_idx, const char* io_std);
|
||||||
int fdev_iob_output(struct fpga_model* model, int y, int x,
|
int fdev_iob_output(struct fpga_model* model, int y, int x,
|
||||||
int type_idx, const char* io_std);
|
int type_idx, const char* io_std);
|
||||||
|
int fdev_iob_IMUX(struct fpga_model* model, int y, int x,
|
||||||
|
int type_idx, int mux);
|
||||||
|
int fdev_iob_slew(struct fpga_model* model, int y, int x,
|
||||||
|
int type_idx, int slew);
|
||||||
|
int fdev_iob_drive(struct fpga_model* model, int y, int x,
|
||||||
|
int type_idx, int drive_strength);
|
||||||
|
|
||||||
int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type,
|
int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type,
|
||||||
int type_idx);
|
int type_idx);
|
||||||
|
|
|
@ -1051,6 +1051,10 @@ int write_floorplan(FILE* f, struct fpga_model* model, int flags)
|
||||||
|
|
||||||
if (!(flags & FP_NO_HEADER))
|
if (!(flags & FP_NO_HEADER))
|
||||||
printf_version(f);
|
printf_version(f);
|
||||||
|
if (model->rc) {
|
||||||
|
fprintf(f, "rc %i\n", model->rc);
|
||||||
|
FAIL(model->rc);
|
||||||
|
}
|
||||||
|
|
||||||
rc = printf_devices(f, model, /*config_only*/ 1);
|
rc = printf_devices(f, model, /*config_only*/ 1);
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
|
|
|
@ -54,6 +54,8 @@
|
||||||
|
|
||||||
struct fpga_model
|
struct fpga_model
|
||||||
{
|
{
|
||||||
|
int rc; // if rc != 0, all function calls will immediately return
|
||||||
|
|
||||||
int cfg_rows;
|
int cfg_rows;
|
||||||
char cfg_columns[512];
|
char cfg_columns[512];
|
||||||
char cfg_left_wiring[1024], cfg_right_wiring[1024];
|
char cfg_left_wiring[1024], cfg_right_wiring[1024];
|
||||||
|
@ -585,7 +587,8 @@ struct fpga_tile
|
||||||
int fpga_build_model(struct fpga_model* model,
|
int fpga_build_model(struct fpga_model* model,
|
||||||
int fpga_rows, const char* columns,
|
int fpga_rows, const char* columns,
|
||||||
const char* left_wiring, const char* right_wiring);
|
const char* left_wiring, const char* right_wiring);
|
||||||
void fpga_free_model(struct fpga_model* model);
|
// returns model->rc (model itself will be memset to 0)
|
||||||
|
int fpga_free_model(struct fpga_model* model);
|
||||||
|
|
||||||
const char* fpga_tiletype_str(enum fpga_tile_type type);
|
const char* fpga_tiletype_str(enum fpga_tile_type type);
|
||||||
|
|
||||||
|
|
|
@ -57,15 +57,19 @@ fail:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fpga_free_model(struct fpga_model* model)
|
int fpga_free_model(struct fpga_model* model)
|
||||||
{
|
{
|
||||||
if (!model) return;
|
int rc;
|
||||||
|
|
||||||
|
if (!model) return 0;
|
||||||
|
rc = model->rc;
|
||||||
free_devices(model);
|
free_devices(model);
|
||||||
free(model->tmp_str);
|
free(model->tmp_str);
|
||||||
strarray_free(&model->str);
|
strarray_free(&model->str);
|
||||||
free(model->tiles);
|
free(model->tiles);
|
||||||
free_xc6_routing_bitpos(model->sw_bitpos);
|
free_xc6_routing_bitpos(model->sw_bitpos);
|
||||||
memset(model, 0, sizeof(*model));
|
memset(model, 0, sizeof(*model));
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* fpga_ttstr[] = // tile type strings
|
static const char* fpga_ttstr[] = // tile type strings
|
||||||
|
|
Loading…
Reference in New Issue
Block a user