From c79b42023e4f5f844a76b675daebe41980b60da1 Mon Sep 17 00:00:00 2001 From: Wolfgang Spraul Date: Fri, 18 Jan 2013 07:53:30 -0500 Subject: [PATCH] blinking_led fix --- blinking_led.c | 230 +++++++++++++++++++++---------------------------- fp2bit.c | 31 +++++-- 2 files changed, 121 insertions(+), 140 deletions(-) diff --git a/blinking_led.c b/blinking_led.c index 4843ae2..9328c0a 100644 --- a/blinking_led.c +++ b/blinking_led.c @@ -17,9 +17,12 @@ // synthesis attribute LOC clk "P55 | IOSTANDARD = LVCMOS33" // synthesis attribute LOC led "P48 | SLEW = QUIETIO | DRIVE = 8" - reg [14:0] counter; + // COUNTER_SIZE tested as 14 (32K crystal) and 23 (20M crystal) + `define COUNTER_SIZE 23 + + reg [`COUNTER_SIZE:0] counter; always @(posedge clk) counter <= counter + 1; - assign led = counter[14]; + assign led = counter[`COUNTER_SIZE]; endmodule */ @@ -27,24 +30,31 @@ int main(int argc, char** argv) { struct fpga_model model; - int param_bits; + int param_highest_bit; const char *param_clock_pin, *param_led_pin; 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; + int logic_x, logic_type_idx, cur_bit; + int cur_y, next_y, i; struct fpgadev_logic logic_cfg; - net_idx_t net; + net_idx_t clock_net, net; + // todo: test with clock=C10/IO_L37N_GCLK12_0, led=M16/IO_L46N_FOE_B_M1DQ3_1 + // currently: T8/R5 + // todo: we could support more ways to specify a pin: + // "bpp:0,30,1" - die-specific bank/pair/positive + // "name:T8" - package-specific pin (including unbonded ones) + // "desc:IO_L30N_2" - package-specific description if (cmdline_help(argc, argv)) { - printf( " %*s [-Dbits=14|23]\n" - " %*s [-Dclock_pin=IO_L30N_GCLK0_USERCCLK_2|...]\n" - " %*s [-Dled_pin=IO_L48P_D7_2|...]\n" + printf( " %*s [-Dhighest_bit=14|23]\n" + " %*s [-Dclock_pin=desc:IO_L30N_GCLK0_USERCCLK_2|...]\n" + " %*s [-Dled_pin=desc:IO_L48P_D7_2|...]\n" "\n", (int) strlen(*argv), "", (int) strlen(*argv), "", (int) strlen(*argv), ""); return 0; } - if (!(param_bits = cmdline_intvar(argc, argv, "bits"))) - param_bits = 14; + if (!(param_highest_bit = cmdline_intvar(argc, argv, "highest_bit"))) + param_highest_bit = 14; if (!(param_clock_pin = cmdline_strvar(argc, argv, "clock_pin"))) param_clock_pin = "IO_L30N_GCLK0_USERCCLK_2"; @@ -68,139 +78,95 @@ int main(int argc, char** argv) fdev_iob_drive(&model, iob_led_y, iob_led_x, iob_led_type_idx, 8); - logic_y = 58; + // todo: temporary because our routing is so fragile... + if (param_highest_bit == 14) + cur_y = 58; + else + cur_y = 52; logic_x = 13; logic_type_idx = DEV_LOG_M_OR_L; - CLEAR(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 = "0"; - 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 = "0"; - 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 = "0"; - 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; - fdev_logic_setconf(&model, logic_y, logic_x, logic_type_idx, &logic_cfg); - - logic_y = 57; - logic_cfg.precyinit = 0; - logic_cfg.a2d[LUT_A].lut6 = "(A6+~A6)*(A5)"; - logic_cfg.a2d[LUT_A].lut5 = "0"; - fdev_logic_setconf(&model, logic_y, logic_x, logic_type_idx, &logic_cfg); - - logic_y = 56; - fdev_logic_setconf(&model, logic_y, logic_x, logic_type_idx, &logic_cfg); - - logic_y = 55; - logic_cfg.cout_used = 0; - logic_cfg.a2d[LUT_C].lut6 = "A5"; - logic_cfg.a2d[LUT_C].lut5 = 0; - logic_cfg.a2d[LUT_C].cy0 = 0; - 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; - CLEAR(logic_cfg.a2d[LUT_D]); - fdev_logic_setconf(&model, logic_y, logic_x, logic_type_idx, &logic_cfg); - - // clock to logic devs - fnet_new(&model, &net); - fnet_add_port(&model, net, iob_clk_y, iob_clk_x, DEV_IOB, + // clock net + fnet_new(&model, &clock_net); + fnet_add_port(&model, clock_net, iob_clk_y, iob_clk_x, DEV_IOB, iob_clk_type_idx, IOB_OUT_I); - fnet_add_port(&model, net, 55, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_CLK); - fnet_add_port(&model, net, 56, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_CLK); - fnet_add_port(&model, net, 57, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_CLK); - fnet_add_port(&model, net, 58, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_CLK); - fnet_route(&model, net); - // vcc to logic devs - fnet_new(&model, &net); - fnet_add_port(&model, net, 55, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_A6); - fnet_add_port(&model, net, 55, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_B6); - fnet_vcc_gnd(&model, net, /*is_vcc*/ 1); + for (cur_bit = 0; cur_bit <= param_highest_bit; cur_bit++) { + RC_ASSERT(&model, cur_y != -1); + if (!(cur_bit % 4)) { // beginning of slice + CLEAR(logic_cfg); + logic_cfg.clk_inv = CLKINV_CLK; + logic_cfg.sync_attr = SYNCATTR_ASYNC; + } + if (!cur_bit) { // first bit + logic_cfg.precyinit = PRECYINIT_0; + 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; + } else if (cur_bit == param_highest_bit) { + logic_cfg.a2d[cur_bit%4].lut6 = "A5"; + logic_cfg.a2d[cur_bit%4].ff = FF_FF; + logic_cfg.a2d[cur_bit%4].ff_mux = MUX_XOR; + logic_cfg.a2d[cur_bit%4].ff_srinit = FF_SRINIT0; + } else { + logic_cfg.a2d[cur_bit%4].lut6 = "(A6+~A6)*(A5)"; + logic_cfg.a2d[cur_bit%4].lut5 = "0"; + logic_cfg.a2d[cur_bit%4].cy0 = CY0_O5; + logic_cfg.a2d[cur_bit%4].ff = FF_FF; + logic_cfg.a2d[cur_bit%4].ff_mux = MUX_XOR; + logic_cfg.a2d[cur_bit%4].ff_srinit = FF_SRINIT0; + } + if (cur_bit%4 == 3 || cur_bit == param_highest_bit) { + static const int out_pin[] = {LO_AQ, LO_BQ, LO_CQ, LO_DQ}; + static const int in_pin[] = {LI_A5, LI_B5, LI_C5, LI_D5}; - fnet_new(&model, &net); - fnet_add_port(&model, net, 56, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_A6); - fnet_add_port(&model, net, 56, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_B6); - fnet_add_port(&model, net, 56, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_C6); - fnet_add_port(&model, net, 56, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_D6); - fnet_vcc_gnd(&model, net, /*is_vcc*/ 1); - - fnet_new(&model, &net); - fnet_add_port(&model, net, 57, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_A6); - fnet_add_port(&model, net, 57, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_B6); - fnet_add_port(&model, net, 57, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_C6); - fnet_add_port(&model, net, 57, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_D6); - fnet_vcc_gnd(&model, net, /*is_vcc*/ 1); - - fnet_new(&model, &net); - fnet_add_port(&model, net, 58, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_A6); - fnet_add_port(&model, net, 58, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_B6); - fnet_add_port(&model, net, 58, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_C6); - fnet_add_port(&model, net, 58, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_D6); - fnet_vcc_gnd(&model, net, /*is_vcc*/ 1); - - // carry chain - fnet_new(&model, &net); - fnet_add_port(&model, net, 55, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_CIN); - fnet_add_port(&model, net, 56, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LO_COUT); - fnet_route(&model, net); - - fnet_new(&model, &net); - fnet_add_port(&model, net, 56, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_CIN); - fnet_add_port(&model, net, 57, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LO_COUT); - fnet_route(&model, net); - - fnet_new(&model, &net); - fnet_add_port(&model, net, 57, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_CIN); - fnet_add_port(&model, net, 58, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LO_COUT); - fnet_route(&model, net); - - // bit chain - { - int out_pin[] = {LO_AQ, LO_BQ, LO_CQ, LO_DQ}; - int in_pin[] = {LI_A5, LI_B5, LI_C5, LI_D5}; - int cur_y, i; - - for (cur_y = 58; cur_y >= 55; cur_y--) { - for (i = 0; i < 4; i++) { - if (cur_y == 55 && i >= 2) - break; + next_y = regular_row_up(cur_y, &model); + if (cur_bit < param_highest_bit) { + RC_ASSERT(&model, next_y != -1); + logic_cfg.cout_used = 1; + // carry chain fnet_new(&model, &net); - fnet_add_port(&model, net, cur_y, 13, DEV_LOGIC, DEV_LOG_M_OR_L, out_pin[i]); - fnet_add_port(&model, net, cur_y, 13, DEV_LOGIC, DEV_LOG_M_OR_L, in_pin[i]); + fnet_add_port(&model, net, cur_y, logic_x, DEV_LOGIC, logic_type_idx, LO_COUT); + fnet_add_port(&model, net, next_y, logic_x, DEV_LOGIC, logic_type_idx, LI_CIN); fnet_route(&model, net); } + fdev_logic_setconf(&model, cur_y, logic_x, logic_type_idx, &logic_cfg); + + // clock net + fnet_add_port(&model, clock_net, cur_y, logic_x, DEV_LOGIC, logic_type_idx, LI_CLK); + + // lut5 net (drive vcc into A6 to enable lut5) + if (logic_cfg.a2d[LUT_A].lut5 + || logic_cfg.a2d[LUT_B].lut5 + || logic_cfg.a2d[LUT_C].lut5 + || logic_cfg.a2d[LUT_D].lut5) { + fnet_new(&model, &net); + if (logic_cfg.a2d[LUT_A].lut5) + fnet_add_port(&model, net, cur_y, logic_x, DEV_LOGIC, logic_type_idx, LI_A6); + if (logic_cfg.a2d[LUT_B].lut5) + fnet_add_port(&model, net, cur_y, logic_x, DEV_LOGIC, logic_type_idx, LI_B6); + if (logic_cfg.a2d[LUT_C].lut5) + fnet_add_port(&model, net, cur_y, logic_x, DEV_LOGIC, logic_type_idx, LI_C6); + if (logic_cfg.a2d[LUT_D].lut5) + fnet_add_port(&model, net, cur_y, logic_x, DEV_LOGIC, logic_type_idx, LI_D6); + fnet_vcc_gnd(&model, net, /*is_vcc*/ 1); + } + for (i = 0; i <= cur_bit%4; i++) { + fnet_new(&model, &net); + fnet_add_port(&model, net, cur_y, logic_x, DEV_LOGIC, logic_type_idx, out_pin[i]); + fnet_add_port(&model, net, cur_y, logic_x, DEV_LOGIC, logic_type_idx, in_pin[i]); + if (cur_bit - cur_bit%4 + i == param_highest_bit) + fnet_add_port(&model, net, iob_led_y, iob_led_x, DEV_IOB, + iob_led_type_idx, IOB_IN_O); + fnet_route(&model, net); + } + cur_y = next_y; } } - fnet_new(&model, &net); - fnet_add_port(&model, net, 55, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LO_CQ); - fnet_add_port(&model, net, 55, 13, DEV_LOGIC, DEV_LOG_M_OR_L, LI_C5); - fnet_add_port(&model, net, iob_led_y, iob_led_x, DEV_IOB, - iob_led_type_idx, IOB_IN_O); - fnet_route(&model, net); - + fnet_route(&model, clock_net); write_floorplan(stdout, &model, FP_DEFAULT); return fpga_free_model(&model); } diff --git a/fp2bit.c b/fp2bit.c index 3277acc..2d85c3a 100644 --- a/fp2bit.c +++ b/fp2bit.c @@ -12,15 +12,14 @@ int main(int argc, char** argv) { struct fpga_model model; - FILE *fbits, *fp = 0; + FILE *fbits = 0, *fp = 0; int rc = -1; - fbits = 0; - if (argc != 3) { + if (argc != 2 && argc != 3) { fprintf(stderr, "\n" "%s - floorplan to bitstream\n" - "Usage: %s \n" + "Usage: %s []\n" "\n", argv[0], argv[0]); goto fail; } @@ -34,10 +33,26 @@ int main(int argc, char** argv) goto fail; } } - fbits = fopen(argv[2], "w"); - if (!fbits) { - fprintf(stderr, "Error opening %s.\n", argv[2]); - goto fail; + if (argc == 3) { + fbits = fopen(argv[2], "w"); + if (!fbits) { + fprintf(stderr, "Error opening %s.\n", argv[2]); + goto fail; + } + } else { + if (fp == stdin) + fbits = stdout; + else { + char out_name[256]; + int i = strlen(argv[1]); + while (i && argv[1][i-1] != '.') i--; + snprintf(out_name, sizeof(out_name), "%.*sbit", i, argv[1]); + fbits = fopen(out_name, "w"); + if (!fbits) { + fprintf(stderr, "Error opening %s.\n", out_name); + goto fail; + } + } } if ((rc = fpga_build_model(&model, XC6SLX9, TQG144)))