support IO standards LVCMOS 33/25/18/15/12, LVTTL
This commit is contained in:
parent
d96fb235ee
commit
a356ac5b55
14
LINKS
14
LINKS
|
@ -4,3 +4,17 @@ http://en.wikipedia.org/wiki/Wikipedia:WikiProject_Electronics/Programs
|
|||
http://qfsm.sourceforge.net/about.html
|
||||
http://www.texample.net/tikz/examples/timing-diagram/
|
||||
http://smithsonianchips.si.edu/ice/s4.htm
|
||||
|
||||
http://www.hottconsultants.com/techtips/pcb-stack-up-3.html
|
||||
|
||||
Andrew's redtin logic analyzer
|
||||
http://code.google.com/p/red-tin-logic-analyzer
|
||||
|
||||
gtkwave wave viewer
|
||||
http://gtkwave.sourceforge.net
|
||||
|
||||
Fedora Electronic Lab tool overview
|
||||
http://spins.fedoraproject.org/fel/#portfolio
|
||||
http://chitlesh.fedorapeople.org/FEL/list.html
|
||||
|
||||
with links to magic, toped, qucs, iverilog, alliance, etc.
|
||||
|
|
1
README
1
README
|
@ -61,6 +61,7 @@ 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
|
||||
|
|
88
autotest.c
88
autotest.c
|
@ -514,7 +514,7 @@ int test_routing_sw_from_iob(struct test_state* tstate,
|
|||
|
||||
rc = fpga_find_iob(tstate->model, "P48", &iob_y, &iob_x, &iob_type_idx);
|
||||
if (rc) FAIL(rc);
|
||||
rc = fdev_iob_output(tstate->model, iob_y, iob_x, iob_type_idx);
|
||||
rc = fdev_iob_output(tstate->model, iob_y, iob_x, iob_type_idx, IO_LVCMOS33);
|
||||
if (rc) FAIL(rc);
|
||||
iob_dev = fdev_p(tstate->model, iob_y, iob_x, DEV_IOB, iob_type_idx);
|
||||
if (!iob_dev) FAIL(EINVAL);
|
||||
|
@ -851,7 +851,7 @@ static int test_iologic_switches(struct test_state* tstate)
|
|||
// input IOB
|
||||
rc = fpga_find_iob(tstate->model, iob_name, &iob_y, &iob_x, &iob_type_idx);
|
||||
if (rc) FAIL(rc);
|
||||
rc = fdev_iob_input(tstate->model, iob_y, iob_x, iob_type_idx);
|
||||
rc = fdev_iob_input(tstate->model, iob_y, iob_x, iob_type_idx, IO_LVCMOS33);
|
||||
if (rc) FAIL(rc);
|
||||
rc = test_iologic_switches2(tstate, iob_y, iob_x, iob_type_idx);
|
||||
if (rc) FAIL(rc);
|
||||
|
@ -860,7 +860,7 @@ static int test_iologic_switches(struct test_state* tstate)
|
|||
// output IOB
|
||||
rc = fpga_find_iob(tstate->model, iob_name, &iob_y, &iob_x, &iob_type_idx);
|
||||
if (rc) FAIL(rc);
|
||||
rc = fdev_iob_output(tstate->model, iob_y, iob_x, iob_type_idx);
|
||||
rc = fdev_iob_output(tstate->model, iob_y, iob_x, iob_type_idx, IO_LVCMOS33);
|
||||
if (rc) FAIL(rc);
|
||||
rc = test_iologic_switches2(tstate, iob_y, iob_x, iob_type_idx);
|
||||
if (rc) FAIL(rc);
|
||||
|
@ -873,16 +873,17 @@ fail:
|
|||
|
||||
static int test_iob_config(struct test_state* tstate)
|
||||
{
|
||||
int iob_y, iob_x, iob_type_idx, rc;
|
||||
int iob_y, iob_x, iob_type_idx, i, j, rc;
|
||||
net_idx_t net_idx;
|
||||
struct fpga_device* dev;
|
||||
int drive_strengths[] = {2, 4, 6, 8, 12, 16, 24};
|
||||
|
||||
tstate->diff_to_null = 1;
|
||||
|
||||
// P45 is an IOBS
|
||||
rc = fpga_find_iob(tstate->model, "P45", &iob_y, &iob_x, &iob_type_idx);
|
||||
if (rc) FAIL(rc);
|
||||
rc = fdev_iob_input(tstate->model, iob_y, iob_x, iob_type_idx);
|
||||
rc = fdev_iob_input(tstate->model, iob_y, iob_x, iob_type_idx, IO_LVCMOS33);
|
||||
if (rc) FAIL(rc);
|
||||
dev = fdev_p(tstate->model, iob_y, iob_x, DEV_IOB, iob_type_idx);
|
||||
if (!dev) FAIL(EINVAL);
|
||||
|
@ -896,7 +897,7 @@ static int test_iob_config(struct test_state* tstate)
|
|||
// P46 is an IOBM
|
||||
rc = fpga_find_iob(tstate->model, "P46", &iob_y, &iob_x, &iob_type_idx);
|
||||
if (rc) FAIL(rc);
|
||||
rc = fdev_iob_input(tstate->model, iob_y, iob_x, iob_type_idx);
|
||||
rc = fdev_iob_input(tstate->model, iob_y, iob_x, iob_type_idx, IO_LVCMOS33);
|
||||
if (rc) FAIL(rc);
|
||||
if ((rc = diff_printf(tstate))) FAIL(rc);
|
||||
fdev_delete(tstate->model, iob_y, iob_x, DEV_IOB, iob_type_idx);
|
||||
|
@ -904,7 +905,7 @@ static int test_iob_config(struct test_state* tstate)
|
|||
// P47 is an IOBS
|
||||
rc = fpga_find_iob(tstate->model, "P47", &iob_y, &iob_x, &iob_type_idx);
|
||||
if (rc) FAIL(rc);
|
||||
rc = fdev_iob_output(tstate->model, iob_y, iob_x, iob_type_idx);
|
||||
rc = fdev_iob_output(tstate->model, iob_y, iob_x, iob_type_idx, IO_LVCMOS33);
|
||||
if (rc) FAIL(rc);
|
||||
dev = fdev_p(tstate->model, iob_y, iob_x, DEV_IOB, iob_type_idx);
|
||||
if (!dev) FAIL(EINVAL);
|
||||
|
@ -928,20 +929,10 @@ static int test_iob_config(struct test_state* tstate)
|
|||
rc = diff_printf(tstate); if (rc) FAIL(rc);
|
||||
dev->u.iob.suspend = SUSP_3STATE;
|
||||
|
||||
dev->u.iob.drive_strength = 2;
|
||||
rc = diff_printf(tstate); if (rc) FAIL(rc);
|
||||
dev->u.iob.drive_strength = 4;
|
||||
rc = diff_printf(tstate); if (rc) FAIL(rc);
|
||||
dev->u.iob.drive_strength = 6;
|
||||
rc = diff_printf(tstate); if (rc) FAIL(rc);
|
||||
dev->u.iob.drive_strength = 8;
|
||||
rc = diff_printf(tstate); if (rc) FAIL(rc);
|
||||
dev->u.iob.drive_strength = 12;
|
||||
rc = diff_printf(tstate); if (rc) FAIL(rc);
|
||||
dev->u.iob.drive_strength = 16;
|
||||
rc = diff_printf(tstate); if (rc) FAIL(rc);
|
||||
dev->u.iob.drive_strength = 24;
|
||||
rc = diff_printf(tstate); if (rc) FAIL(rc);
|
||||
for (i = 0; i < sizeof(drive_strengths)/sizeof(*drive_strengths); i++) {
|
||||
dev->u.iob.drive_strength = drive_strengths[i];
|
||||
rc = diff_printf(tstate); if (rc) FAIL(rc);
|
||||
}
|
||||
dev->u.iob.drive_strength = 8;
|
||||
|
||||
dev->u.iob.slew = SLEW_SLOW;
|
||||
|
@ -957,7 +948,7 @@ static int test_iob_config(struct test_state* tstate)
|
|||
// P48 is an IOBM
|
||||
rc = fpga_find_iob(tstate->model, "P48", &iob_y, &iob_x, &iob_type_idx);
|
||||
if (rc) FAIL(rc);
|
||||
rc = fdev_iob_output(tstate->model, iob_y, iob_x, iob_type_idx);
|
||||
rc = fdev_iob_output(tstate->model, iob_y, iob_x, iob_type_idx, IO_LVCMOS33);
|
||||
if (rc) FAIL(rc);
|
||||
dev = fdev_p(tstate->model, iob_y, iob_x, DEV_IOB, iob_type_idx);
|
||||
if (!dev) FAIL(EINVAL);
|
||||
|
@ -977,7 +968,59 @@ static int test_iob_config(struct test_state* tstate)
|
|||
if (rc) FAIL(rc);
|
||||
if ((rc = diff_printf(tstate))) FAIL(rc);
|
||||
|
||||
fnet_delete(tstate->model, net_idx);
|
||||
fdev_delete(tstate->model, iob_y, iob_x, DEV_IOB, iob_type_idx);
|
||||
|
||||
// different IO standards
|
||||
// The left (3) and right (1) banks have higher voltage ranges
|
||||
// than the top (0) and bottom (2) banks, so we test this on
|
||||
// the left side (ug381 page 13).
|
||||
// todo: IO_SSTL2_I is not implemented right
|
||||
{ const char* io_std[] = { IO_LVCMOS33, IO_LVCMOS25, IO_LVCMOS18,
|
||||
IO_LVCMOS18_JEDEC, IO_LVCMOS15, IO_LVCMOS15_JEDEC,
|
||||
IO_LVCMOS12, IO_LVCMOS12_JEDEC, IO_LVTTL, IO_SSTL2_I, 0 };
|
||||
i = 0;
|
||||
while (io_std[i]) {
|
||||
// input
|
||||
rc = fpga_find_iob(tstate->model, "P22", &iob_y, &iob_x, &iob_type_idx);
|
||||
if (rc) FAIL(rc);
|
||||
rc = fdev_iob_input(tstate->model, iob_y, iob_x, iob_type_idx, io_std[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);
|
||||
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
while (io_std[i]) {
|
||||
// output
|
||||
rc = fpga_find_iob(tstate->model, "P22", &iob_y, &iob_x, &iob_type_idx);
|
||||
if (rc) FAIL(rc);
|
||||
rc = fdev_iob_output(tstate->model, iob_y, iob_x, iob_type_idx, io_std[i]);
|
||||
if (rc) FAIL(rc);
|
||||
if (!strcmp(io_std[i], IO_SSTL2_I)) {
|
||||
rc = diff_printf(tstate); if (rc) FAIL(rc);
|
||||
} else {
|
||||
dev = fdev_p(tstate->model, iob_y, iob_x, DEV_IOB, iob_type_idx);
|
||||
if (!dev) FAIL(EINVAL);
|
||||
|
||||
for (j = 0; j < sizeof(drive_strengths)/sizeof(*drive_strengths); j++) {
|
||||
if ((!strcmp(io_std[i], IO_LVCMOS15)
|
||||
|| !strcmp(io_std[i], IO_LVCMOS15_JEDEC))
|
||||
&& drive_strengths[j] == 24)
|
||||
continue;
|
||||
if ((!strcmp(io_std[i], IO_LVCMOS12)
|
||||
|| !strcmp(io_std[i], IO_LVCMOS12_JEDEC))
|
||||
&& (drive_strengths[j] == 16 || drive_strengths[j] == 24))
|
||||
continue;
|
||||
dev->u.iob.drive_strength = drive_strengths[j];
|
||||
rc = diff_printf(tstate); if (rc) FAIL(rc);
|
||||
}
|
||||
}
|
||||
fdev_delete(tstate->model, iob_y, iob_x, DEV_IOB, iob_type_idx);
|
||||
|
||||
i++;
|
||||
}}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
|
@ -1126,7 +1169,6 @@ static int test_lut_encoding(struct test_state* tstate)
|
|||
}
|
||||
}
|
||||
}
|
||||
out:
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
|
|
|
@ -25,17 +25,17 @@ int main(int argc, char** argv)
|
|||
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))) FAIL(rc);
|
||||
iob_inA_type_idx, IO_LVCMOS33))) FAIL(rc);
|
||||
|
||||
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))) FAIL(rc);
|
||||
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))) FAIL(rc);
|
||||
iob_out_type_idx, IO_LVCMOS33))) FAIL(rc);
|
||||
|
||||
logic_y = 68;
|
||||
logic_x = 13;
|
||||
|
|
|
@ -25,17 +25,17 @@ int main(int argc, char** argv)
|
|||
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))) FAIL(rc);
|
||||
iob_inA_type_idx, IO_LVCMOS33))) FAIL(rc);
|
||||
|
||||
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))) FAIL(rc);
|
||||
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))) FAIL(rc);
|
||||
iob_out_type_idx, IO_LVCMOS33))) FAIL(rc);
|
||||
|
||||
logic_y = 68;
|
||||
logic_x = 13;
|
||||
|
|
|
@ -123,17 +123,30 @@ static int write_iobs(struct fpga_bits* bits, struct fpga_model* model)
|
|||
if (dev->u.iob.istandard[0]) {
|
||||
if (!dev->u.iob.I_mux
|
||||
|| !dev->u.iob.bypass_mux
|
||||
|| strcmp(dev->u.iob.istandard, IO_LVCMOS33)
|
||||
|| dev->u.iob.ostandard[0])
|
||||
HERE();
|
||||
|
||||
u64 = XC6_IOB_INSTANTIATED;
|
||||
u64 |= XC6_IOB_INPUT_LVCMOS33;
|
||||
if (dev->u.iob.I_mux == IMUX_I)
|
||||
u64 |= XC6_IOB_IMUX_I;
|
||||
else if (dev->u.iob.I_mux == IMUX_I_B)
|
||||
u64 = XC6_IOB_INPUT | XC6_IOB_INSTANTIATED;
|
||||
|
||||
if (dev->u.iob.I_mux == IMUX_I_B)
|
||||
u64 |= XC6_IOB_IMUX_I_B;
|
||||
else HERE();
|
||||
|
||||
if (!strcmp(dev->u.iob.istandard, IO_LVCMOS33)
|
||||
|| !strcmp(dev->u.iob.istandard, IO_LVCMOS25)
|
||||
|| !strcmp(dev->u.iob.istandard, IO_LVTTL))
|
||||
u64 |= XC6_IOB_INPUT_LVCMOS33_25_LVTTL;
|
||||
else if (!strcmp(dev->u.iob.istandard, IO_LVCMOS18)
|
||||
|| !strcmp(dev->u.iob.istandard, IO_LVCMOS15)
|
||||
|| !strcmp(dev->u.iob.istandard, IO_LVCMOS12))
|
||||
u64 |= XC6_IOB_INPUT_LVCMOS18_15_12;
|
||||
else if (!strcmp(dev->u.iob.istandard, IO_LVCMOS18_JEDEC)
|
||||
|| !strcmp(dev->u.iob.istandard, IO_LVCMOS15_JEDEC)
|
||||
|| !strcmp(dev->u.iob.istandard, IO_LVCMOS12_JEDEC))
|
||||
u64 |= XC6_IOB_INPUT_LVCMOS18_15_12_JEDEC;
|
||||
else if (!strcmp(dev->u.iob.istandard, IO_SSTL2_I))
|
||||
u64 |= XC6_IOB_INPUT_SSTL2_I;
|
||||
else
|
||||
HERE();
|
||||
|
||||
frame_set_u64(&bits->d[IOB_DATA_START
|
||||
+ part_idx*IOB_ENTRY_LEN], u64);
|
||||
|
@ -141,29 +154,85 @@ static int write_iobs(struct fpga_bits* bits, struct fpga_model* model)
|
|||
if (!dev->u.iob.drive_strength
|
||||
|| !dev->u.iob.slew
|
||||
|| !dev->u.iob.suspend
|
||||
|| strcmp(dev->u.iob.ostandard, IO_LVCMOS33)
|
||||
|| dev->u.iob.istandard[0])
|
||||
HERE();
|
||||
|
||||
u64 = XC6_IOB_INSTANTIATED;
|
||||
// for now we always turn on O_PINW even if no net
|
||||
// is connected to the pinw
|
||||
u64 |= XC6_IOB_MASK_O_PINW;
|
||||
switch (dev->u.iob.drive_strength) {
|
||||
case 2: u64 |= XC6_IOB_OUTPUT_LVCMOS33_DRIVE_2; break;
|
||||
case 4: u64 |= XC6_IOB_OUTPUT_LVCMOS33_DRIVE_4; break;
|
||||
case 6: u64 |= XC6_IOB_OUTPUT_LVCMOS33_DRIVE_6; break;
|
||||
case 8: u64 |= XC6_IOB_OUTPUT_LVCMOS33_DRIVE_8; break;
|
||||
case 12: u64 |= XC6_IOB_OUTPUT_LVCMOS33_DRIVE_12; break;
|
||||
case 16: u64 |= XC6_IOB_OUTPUT_LVCMOS33_DRIVE_16; break;
|
||||
case 24: u64 |= XC6_IOB_OUTPUT_LVCMOS33_DRIVE_24; break;
|
||||
default: HERE();
|
||||
}
|
||||
u64 |= XC6_IOB_O_PINW;
|
||||
if (!strcmp(dev->u.iob.ostandard, IO_LVTTL)) {
|
||||
switch (dev->u.iob.drive_strength) {
|
||||
case 2: u64 |= XC6_IOB_OUTPUT_LVTTL_DRIVE_2; break;
|
||||
case 4: u64 |= XC6_IOB_OUTPUT_LVTTL_DRIVE_4; break;
|
||||
case 6: u64 |= XC6_IOB_OUTPUT_LVTTL_DRIVE_6; break;
|
||||
case 8: u64 |= XC6_IOB_OUTPUT_LVTTL_DRIVE_8; break;
|
||||
case 12: u64 |= XC6_IOB_OUTPUT_LVTTL_DRIVE_12; break;
|
||||
case 16: u64 |= XC6_IOB_OUTPUT_LVTTL_DRIVE_16; break;
|
||||
case 24: u64 |= XC6_IOB_OUTPUT_LVTTL_DRIVE_24; break;
|
||||
default: FAIL(EINVAL);
|
||||
}
|
||||
} else if (!strcmp(dev->u.iob.ostandard, IO_LVCMOS33)) {
|
||||
switch (dev->u.iob.drive_strength) {
|
||||
case 2: u64 |= XC6_IOB_OUTPUT_LVCMOS33_25_DRIVE_2; break;
|
||||
case 4: u64 |= XC6_IOB_OUTPUT_LVCMOS33_DRIVE_4; break;
|
||||
case 6: u64 |= XC6_IOB_OUTPUT_LVCMOS33_DRIVE_6; break;
|
||||
case 8: u64 |= XC6_IOB_OUTPUT_LVCMOS33_DRIVE_8; break;
|
||||
case 12: u64 |= XC6_IOB_OUTPUT_LVCMOS33_DRIVE_12; break;
|
||||
case 16: u64 |= XC6_IOB_OUTPUT_LVCMOS33_DRIVE_16; break;
|
||||
case 24: u64 |= XC6_IOB_OUTPUT_LVCMOS33_DRIVE_24; break;
|
||||
default: FAIL(EINVAL);
|
||||
}
|
||||
} else if (!strcmp(dev->u.iob.ostandard, IO_LVCMOS25)) {
|
||||
switch (dev->u.iob.drive_strength) {
|
||||
case 2: u64 |= XC6_IOB_OUTPUT_LVCMOS33_25_DRIVE_2; break;
|
||||
case 4: u64 |= XC6_IOB_OUTPUT_LVCMOS25_DRIVE_4; break;
|
||||
case 6: u64 |= XC6_IOB_OUTPUT_LVCMOS25_DRIVE_6; break;
|
||||
case 8: u64 |= XC6_IOB_OUTPUT_LVCMOS25_DRIVE_8; break;
|
||||
case 12: u64 |= XC6_IOB_OUTPUT_LVCMOS25_DRIVE_12; break;
|
||||
case 16: u64 |= XC6_IOB_OUTPUT_LVCMOS25_DRIVE_16; break;
|
||||
case 24: u64 |= XC6_IOB_OUTPUT_LVCMOS25_DRIVE_24; break;
|
||||
default: FAIL(EINVAL);
|
||||
}
|
||||
} else if (!strcmp(dev->u.iob.ostandard, IO_LVCMOS18)
|
||||
|| !strcmp(dev->u.iob.ostandard, IO_LVCMOS18_JEDEC)) {
|
||||
switch (dev->u.iob.drive_strength) {
|
||||
case 2: u64 |= XC6_IOB_OUTPUT_LVCMOS18_DRIVE_2; break;
|
||||
case 4: u64 |= XC6_IOB_OUTPUT_LVCMOS18_DRIVE_4; break;
|
||||
case 6: u64 |= XC6_IOB_OUTPUT_LVCMOS18_DRIVE_6; break;
|
||||
case 8: u64 |= XC6_IOB_OUTPUT_LVCMOS18_DRIVE_8; break;
|
||||
case 12: u64 |= XC6_IOB_OUTPUT_LVCMOS18_DRIVE_12; break;
|
||||
case 16: u64 |= XC6_IOB_OUTPUT_LVCMOS18_DRIVE_16; break;
|
||||
case 24: u64 |= XC6_IOB_OUTPUT_LVCMOS18_DRIVE_24; break;
|
||||
default: FAIL(EINVAL);
|
||||
}
|
||||
} else if (!strcmp(dev->u.iob.ostandard, IO_LVCMOS15)
|
||||
|| !strcmp(dev->u.iob.ostandard, IO_LVCMOS15_JEDEC)) {
|
||||
switch (dev->u.iob.drive_strength) {
|
||||
case 2: u64 |= XC6_IOB_OUTPUT_LVCMOS15_DRIVE_2; break;
|
||||
case 4: u64 |= XC6_IOB_OUTPUT_LVCMOS15_DRIVE_4; break;
|
||||
case 6: u64 |= XC6_IOB_OUTPUT_LVCMOS15_DRIVE_6; break;
|
||||
case 8: u64 |= XC6_IOB_OUTPUT_LVCMOS15_DRIVE_8; break;
|
||||
case 12: u64 |= XC6_IOB_OUTPUT_LVCMOS15_DRIVE_12; break;
|
||||
case 16: u64 |= XC6_IOB_OUTPUT_LVCMOS15_DRIVE_16; break;
|
||||
default: FAIL(EINVAL);
|
||||
}
|
||||
} else if (!strcmp(dev->u.iob.ostandard, IO_LVCMOS12)
|
||||
|| !strcmp(dev->u.iob.ostandard, IO_LVCMOS12_JEDEC)) {
|
||||
switch (dev->u.iob.drive_strength) {
|
||||
case 2: u64 |= XC6_IOB_OUTPUT_LVCMOS12_DRIVE_2; break;
|
||||
case 4: u64 |= XC6_IOB_OUTPUT_LVCMOS12_DRIVE_4; break;
|
||||
case 6: u64 |= XC6_IOB_OUTPUT_LVCMOS12_DRIVE_6; break;
|
||||
case 8: u64 |= XC6_IOB_OUTPUT_LVCMOS12_DRIVE_8; break;
|
||||
case 12: u64 |= XC6_IOB_OUTPUT_LVCMOS12_DRIVE_12; break;
|
||||
default: FAIL(EINVAL);
|
||||
}
|
||||
} else FAIL(EINVAL);
|
||||
switch (dev->u.iob.slew) {
|
||||
case SLEW_SLOW: u64 |= XC6_IOB_SLEW_SLOW; break;
|
||||
case SLEW_FAST: u64 |= XC6_IOB_SLEW_FAST; break;
|
||||
case SLEW_QUIETIO: u64 |= XC6_IOB_SLEW_QUIETIO; break;
|
||||
default: HERE();
|
||||
default: FAIL(EINVAL);
|
||||
}
|
||||
switch (dev->u.iob.suspend) {
|
||||
case SUSP_LAST_VAL: u64 |= XC6_IOB_SUSP_LAST_VAL; break;
|
||||
|
@ -172,7 +241,7 @@ static int write_iobs(struct fpga_bits* bits, struct fpga_model* model)
|
|||
case SUSP_3STATE_PULLDOWN: u64 |= XC6_IOB_SUSP_3STATE_PULLDOWN; break;
|
||||
case SUSP_3STATE_KEEPER: u64 |= XC6_IOB_SUSP_3STATE_KEEPER; break;
|
||||
case SUSP_3STATE_OCT_ON: u64 |= XC6_IOB_SUSP_3STATE_OCT_ON; break;
|
||||
default: HERE();
|
||||
default: FAIL(EINVAL);
|
||||
}
|
||||
|
||||
frame_set_u64(&bits->d[IOB_DATA_START
|
||||
|
@ -219,58 +288,214 @@ static int extract_iobs(struct fpga_model* model, struct fpga_bits* bits)
|
|||
clear_bit(bits, /*row*/ 0, get_rightside_major(XC6SLX9),
|
||||
/*minor*/ 22, 64*15+XC6_HCLK_BITS+4);
|
||||
}
|
||||
if ((u64 & XC6_IOB_MASK_INSTANTIATED) == XC6_IOB_INSTANTIATED)
|
||||
u64 &= ~XC6_IOB_MASK_INSTANTIATED;
|
||||
if (u64 & XC6_IOB_INSTANTIATED)
|
||||
u64 &= ~XC6_IOB_INSTANTIATED;
|
||||
else
|
||||
HERE();
|
||||
|
||||
switch (u64 & XC6_IOB_MASK_IO) {
|
||||
case XC6_IOB_INPUT_LVCMOS33:
|
||||
u64 &= ~XC6_IOB_MASK_IO;
|
||||
|
||||
strcpy(cfg.istandard, IO_LVCMOS33);
|
||||
case XC6_IOB_INPUT:
|
||||
cfg.bypass_mux = BYPASS_MUX_I;
|
||||
|
||||
switch (u64 & XC6_IOB_MASK_I_MUX) {
|
||||
case XC6_IOB_IMUX_I:
|
||||
u64 &= ~XC6_IOB_MASK_I_MUX;
|
||||
cfg.I_mux = IMUX_I;
|
||||
if (u64 & XC6_IOB_IMUX_I_B) {
|
||||
cfg.I_mux = IMUX_I_B;
|
||||
u64 &= ~XC6_IOB_IMUX_I_B;
|
||||
} else
|
||||
cfg.I_mux = IMUX_I;
|
||||
|
||||
switch (u64 & XC6_IOB_MASK_IN_TYPE) {
|
||||
case XC6_IOB_INPUT_LVCMOS33_25_LVTTL:
|
||||
u64 &= ~XC6_IOB_MASK_IN_TYPE;
|
||||
strcpy(cfg.istandard, IO_LVCMOS25);
|
||||
break;
|
||||
case XC6_IOB_IMUX_I_B:
|
||||
u64 &= ~XC6_IOB_MASK_I_MUX;
|
||||
cfg.I_mux = IMUX_I_B;
|
||||
case XC6_IOB_INPUT_LVCMOS18_15_12:
|
||||
u64 &= ~XC6_IOB_MASK_IN_TYPE;
|
||||
strcpy(cfg.istandard, IO_LVCMOS12);
|
||||
break;
|
||||
case XC6_IOB_INPUT_LVCMOS18_15_12_JEDEC:
|
||||
u64 &= ~XC6_IOB_MASK_IN_TYPE;
|
||||
strcpy(cfg.istandard, IO_LVCMOS12_JEDEC);
|
||||
break;
|
||||
case XC6_IOB_INPUT_SSTL2_I:
|
||||
u64 &= ~XC6_IOB_MASK_IN_TYPE;
|
||||
strcpy(cfg.istandard, IO_SSTL2_I);
|
||||
break;
|
||||
default: HERE();
|
||||
}
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_2:
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_4:
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_6:
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_8:
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_12:
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_16:
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_24:
|
||||
switch (u64 & XC6_IOB_MASK_IO) {
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_2:
|
||||
cfg.drive_strength = 2; break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_4:
|
||||
cfg.drive_strength = 4; break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_6:
|
||||
cfg.drive_strength = 6; break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_8:
|
||||
cfg.drive_strength = 8; break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_12:
|
||||
cfg.drive_strength = 12; break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_16:
|
||||
cfg.drive_strength = 16; break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_24:
|
||||
cfg.drive_strength = 24; break;
|
||||
default: HERE(); break;
|
||||
}
|
||||
u64 &= ~XC6_IOB_MASK_IO;
|
||||
u64 &= ~XC6_IOB_MASK_O_PINW;
|
||||
break;
|
||||
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_25_DRIVE_2:
|
||||
cfg.drive_strength = 2;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS25);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_4:
|
||||
cfg.drive_strength = 4;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS33);
|
||||
cfg.O_used = 1;
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_6:
|
||||
cfg.drive_strength = 6;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS33);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_8:
|
||||
cfg.drive_strength = 8;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS33);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_12:
|
||||
cfg.drive_strength = 12;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS33);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_16:
|
||||
cfg.drive_strength = 16;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS33);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS33_DRIVE_24:
|
||||
cfg.drive_strength = 24;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS33);
|
||||
break;
|
||||
|
||||
case XC6_IOB_OUTPUT_LVCMOS25_DRIVE_4:
|
||||
cfg.drive_strength = 4;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS25);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS25_DRIVE_6:
|
||||
cfg.drive_strength = 6;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS25);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS25_DRIVE_8:
|
||||
cfg.drive_strength = 8;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS25);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS25_DRIVE_12:
|
||||
cfg.drive_strength = 12;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS25);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS25_DRIVE_16:
|
||||
cfg.drive_strength = 16;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS25);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS25_DRIVE_24:
|
||||
cfg.drive_strength = 24;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS25);
|
||||
break;
|
||||
|
||||
case XC6_IOB_OUTPUT_LVTTL_DRIVE_2:
|
||||
cfg.drive_strength = 2;
|
||||
strcpy(cfg.ostandard, IO_LVTTL);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVTTL_DRIVE_4:
|
||||
cfg.drive_strength = 4;
|
||||
strcpy(cfg.ostandard, IO_LVTTL);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVTTL_DRIVE_6:
|
||||
cfg.drive_strength = 6;
|
||||
strcpy(cfg.ostandard, IO_LVTTL);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVTTL_DRIVE_8:
|
||||
cfg.drive_strength = 8;
|
||||
strcpy(cfg.ostandard, IO_LVTTL);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVTTL_DRIVE_12:
|
||||
cfg.drive_strength = 12;
|
||||
strcpy(cfg.ostandard, IO_LVTTL);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVTTL_DRIVE_16:
|
||||
cfg.drive_strength = 16;
|
||||
strcpy(cfg.ostandard, IO_LVTTL);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVTTL_DRIVE_24:
|
||||
cfg.drive_strength = 24;
|
||||
strcpy(cfg.ostandard, IO_LVTTL);
|
||||
break;
|
||||
|
||||
case XC6_IOB_OUTPUT_LVCMOS18_DRIVE_2:
|
||||
cfg.drive_strength = 2;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS18);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS18_DRIVE_4:
|
||||
cfg.drive_strength = 4;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS18);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS18_DRIVE_6:
|
||||
cfg.drive_strength = 6;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS18);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS18_DRIVE_8:
|
||||
cfg.drive_strength = 8;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS18);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS18_DRIVE_12:
|
||||
cfg.drive_strength = 12;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS18);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS18_DRIVE_16:
|
||||
cfg.drive_strength = 16;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS18);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS18_DRIVE_24:
|
||||
cfg.drive_strength = 24;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS18);
|
||||
break;
|
||||
|
||||
case XC6_IOB_OUTPUT_LVCMOS15_DRIVE_2:
|
||||
cfg.drive_strength = 2;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS15);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS15_DRIVE_4:
|
||||
cfg.drive_strength = 4;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS15);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS15_DRIVE_6:
|
||||
cfg.drive_strength = 6;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS15);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS15_DRIVE_8:
|
||||
cfg.drive_strength = 8;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS15);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS15_DRIVE_12:
|
||||
cfg.drive_strength = 12;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS15);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS15_DRIVE_16:
|
||||
cfg.drive_strength = 16;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS15);
|
||||
break;
|
||||
|
||||
case XC6_IOB_OUTPUT_LVCMOS12_DRIVE_2:
|
||||
cfg.drive_strength = 2;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS12);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS12_DRIVE_4:
|
||||
cfg.drive_strength = 4;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS12);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS12_DRIVE_6:
|
||||
cfg.drive_strength = 6;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS12);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS12_DRIVE_8:
|
||||
cfg.drive_strength = 8;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS12);
|
||||
break;
|
||||
case XC6_IOB_OUTPUT_LVCMOS12_DRIVE_12:
|
||||
cfg.drive_strength = 12;
|
||||
strcpy(cfg.ostandard, IO_LVCMOS12);
|
||||
break;
|
||||
|
||||
default: HERE(); break;
|
||||
}
|
||||
if (cfg.istandard[0] || cfg.ostandard[0])
|
||||
u64 &= ~XC6_IOB_MASK_IO;
|
||||
if (cfg.ostandard[0]) {
|
||||
cfg.O_used = 1;
|
||||
u64 &= ~XC6_IOB_O_PINW;
|
||||
|
||||
if (!strcmp(cfg.ostandard, IO_LVCMOS12)
|
||||
|| !strcmp(cfg.ostandard, IO_LVCMOS15)
|
||||
|| !strcmp(cfg.ostandard, IO_LVCMOS18)
|
||||
|| !strcmp(cfg.ostandard, IO_LVCMOS25)
|
||||
|| !strcmp(cfg.ostandard, IO_LVCMOS33)
|
||||
|| !strcmp(cfg.ostandard, IO_LVTTL)) {
|
||||
switch (u64 & XC6_IOB_MASK_SLEW) {
|
||||
case XC6_IOB_SLEW_SLOW:
|
||||
u64 &= ~XC6_IOB_MASK_SLEW;
|
||||
|
@ -286,35 +511,34 @@ static int extract_iobs(struct fpga_model* model, struct fpga_bits* bits)
|
|||
break;
|
||||
default: HERE();
|
||||
}
|
||||
switch (u64 & XC6_IOB_MASK_SUSPEND) {
|
||||
case XC6_IOB_SUSP_3STATE:
|
||||
u64 &= ~XC6_IOB_MASK_SUSPEND;
|
||||
cfg.suspend = SUSP_3STATE;
|
||||
break;
|
||||
case XC6_IOB_SUSP_3STATE_OCT_ON:
|
||||
u64 &= ~XC6_IOB_MASK_SUSPEND;
|
||||
cfg.suspend = SUSP_3STATE_OCT_ON;
|
||||
break;
|
||||
case XC6_IOB_SUSP_3STATE_KEEPER:
|
||||
u64 &= ~XC6_IOB_MASK_SUSPEND;
|
||||
cfg.suspend = SUSP_3STATE_KEEPER;
|
||||
break;
|
||||
case XC6_IOB_SUSP_3STATE_PULLUP:
|
||||
u64 &= ~XC6_IOB_MASK_SUSPEND;
|
||||
cfg.suspend = SUSP_3STATE_PULLUP;
|
||||
break;
|
||||
case XC6_IOB_SUSP_3STATE_PULLDOWN:
|
||||
u64 &= ~XC6_IOB_MASK_SUSPEND;
|
||||
cfg.suspend = SUSP_3STATE_PULLDOWN;
|
||||
break;
|
||||
case XC6_IOB_SUSP_LAST_VAL:
|
||||
u64 &= ~XC6_IOB_MASK_SUSPEND;
|
||||
cfg.suspend = SUSP_LAST_VAL;
|
||||
break;
|
||||
default: HERE();
|
||||
}
|
||||
break;
|
||||
default: HERE(); break;
|
||||
}
|
||||
switch (u64 & XC6_IOB_MASK_SUSPEND) {
|
||||
case XC6_IOB_SUSP_3STATE:
|
||||
u64 &= ~XC6_IOB_MASK_SUSPEND;
|
||||
cfg.suspend = SUSP_3STATE;
|
||||
break;
|
||||
case XC6_IOB_SUSP_3STATE_OCT_ON:
|
||||
u64 &= ~XC6_IOB_MASK_SUSPEND;
|
||||
cfg.suspend = SUSP_3STATE_OCT_ON;
|
||||
break;
|
||||
case XC6_IOB_SUSP_3STATE_KEEPER:
|
||||
u64 &= ~XC6_IOB_MASK_SUSPEND;
|
||||
cfg.suspend = SUSP_3STATE_KEEPER;
|
||||
break;
|
||||
case XC6_IOB_SUSP_3STATE_PULLUP:
|
||||
u64 &= ~XC6_IOB_MASK_SUSPEND;
|
||||
cfg.suspend = SUSP_3STATE_PULLUP;
|
||||
break;
|
||||
case XC6_IOB_SUSP_3STATE_PULLDOWN:
|
||||
u64 &= ~XC6_IOB_MASK_SUSPEND;
|
||||
cfg.suspend = SUSP_3STATE_PULLDOWN;
|
||||
break;
|
||||
case XC6_IOB_SUSP_LAST_VAL:
|
||||
u64 &= ~XC6_IOB_MASK_SUSPEND;
|
||||
cfg.suspend = SUSP_LAST_VAL;
|
||||
break;
|
||||
default: HERE();
|
||||
}
|
||||
}
|
||||
if (!u64) {
|
||||
frame_set_u64(&bits->d[IOB_DATA_START
|
||||
|
|
|
@ -682,7 +682,8 @@ fail:
|
|||
// iob device
|
||||
//
|
||||
|
||||
int fdev_iob_input(struct fpga_model* model, int y, int x, int type_idx)
|
||||
int fdev_iob_input(struct fpga_model* model, int y, int x, int type_idx,
|
||||
const char* io_std)
|
||||
{
|
||||
struct fpga_device* dev;
|
||||
int rc;
|
||||
|
@ -692,7 +693,7 @@ int fdev_iob_input(struct fpga_model* model, int y, int x, int type_idx)
|
|||
rc = reset_required_pins(dev);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
strcpy(dev->u.iob.istandard, IO_LVCMOS33);
|
||||
strcpy(dev->u.iob.istandard, io_std);
|
||||
dev->u.iob.bypass_mux = BYPASS_MUX_I;
|
||||
dev->u.iob.I_mux = IMUX_I;
|
||||
dev->instantiated = 1;
|
||||
|
@ -701,7 +702,8 @@ fail:
|
|||
return rc;
|
||||
}
|
||||
|
||||
int fdev_iob_output(struct fpga_model* model, int y, int x, int type_idx)
|
||||
int fdev_iob_output(struct fpga_model* model, int y, int x, int type_idx,
|
||||
const char* io_std)
|
||||
{
|
||||
struct fpga_device* dev;
|
||||
int rc;
|
||||
|
@ -711,11 +713,21 @@ int fdev_iob_output(struct fpga_model* model, int y, int x, int type_idx)
|
|||
rc = reset_required_pins(dev);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
strcpy(dev->u.iob.ostandard, IO_LVCMOS33);
|
||||
dev->u.iob.drive_strength = 8;
|
||||
strcpy(dev->u.iob.ostandard, io_std);
|
||||
dev->u.iob.O_used = 1;
|
||||
dev->u.iob.slew = SLEW_QUIETIO;
|
||||
dev->u.iob.suspend = SUSP_3STATE;
|
||||
if (strcmp(io_std, IO_SSTL2_I)) {
|
||||
// also see ug381 page 31
|
||||
if (!strcmp(io_std, IO_LVCMOS33)
|
||||
|| !strcmp(io_std, IO_LVCMOS25))
|
||||
dev->u.iob.drive_strength = 12;
|
||||
else if (!strcmp(io_std, IO_LVCMOS12)
|
||||
|| !strcmp(io_std, IO_LVCMOS12_JEDEC))
|
||||
dev->u.iob.drive_strength = 6;
|
||||
else
|
||||
dev->u.iob.drive_strength = 8;
|
||||
dev->u.iob.slew = SLEW_SLOW;
|
||||
}
|
||||
dev->instantiated = 1;
|
||||
return 0;
|
||||
fail:
|
||||
|
|
|
@ -78,8 +78,10 @@ int fdev_logic_cout_used(struct fpga_model* model, int y, int x,
|
|||
int fdev_logic_precyinit(struct fpga_model* model, int y, int x,
|
||||
int type_idx, int precyinit);
|
||||
|
||||
int fdev_iob_input(struct fpga_model* model, int y, int x, int type_idx);
|
||||
int fdev_iob_output(struct fpga_model* model, int y, int x, int type_idx);
|
||||
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_set_required_pins(struct fpga_model* model, int y, int x, int type,
|
||||
int type_idx);
|
||||
|
|
|
@ -366,7 +366,7 @@ const char* lut2bool(const uint64_t lut, int bits,
|
|||
|
||||
int printf_iob(uint8_t* d, int len, int inpos, int num_entries)
|
||||
{
|
||||
int i, j, num_printed;
|
||||
int i, num_printed;
|
||||
uint64_t u64;
|
||||
|
||||
num_printed = 0;
|
||||
|
@ -375,10 +375,6 @@ int printf_iob(uint8_t* d, int len, int inpos, int num_entries)
|
|||
if (u64) {
|
||||
printf("iob i%i 0x%016llX\n", i,
|
||||
(long long unsigned) u64);
|
||||
for (j = 0; j < 64; j++) {
|
||||
if (u64 & (1ULL << j))
|
||||
printf("iob i%i b%i\n", i, j);
|
||||
}
|
||||
num_printed++;
|
||||
}
|
||||
}
|
||||
|
|
12
libs/model.h
12
libs/model.h
|
@ -445,8 +445,16 @@ struct fpgadev_logic
|
|||
|
||||
enum { IOBM = 1, IOBS };
|
||||
typedef char IOSTANDARD[32];
|
||||
#define IO_LVCMOS33 "LVCMOS33"
|
||||
#define IO_SSTL2_I "SSTL2_I" // drive attr and slew not used here?
|
||||
#define IO_LVTTL "LVTTL"
|
||||
#define IO_LVCMOS33 "LVCMOS33"
|
||||
#define IO_LVCMOS25 "LVCMOS25"
|
||||
#define IO_LVCMOS18 "LVCMOS18"
|
||||
#define IO_LVCMOS18_JEDEC "LVCMOS18_JEDEC"
|
||||
#define IO_LVCMOS15 "LVCMOS15"
|
||||
#define IO_LVCMOS15_JEDEC "LVCMOS15_JEDEC"
|
||||
#define IO_LVCMOS12 "LVCMOS12"
|
||||
#define IO_LVCMOS12_JEDEC "LVCMOS12_JEDEC"
|
||||
#define IO_SSTL2_I "SSTL2_I" // TODO: sstl not fully supported
|
||||
enum { BYPASS_MUX_I = 1, BYPASS_MUX_O, BYPASS_MUX_T };
|
||||
enum { IMUX_I_B = 1, IMUX_I };
|
||||
enum { SLEW_SLOW = 1, SLEW_FAST, SLEW_QUIETIO };
|
||||
|
|
55
libs/parts.h
55
libs/parts.h
|
@ -41,25 +41,64 @@
|
|||
#define XC6_HCLK_BYTES 2
|
||||
#define XC6_HCLK_BITS (XC6_HCLK_BYTES*8)
|
||||
|
||||
#define XC6_IOB_MASK_INSTANTIATED 0x0000000000000080
|
||||
#define XC6_IOB_MASK_IO 0x00FF00FF00000000
|
||||
#define XC6_IOB_MASK_O_PINW 0x0000000000000100
|
||||
#define XC6_IOB_MASK_I_MUX 0x000000000000E400
|
||||
#define XC6_IOB_MASK_IO 0x00FF00FFFF000000
|
||||
#define XC6_IOB_MASK_IN_TYPE 0x000000000000F000
|
||||
#define XC6_IOB_MASK_SLEW 0x0000000000FF0000
|
||||
#define XC6_IOB_MASK_SUSPEND 0x000000000000001F
|
||||
|
||||
#define XC6_IOB_INSTANTIATED 0x0000000000000080
|
||||
#define XC6_IOB_INPUT_LVCMOS33 0x00D0002400000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS33_DRIVE_2 0x001000B400000000
|
||||
#define XC6_IOB_INPUT 0x00D0002400000000
|
||||
#define XC6_IOB_INPUT_LVCMOS33_25_LVTTL 0x000000000000E000
|
||||
#define XC6_IOB_INPUT_LVCMOS18_15_12 0x000000000000C000
|
||||
#define XC6_IOB_INPUT_LVCMOS18_15_12_JEDEC 0x0000000000002000
|
||||
#define XC6_IOB_INPUT_SSTL2_I 0x000000000000B000
|
||||
|
||||
#define XC6_IOB_OUTPUT_LVCMOS33_25_DRIVE_2 0x001000B400000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS33_DRIVE_4 0x0070006C00000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS33_DRIVE_6 0x003000FC00000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS33_DRIVE_8 0x0040000000000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS33_DRIVE_12 0x0060008800000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS33_DRIVE_16 0x009800C600000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS33_DRIVE_24 0x0088007200000000
|
||||
|
||||
#define XC6_IOB_OUTPUT_LVCMOS25_DRIVE_4 0x00B0006C00000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS25_DRIVE_6 0x004000FC00000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS25_DRIVE_8 0x0000000000000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS25_DRIVE_12 0x0058008800000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS25_DRIVE_16 0x00B800C600000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS25_DRIVE_24 0x0054007200000000
|
||||
|
||||
#define XC6_IOB_OUTPUT_LVTTL_DRIVE_2 0x009000B400000000
|
||||
#define XC6_IOB_OUTPUT_LVTTL_DRIVE_4 0x00F0006C00000000
|
||||
#define XC6_IOB_OUTPUT_LVTTL_DRIVE_6 0x007000FC00000000
|
||||
#define XC6_IOB_OUTPUT_LVTTL_DRIVE_8 0x0030000000000000
|
||||
#define XC6_IOB_OUTPUT_LVTTL_DRIVE_12 0x0080008800000000
|
||||
#define XC6_IOB_OUTPUT_LVTTL_DRIVE_16 0x006000C600000000
|
||||
#define XC6_IOB_OUTPUT_LVTTL_DRIVE_24 0x0018007200000000
|
||||
|
||||
#define XC6_IOB_OUTPUT_LVCMOS18_DRIVE_2 0x00F000B402000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS18_DRIVE_4 0x00C000AC02000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS18_DRIVE_6 0x00E000BC02000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS18_DRIVE_8 0x00D800A002000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS18_DRIVE_12 0x003800A802000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS18_DRIVE_16 0x002800A602000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS18_DRIVE_24 0x00A400A202000000
|
||||
|
||||
#define XC6_IOB_OUTPUT_LVCMOS15_DRIVE_2 0x00B0007402000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS15_DRIVE_4 0x00E0000C02000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS15_DRIVE_6 0x0098005C02000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS15_DRIVE_8 0x00C8003002000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS15_DRIVE_12 0x00F4001802000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS15_DRIVE_16 0x002400D602000000
|
||||
|
||||
#define XC6_IOB_OUTPUT_LVCMOS12_DRIVE_2 0x004000B402000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS12_DRIVE_4 0x0098006C02000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS12_DRIVE_6 0x008800FC02000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS12_DRIVE_8 0x0014000002000000
|
||||
#define XC6_IOB_OUTPUT_LVCMOS12_DRIVE_12 0x00FC008802000000
|
||||
|
||||
#define XC6_IOB_IMUX_I_B 0x0000000000000400
|
||||
#define XC6_IOB_O_PINW 0x0000000000000100
|
||||
#define XC6_IOB_IMUX_I 0x000000000000E000
|
||||
#define XC6_IOB_IMUX_I_B 0x000000000000E400
|
||||
#define XC6_IOB_SLEW_SLOW 0x0000000000000000
|
||||
#define XC6_IOB_SLEW_FAST 0x0000000000330000
|
||||
#define XC6_IOB_SLEW_QUIETIO 0x0000000000660000
|
||||
|
|
Loading…
Reference in New Issue
Block a user