/* * libbsdl - parser regression test over a synthetic in-memory BSDL. * SPDX-License-Identifier: LGPL-2.1-or-later * * Exercises: entity, IDCODE, port directions, scalar + vector PIN_MAP, * TAP_SCAN roles, boundary register, instruction opcodes. */ #include #include #include "bsdl/bsdl.h" static int failures = 0; #define CHECK(cond) do { \ if (!(cond)) { \ fprintf(stderr, "FAIL %s:%d: %s\n", __FILE__, __LINE__, #cond); \ failures++; \ } \ } while (0) static const char DEMO[] = "entity DEMO is\n" " generic (PHYSICAL_PIN_MAP : string := \"PKG\");\n" " port (\n" " TCK:in bit;\n" " TDI:in bit;\n" " TDO:out bit;\n" " TMS:in bit;\n" " Q:out bit_vector(0 to 1);\n" " VCC:linkage bit;\n" " GND:linkage bit_vector(0 to 1)\n" " );\n" " use STD_1149_1_2001.all;\n" " attribute PIN_MAP of DEMO : entity is PHYSICAL_PIN_MAP;\n" " constant PKG : PIN_MAP_STRING :=\n" " \"TCK:1,\" &\n" " \"TDI:2,\" &\n" " \"TDO:3,\" &\n" " \"TMS:4,\" &\n" " \"Q:(5,6),\" &\n" " \"VCC:7,\" &\n" " \"GND:(8,9)\";\n" " attribute TAP_SCAN_IN of TDI : signal is true;\n" " attribute TAP_SCAN_MODE of TMS : signal is true;\n" " attribute TAP_SCAN_OUT of TDO : signal is true;\n" " attribute TAP_SCAN_CLOCK of TCK : signal is (10.0e6, BOTH);\n" " attribute INSTRUCTION_LENGTH of DEMO : entity is 4;\n" " attribute INSTRUCTION_OPCODE of DEMO : entity is\n" " \"BYPASS (1111),\" &\n" " \"EXTEST (0000),\" &\n" " \"SAMPLE (0001),\" &\n" " \"IDCODE (1110)\";\n" " attribute IDCODE_REGISTER of DEMO : entity is\n" " \"0001\" &\n" " \"0010001101000101\" &\n" " \"00000000111\" &\n" " \"1\";\n" " attribute BOUNDARY_LENGTH of DEMO : entity is 3;\n" " attribute BOUNDARY_REGISTER of DEMO : entity is\n" " \"0 (BC_1, Q(0), output3, X, 2, 1, Z),\" &\n" " \"1 (BC_1, Q(1), output3, X, 2, 1, Z),\" &\n" " \"2 (BC_1, *, control, 1)\";\n" "end DEMO;\n"; static const bsdl_pin_t *pin(const bsdl_t *m, const char *name) { size_t i; for (i = 0; i < m->pin_count; i++) if (!strcmp(m->pins[i].name, name)) return &m->pins[i]; return NULL; } static int has_instr(const bsdl_t *m, const char *name, const char *opcode) { size_t i; for (i = 0; i < m->instruction_count; i++) if (!strcmp(m->instructions[i].name, name) && !strcmp(m->instructions[i].opcode, opcode)) return 1; return 0; } int main(void) { bsdl_opts_t opts; bsdl_t *m; const bsdl_pin_t *p; bsdl_opts_default(&opts); m = bsdl_parse_buffer(DEMO, sizeof(DEMO) - 1, "demo.bsd", &opts); CHECK(m != NULL); if (!m) { fprintf(stderr, "parse returned NULL\n"); return 1; } /* header */ CHECK(strcmp(m->entity, "DEMO") == 0); CHECK(m->idcode == 0x1234500FUL); CHECK(m->idcode_mask == 0xFFFFFFFFUL); CHECK(m->instruction_length == 4); /* 4 scalars + Q(0..1) + VCC + GND(0..1) = 9 */ CHECK(m->pin_count == 9); /* scalar pin + TAP role + physical pin */ p = pin(m, "TCK"); CHECK(p && p->dir == BSDL_DIR_IN && p->tap_role == BSDL_TAP_TCK && p->physical_pin && !strcmp(p->physical_pin, "1")); p = pin(m, "TDI"); CHECK(p && p->tap_role == BSDL_TAP_TDI && !strcmp(p->physical_pin, "2")); p = pin(m, "TDO"); CHECK(p && p->dir == BSDL_DIR_OUT && p->tap_role == BSDL_TAP_TDO); p = pin(m, "TMS"); CHECK(p && p->tap_role == BSDL_TAP_TMS); /* vector PIN_MAP, positional: Q(0)->5, Q(1)->6 */ p = pin(m, "Q(0)"); CHECK(p && p->dir == BSDL_DIR_OUT && p->physical_pin && !strcmp(p->physical_pin, "5")); p = pin(m, "Q(1)"); CHECK(p && p->physical_pin && !strcmp(p->physical_pin, "6")); /* linkage scalar + vector */ p = pin(m, "VCC"); CHECK(p && p->dir == BSDL_DIR_LINKAGE && !strcmp(p->physical_pin, "7")); p = pin(m, "GND(0)"); CHECK(p && p->dir == BSDL_DIR_LINKAGE && !strcmp(p->physical_pin, "8")); p = pin(m, "GND(1)"); CHECK(p && !strcmp(p->physical_pin, "9")); /* boundary register linkage to pins (tristate output cell) */ CHECK(m->chain_count == 3); p = pin(m, "Q(0)"); CHECK(p && p->out_bit == 0 && p->ctrl_bit == 2); p = pin(m, "Q(1)"); CHECK(p && p->out_bit == 1 && p->ctrl_bit == 2); /* instructions */ CHECK(has_instr(m, "IDCODE", "1110")); CHECK(has_instr(m, "EXTEST", "0000")); CHECK(has_instr(m, "BYPASS", "1111")); CHECK(has_instr(m, "SAMPLE", "0001")); bsdl_free(m); if (failures) { fprintf(stderr, "%d check(s) failed\n", failures); return 1; } printf("all parse checks passed\n"); return 0; }