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.
|
||||
The long-term goals of fpgatools are:
|
||||
|
||||
*) reach the maximum physical performance of the chip
|
||||
*) reach maximum physical chip performance
|
||||
*) fast development cycles
|
||||
*) independent toolchain that only depends on other free software
|
||||
*) bootstrap on chip, i.e. program the fpga from a softcore running
|
||||
on the same fpga
|
||||
*) complete package including all tools to get started such as jtag,
|
||||
debugging, parts data and designs for prototyping hardware
|
||||
*) work towards a design flow that includes later manufacturing
|
||||
in different ASIC processes, include information about ASIC
|
||||
processes, libraries, GDS generation, etc.
|
||||
*) reconfigure on-chip
|
||||
*) include get-started tools such as jtag, debugging, parts data
|
||||
and designs for prototyping hardware
|
||||
*) design flow that includes asic manufacturing
|
||||
*) lightweight C implementation without GUI
|
||||
*) supported platform: Linux
|
||||
*) license: public domain
|
||||
|
@ -59,13 +56,9 @@ Design Principles
|
|||
TODO
|
||||
|
||||
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: counter (including clock, jtag)
|
||||
* support reading iologic switches
|
||||
* autotest: fix roundtrip issues in routing_sw test
|
||||
* autotest: fix bugs in lut_encoding, logic_cfg, routing_sw, io_sw tests
|
||||
* autotest: protect stderr of diff executable in autotest log
|
||||
* 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++;
|
||||
}}
|
||||
// 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;
|
||||
fail:
|
||||
return rc;
|
||||
|
|
|
@ -22,43 +22,73 @@
|
|||
assign led = counter[14];
|
||||
|
||||
endmodule
|
||||
|
||||
*/
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
struct fpga_model model;
|
||||
int iob_inA_y, iob_inA_x, iob_inA_type_idx;
|
||||
int iob_inB_y, iob_inB_x, iob_inB_type_idx;
|
||||
int iob_out_y, iob_out_x, iob_out_type_idx;
|
||||
int iob_clk_y, iob_clk_x, iob_clk_type_idx;
|
||||
int iob_led_y, iob_led_x, iob_led_type_idx;
|
||||
int logic_y, logic_x, logic_type_idx;
|
||||
struct fpgadev_logic logic_cfg;
|
||||
net_idx_t inA_net, inB_net, out_net;
|
||||
int rc;
|
||||
|
||||
if ((rc = fpga_build_model(&model, XC6SLX9_ROWS, XC6SLX9_COLUMNS,
|
||||
XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING))) FAIL(rc);
|
||||
fpga_build_model(&model, XC6SLX9_ROWS, XC6SLX9_COLUMNS,
|
||||
XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING);
|
||||
|
||||
if ((rc = fpga_find_iob(&model, "P45", &iob_inA_y, &iob_inA_x,
|
||||
&iob_inA_type_idx))) FAIL(rc);
|
||||
if ((rc = fdev_iob_input(&model, iob_inA_y, iob_inA_x,
|
||||
iob_inA_type_idx, IO_LVCMOS33))) FAIL(rc);
|
||||
fpga_find_iob(&model, "P55", &iob_clk_y, &iob_clk_x, &iob_clk_type_idx);
|
||||
fdev_iob_input(&model, iob_clk_y, iob_clk_x, iob_clk_type_idx,
|
||||
IO_LVCMOS33);
|
||||
|
||||
if ((rc = fpga_find_iob(&model, "P46", &iob_inB_y, &iob_inB_x,
|
||||
&iob_inB_type_idx))) FAIL(rc);
|
||||
if ((rc = fdev_iob_input(&model, iob_inB_y, iob_inB_x,
|
||||
iob_inB_type_idx, IO_LVCMOS33))) FAIL(rc);
|
||||
|
||||
if ((rc = fpga_find_iob(&model, "P48", &iob_out_y, &iob_out_x,
|
||||
&iob_out_type_idx))) FAIL(rc);
|
||||
if ((rc = fdev_iob_output(&model, iob_out_y, iob_out_x,
|
||||
iob_out_type_idx, IO_LVCMOS33))) FAIL(rc);
|
||||
fpga_find_iob(&model, "P48", &iob_led_y, &iob_led_x, &iob_led_type_idx);
|
||||
fdev_iob_output(&model, iob_led_y, iob_led_x, iob_led_type_idx,
|
||||
IO_LVCMOS25);
|
||||
fdev_iob_slew(&model, iob_led_y, iob_led_x, iob_led_type_idx,
|
||||
SLEW_QUIETIO);
|
||||
fdev_iob_drive(&model, iob_led_y, iob_led_x, iob_led_type_idx,
|
||||
8);
|
||||
|
||||
#if 0
|
||||
logic_y = 68;
|
||||
logic_x = 13;
|
||||
logic_type_idx = DEV_LOG_X;
|
||||
if ((rc = fdev_logic_a2d_lut(&model, logic_y, logic_x, logic_type_idx,
|
||||
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_add_port(&model, inA_net, iob_inA_y, iob_inA_x,
|
||||
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,
|
||||
DEV_IOB, iob_out_type_idx, IOB_IN_O))) FAIL(rc);
|
||||
if ((rc = fnet_autoroute(&model, out_net))) FAIL(rc);
|
||||
#endif
|
||||
|
||||
if ((rc = write_floorplan(stdout, &model, FP_DEFAULT))) FAIL(rc);
|
||||
return EXIT_SUCCESS;
|
||||
fail:
|
||||
return rc;
|
||||
write_floorplan(stdout, &model, FP_DEFAULT);
|
||||
return fpga_free_model(&model);
|
||||
}
|
||||
|
|
|
@ -163,7 +163,7 @@ const char* fpga_iob_sitename(struct fpga_model* model, int y, int x,
|
|||
|
||||
if (y == TOP_OUTER_ROW) {
|
||||
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;
|
||||
return xc6slx9_iob_top[i].name[idx];
|
||||
}
|
||||
|
@ -798,6 +798,60 @@ fail:
|
|||
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)
|
||||
{
|
||||
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 fdev_iob_output(struct fpga_model* model, int y, int x,
|
||||
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 type_idx);
|
||||
|
|
|
@ -1051,6 +1051,10 @@ int write_floorplan(FILE* f, struct fpga_model* model, int flags)
|
|||
|
||||
if (!(flags & FP_NO_HEADER))
|
||||
printf_version(f);
|
||||
if (model->rc) {
|
||||
fprintf(f, "rc %i\n", model->rc);
|
||||
FAIL(model->rc);
|
||||
}
|
||||
|
||||
rc = printf_devices(f, model, /*config_only*/ 1);
|
||||
if (rc) FAIL(rc);
|
||||
|
|
|
@ -54,6 +54,8 @@
|
|||
|
||||
struct fpga_model
|
||||
{
|
||||
int rc; // if rc != 0, all function calls will immediately return
|
||||
|
||||
int cfg_rows;
|
||||
char cfg_columns[512];
|
||||
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_rows, const char* columns,
|
||||
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);
|
||||
|
||||
|
|
|
@ -57,15 +57,19 @@ fail:
|
|||
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(model->tmp_str);
|
||||
strarray_free(&model->str);
|
||||
free(model->tiles);
|
||||
free_xc6_routing_bitpos(model->sw_bitpos);
|
||||
memset(model, 0, sizeof(*model));
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const char* fpga_ttstr[] = // tile type strings
|
||||
|
|
Loading…
Reference in New Issue
Block a user