continued on blinking_led.c

This commit is contained in:
Wolfgang Spraul 2012-10-12 01:29:10 +02:00
parent 6a0f623028
commit cf4a88fbb3
8 changed files with 150 additions and 41 deletions

19
README
View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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