diff --git a/jtag/ChangeLog b/jtag/ChangeLog index 3a79a52d..61bd21be 100644 --- a/jtag/ChangeLog +++ b/jtag/ChangeLog @@ -1,3 +1,9 @@ +2008-01-20 Arnim Laeuger + + * src/bsdl/bsdl_bison.y, src/bsdl/bsdl_sem.c, src/bsdl/bsdl.h: + handle vectored ports correctly, part 1 of fix for + [ 1875737 ] Syntax errors/Port index warning parsing ATMEL BSDL files + 2008-01-20 Kolja Waschk * src/jim/some_cpu.c, src/jim/some_cpu.bsd: Added BSDL file for some_cpu diff --git a/jtag/src/bsdl/bsdl.h b/jtag/src/bsdl/bsdl.h index 3bfa9e67..bb755444 100644 --- a/jtag/src/bsdl/bsdl.h +++ b/jtag/src/bsdl/bsdl.h @@ -89,12 +89,20 @@ struct cell_info { int disable_safe_value; }; +struct port_desc { + char *name; + int is_vector; + int low_idx; + int high_idx; +}; + /* structure jtag_ctrl collects all elements that are required to interface with jtag internals */ struct jtag_ctrl { int mode; char *idcode; /* IDCODE string */ part_t *part; + struct port_desc port_desc; struct cell_info cell_info; struct instr_elem *instr_list; struct access_data access_data; @@ -136,13 +144,16 @@ void bsdl_sem_init(parser_priv_t *); void bsdl_sem_deinit(parser_priv_t *); void bsdl_set_entity(parser_priv_t *, char *); void bsdl_set_instruction_length(parser_priv_t *, int); -void bsdl_add_pin(parser_priv_t *, char *); +void bsdl_prt_add_name(parser_priv_t *, char *); +void bsdl_prt_add_bit(parser_priv_t *); +void bsdl_prt_add_range(parser_priv_t *, int, int); +void bsdl_prt_apply_port(parser_priv_t *); void bsdl_set_idcode(parser_priv_t *, char *); void bsdl_set_usercode(parser_priv_t *, char *); void bsdl_add_instruction(parser_priv_t *, char *, char *); void bsdl_set_bsr_length(parser_priv_t *, int); void bsdl_ci_no_disable(parser_priv_t *); -void bsdl_ci_set_cell_spec(parser_priv_t *, char *, int, char *); +void bsdl_ci_set_cell_spec(parser_priv_t *, int, char *); void bsdl_ci_set_cell_spec_disable(parser_priv_t *, int, int, int); void bsdl_ci_apply_cell_info(parser_priv_t *, int); void bsdl_ac_set_register(parser_priv_t *, char *, int); diff --git a/jtag/src/bsdl/bsdl_bison.y b/jtag/src/bsdl/bsdl_bison.y index 23243ea5..7641dc2f 100644 --- a/jtag/src/bsdl/bsdl_bison.y +++ b/jtag/src/bsdl/bsdl_bison.y @@ -192,7 +192,6 @@ void yyerror(parser_priv_t *, const char *); %type Pattern_List %type DECIMAL_NUMBER %type REAL_NUMBER -%type Port_Name %type Cell_Function %type Safe_Value %type Disable_Value @@ -269,19 +268,29 @@ Port_Specifier_List : Port_Specifier | Port_Specifier_List SEMICOLON Port_Specifier ; Port_Specifier : Port_List COLON Function Scaler_Or_Vector + { + bsdl_prt_apply_port(priv_data); + } ; Port_List : IDENTIFIER - { free($1); } + { bsdl_prt_add_name(priv_data, $1); } | Port_List COMMA IDENTIFIER - { free($3); } + { + Print_Warning(priv_data, + "Comma separated port names in port list not supported"); + bsdl_prt_add_name(priv_data, $3); + } ; Function : IN | OUT | INOUT | BUFFER | LINKAGE ; Scaler_Or_Vector : BIT + { bsdl_prt_add_bit(priv_data); } | BIT_VECTOR LPAREN Vector_Range RPAREN ; Vector_Range : DECIMAL_NUMBER TO DECIMAL_NUMBER + { bsdl_prt_add_range(priv_data, $1, $3); } | DECIMAL_NUMBER DOWNTO DECIMAL_NUMBER + { bsdl_prt_add_range(priv_data, $3, $1); } ; VHDL_Use_Part : Standard_Use | Standard_Use VHDL_Use_List @@ -496,9 +505,7 @@ BSDL_Map_String : Pin_Mapping | BSDL_Map_String COMMA Pin_Mapping ; Pin_Mapping : IDENTIFIER COLON Physical_Pin_Desc - { - bsdl_add_pin(priv_data, $1); - } + { free($1); } ; Physical_Pin_Desc: Physical_Pin | LPAREN Physical_Pin_List RPAREN @@ -780,19 +787,24 @@ Cell_Spec : IDENTIFIER COMMA Port_Name COMMA Cell_Function COMMA Safe_Value { free($1); - bsdl_ci_set_cell_spec(priv_data, $3, $5, $7); + bsdl_ci_set_cell_spec(priv_data, $5, $7); } ; Port_Name : IDENTIFIER - { $$ = $1; } + { + bsdl_prt_add_name(priv_data, $1); + bsdl_prt_add_bit(priv_data); + } | IDENTIFIER LPAREN DECIMAL_NUMBER RPAREN { - Print_Warning(priv_data, "Port name index not supported in Boundary Cell description"); - $$ = NULL; - free($1); + bsdl_prt_add_name(priv_data, $1); + bsdl_prt_add_range(priv_data, $3, $3); } | ASTERISK - { $$ = strdup("*"); } + { + bsdl_prt_add_name(priv_data, strdup("*")); + bsdl_prt_add_bit(priv_data); + } ; Cell_Function : INPUT { $$ = INPUT; } diff --git a/jtag/src/bsdl/bsdl_sem.c b/jtag/src/bsdl/bsdl_sem.c index 20e89857..742be1ff 100644 --- a/jtag/src/bsdl/bsdl_sem.c +++ b/jtag/src/bsdl/bsdl_sem.c @@ -207,32 +207,134 @@ void bsdl_set_instruction_length(parser_priv_t *priv, int len) /***************************************************************************** - * void bsdl_add_pin(parser_priv_t *priv, char *pin) + * void bsdl_prt_add_name(parser_priv_t *priv, char *name) + * Port name management function * - * Adds the specified pin name as a signal via shell command + * Sets the name field of the temporary storage area for port description + * (port_desc) to the parameter name. + * + * Parameters + * priv : private data container for parser related tasks + * name : base name of the port, memory get's free'd + * + * Returns + * void + ****************************************************************************/ +void bsdl_prt_add_name(parser_priv_t *priv, char *name) +{ + struct port_desc *pd = &(priv->jtag_ctrl.port_desc); + + pd->name = name; +} + + +/***************************************************************************** + * void bsdl_prt_add_bit(parser_priv_t *priv) + * Port name management function + * + * Sets the vector and index fields of the temporary storage area for port + * description (port_desc) to non-vector information. The low and high indice + * are set to equal numbers (exact value is irrelevant). + * + * Parameters + * priv : private data container for parser related tasks + * + * Returns + * void + ****************************************************************************/ +void bsdl_prt_add_bit(parser_priv_t *priv) +{ + struct port_desc *pd = &(priv->jtag_ctrl.port_desc); + + pd->is_vector = 0; + pd->low_idx = 0; + pd->high_idx = 0; +} + + +/***************************************************************************** + * void bsdl_prt_add_range(parser_priv_t *priv, int low, int high) + * Port name management function + * + * Sets the vector and index fields of the temporary storage area for port + * description (port_desc) to the specified vector information. + * + * Parameters + * priv : private data container for parser related tasks + * low : low index of vector + * high : high index of vector + * + * Returns + * void + ****************************************************************************/ +void bsdl_prt_add_range(parser_priv_t *priv, int low, int high) +{ + struct port_desc *pd = &(priv->jtag_ctrl.port_desc); + + pd->is_vector = 1; + pd->low_idx = low; + pd->high_idx = high; +} + + +/***************************************************************************** + * void bsdl_prt_apply_port(parser_priv_t *priv) + * Port name management function + * + * Adds the specified port name as a signal via shell command * signal + * The port name is taken from the port_desc structure that was filled in + * previously by rule Scalar_or_Vector. This way, the function can build + * vectored ports as well. * * Parameters * priv : private data container for parser related tasks - * pin : name of the new pin, memory gets free'd * * Returns * void ****************************************************************************/ -void bsdl_add_pin(parser_priv_t *priv, char *pin) +void bsdl_prt_apply_port(parser_priv_t *priv) { + struct port_desc *pd = &(priv->jtag_ctrl.port_desc); + if (priv->jtag_ctrl.mode >= 0) { char *cmd[] = {"signal", - pin, + NULL, NULL}; + char *port_string; + size_t str_len, name_len; + int idx; + + /* handle indexed port name: + - names of scalar ports are simply copied from the port_desc structure + to the final string that goes into ci + - names of vectored ports are expanded with their decimal index as + collected earlier earlier in rule Scalar_or_Vector + */ + name_len = strlen(pd->name); + str_len = name_len + 1 + 10 + 1 + 1; + if ((port_string = (char *)malloc(str_len)) != NULL) { + cmd[1] = port_string; + + for (idx = pd->low_idx; idx <= pd->high_idx; idx++) { + if (pd->is_vector) + snprintf(port_string, str_len-1, "%s(%d)", pd->name, idx); + else + strncpy(port_string, pd->name, str_len-1); + port_string[str_len-1] = '\0'; - if (priv->jtag_ctrl.mode >= 1) - cmd_run(cmd); - else - print_cmd(cmd); + if (priv->jtag_ctrl.mode >= 1) + cmd_run(cmd); + else + print_cmd(cmd); + } + + free(port_string); + } else + bsdl_msg(BSDL_MSG_ERR, "Out of memory, %s line %i\n", __FILE__, __LINE__); } - free(pin); + free(pd->name); } @@ -391,14 +493,15 @@ void bsdl_ci_no_disable(parser_priv_t *priv) /***************************************************************************** * Cell Info management function * void bsdl_ci_set_cell_spec(parser_priv_t *priv, - * char *port_name, int function, char *safe_value) + * int function, char *safe_value) * * Sets the specified values of the current cell_spec (without disable term) * to the variables for temporary storage of these information elements. + * The name of the related port is taken from the port_desc structure that + * was filled in previously by the rule Port_Name. * * Parameters * priv : private data container for parser related tasks - * port_name : port name this spec applies to * function : cell function indentificator * safe_value : safe value for initialization of this cell * @@ -406,13 +509,38 @@ void bsdl_ci_no_disable(parser_priv_t *priv) * void ****************************************************************************/ void bsdl_ci_set_cell_spec(parser_priv_t *priv, - char *port_name, int function, char *safe_value) + int function, char *safe_value) { struct cell_info *ci = &(priv->jtag_ctrl.cell_info); + struct port_desc *pd = &(priv->jtag_ctrl.port_desc); + char *port_string; + size_t str_len, name_len; - ci->port_name = port_name; ci->cell_function = function; ci->basic_safe_value = safe_value; + + /* handle indexed port name: + - names of scalar ports are simply copied from the port_desc structure + to the final string that goes into ci + - names of vectored ports are expanded with their decimal index as + collected earlier earlier in rule Port_Name + */ + name_len = strlen(pd->name); + str_len = name_len + 1 + 10 + 1 + 1; + if ((port_string = (char *)malloc(str_len)) != NULL) { + if (pd->is_vector) + snprintf(port_string, str_len-1, "%s(%d)", pd->name, pd->low_idx); + else + strncpy(port_string, pd->name, str_len-1); + port_string[str_len-1] = '\0'; + + ci->port_name = port_string; + } else { + bsdl_msg(BSDL_MSG_ERR, "Out of memory, %s line %i\n", __FILE__, __LINE__); + ci->port_name = NULL; + } + + free(pd->name); }