Add support for .part/v.s
This patch adds support for .part/v.s. A variable part select with a signed select expression in a continuous assign.
This commit is contained in:
parent
e1af002a32
commit
98c39cfa24
|
|
@ -1654,16 +1654,9 @@ static void draw_lpm_part(ivl_lpm_t net)
|
||||||
fprintf(vvp_out, ", %u, %u;\n", base, width);
|
fprintf(vvp_out, ", %u, %u;\n", base, width);
|
||||||
} else {
|
} else {
|
||||||
const char*sel_symbol = draw_net_input(sel);
|
const char*sel_symbol = draw_net_input(sel);
|
||||||
/* We need to enhance .part/v to support a signed index. */
|
fprintf(vvp_out, "L_%p%s .part/v%s %s", net, dly,
|
||||||
if (ivl_lpm_signed(net) && width_of_nexus(sel) < 8*sizeof(int)) {
|
(ivl_lpm_signed(net) ? ".s" : ""),
|
||||||
fprintf(stderr, "%s:%u: tgt-vvp warning: V0.9 may give "
|
draw_net_input(ivl_lpm_data(net,0)));
|
||||||
"incorrect results for a select with a "
|
|
||||||
"signed index less than %zu bits.\n",
|
|
||||||
ivl_lpm_file(net), ivl_lpm_lineno(net),
|
|
||||||
8*sizeof(int));
|
|
||||||
}
|
|
||||||
fprintf(vvp_out, "L_%p%s .part/v %s",
|
|
||||||
net, dly, draw_net_input(ivl_lpm_data(net,0)));
|
|
||||||
fprintf(vvp_out, ", %s", sel_symbol);
|
fprintf(vvp_out, ", %s", sel_symbol);
|
||||||
fprintf(vvp_out, ", %u;\n", width);
|
fprintf(vvp_out, ", %u;\n", width);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -473,6 +473,7 @@ bit number, and a width. Normally, those bits are constant values.
|
||||||
<label> .part <symbol>, <base>, <wid>;
|
<label> .part <symbol>, <base>, <wid>;
|
||||||
<label> .part/pv <symbol>, <base>, <wid>, <vector_wid>;
|
<label> .part/pv <symbol>, <base>, <wid>, <vector_wid>;
|
||||||
<label> .part/v <symbol>, <symbol>, <wid>;
|
<label> .part/v <symbol>, <symbol>, <wid>;
|
||||||
|
<label> .part/v.s <symbol>, <symbol>, <wid>;
|
||||||
|
|
||||||
The input is typically a .reg or .net, but can be any vector node in
|
The input is typically a .reg or .net, but can be any vector node in
|
||||||
the netlist.
|
the netlist.
|
||||||
|
|
@ -485,7 +486,8 @@ that part is written to. Destination nodes use this value to check
|
||||||
further output widths.
|
further output widths.
|
||||||
|
|
||||||
The .part/v variation takes a vector (or long) input on port-1 as the
|
The .part/v variation takes a vector (or long) input on port-1 as the
|
||||||
base of the part select. Thus, the part select can move around.
|
base of the part select. Thus, the part select can move around. The
|
||||||
|
.part/v.s variation treats the vector as a signed value.
|
||||||
|
|
||||||
PART CONCATENATION STATEMENTS:
|
PART CONCATENATION STATEMENTS:
|
||||||
|
|
||||||
|
|
@ -1111,7 +1113,7 @@ current read or write context of the running thread, using its
|
||||||
stored context index.
|
stored context index.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ extern void compile_part_select_pv(char*label, char*src,
|
||||||
unsigned base, unsigned wid,
|
unsigned base, unsigned wid,
|
||||||
unsigned vec_wid);
|
unsigned vec_wid);
|
||||||
extern void compile_part_select_var(char*label, char*src,
|
extern void compile_part_select_var(char*label, char*src,
|
||||||
char*var, unsigned wid);
|
char*var, unsigned wid, bool is_signed);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is called by the parser to make the various arithmetic and
|
* This is called by the parser to make the various arithmetic and
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,7 @@ static char* strdupnew(char const *str)
|
||||||
".part" { return K_PART; }
|
".part" { return K_PART; }
|
||||||
".part/pv" { return K_PART_PV; }
|
".part/pv" { return K_PART_PV; }
|
||||||
".part/v" { return K_PART_V; }
|
".part/v" { return K_PART_V; }
|
||||||
|
".part/v.s" { return K_PART_V_S; }
|
||||||
".port" { return K_PORT; }
|
".port" { return K_PORT; }
|
||||||
".reduce/and" { return K_REDUCE_AND; }
|
".reduce/and" { return K_REDUCE_AND; }
|
||||||
".reduce/or" { return K_REDUCE_OR; }
|
".reduce/or" { return K_REDUCE_OR; }
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ static struct __vpiModPath*modpath_dst = 0;
|
||||||
%token K_MODPATH K_NET K_NET_S K_NET_R
|
%token K_MODPATH K_NET K_NET_S K_NET_R
|
||||||
%token K_NET8 K_NET8_S
|
%token K_NET8 K_NET8_S
|
||||||
%token K_PARAM_STR K_PARAM_L K_PARAM_REAL K_PART K_PART_PV
|
%token K_PARAM_STR K_PARAM_L K_PARAM_REAL K_PART K_PART_PV
|
||||||
%token K_PART_V K_PORT K_PV K_REDUCE_AND K_REDUCE_OR K_REDUCE_XOR
|
%token K_PART_V K_PART_V_S K_PORT K_PV K_REDUCE_AND K_REDUCE_OR K_REDUCE_XOR
|
||||||
%token K_REDUCE_NAND K_REDUCE_NOR K_REDUCE_XNOR K_REPEAT
|
%token K_REDUCE_NAND K_REDUCE_NOR K_REDUCE_XNOR K_REPEAT
|
||||||
%token K_RESOLV K_SCOPE K_SFUNC K_SFUNC_E K_SHIFTL K_SHIFTR K_SHIFTRS
|
%token K_RESOLV K_SCOPE K_SFUNC K_SFUNC_E K_SHIFTL K_SHIFTR K_SHIFTRS
|
||||||
%token K_THREAD K_TIMESCALE K_TRAN K_TRANIF0 K_TRANIF1 K_TRANVP
|
%token K_THREAD K_TIMESCALE K_TRAN K_TRANIF0 K_TRANIF1 K_TRANVP
|
||||||
|
|
@ -250,7 +250,9 @@ statement
|
||||||
{ compile_part_select_pv($1, $3, $5, $7, $9); }
|
{ compile_part_select_pv($1, $3, $5, $7, $9); }
|
||||||
|
|
||||||
| T_LABEL K_PART_V T_SYMBOL ',' T_SYMBOL ',' T_NUMBER ';'
|
| T_LABEL K_PART_V T_SYMBOL ',' T_SYMBOL ',' T_NUMBER ';'
|
||||||
{ compile_part_select_var($1, $3, $5, $7); }
|
{ compile_part_select_var($1, $3, $5, $7, false); }
|
||||||
|
| T_LABEL K_PART_V_S T_SYMBOL ',' T_SYMBOL ',' T_NUMBER ';'
|
||||||
|
{ compile_part_select_var($1, $3, $5, $7, true); }
|
||||||
|
|
||||||
| T_LABEL K_CONCAT '[' T_NUMBER T_NUMBER T_NUMBER T_NUMBER ']' ','
|
| T_LABEL K_CONCAT '[' T_NUMBER T_NUMBER T_NUMBER T_NUMBER ']' ','
|
||||||
symbols ';'
|
symbols ';'
|
||||||
|
|
|
||||||
22
vvp/part.cc
22
vvp/part.cc
|
|
@ -229,8 +229,8 @@ void vvp_fun_part_pv::recv_vec8(vvp_net_ptr_t port, const vvp_vector8_t&bit)
|
||||||
vvp_send_vec8_pv(port.ptr()->out, bit, base_, wid_, vwid_);
|
vvp_send_vec8_pv(port.ptr()->out, bit, base_, wid_, vwid_);
|
||||||
}
|
}
|
||||||
|
|
||||||
vvp_fun_part_var::vvp_fun_part_var(unsigned w)
|
vvp_fun_part_var::vvp_fun_part_var(unsigned w, bool is_signed)
|
||||||
: wid_(w)
|
: wid_(w), is_signed_(is_signed)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -251,9 +251,7 @@ bool vvp_fun_part_var::recv_vec4_(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
||||||
// INT_MIN is before the vector and is used to
|
// INT_MIN is before the vector and is used to
|
||||||
// represent a 'bx value on the select input.
|
// represent a 'bx value on the select input.
|
||||||
tmp = INT_MIN;
|
tmp = INT_MIN;
|
||||||
// We need a new .part/v that knows if the index is signed.
|
vector4_to_value(bit, tmp, is_signed_);
|
||||||
// For now this will work for a normal integer value.
|
|
||||||
vector4_to_value(bit, tmp, false);
|
|
||||||
if ((int)tmp == base) return false;
|
if ((int)tmp == base) return false;
|
||||||
base = tmp;
|
base = tmp;
|
||||||
break;
|
break;
|
||||||
|
|
@ -280,8 +278,8 @@ bool vvp_fun_part_var::recv_vec4_(vvp_net_ptr_t port, const vvp_vector4_t&bit,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
vvp_fun_part_var_sa::vvp_fun_part_var_sa(unsigned w)
|
vvp_fun_part_var_sa::vvp_fun_part_var_sa(unsigned w, bool is_signed)
|
||||||
: vvp_fun_part_var(w), base_(0)
|
: vvp_fun_part_var(w, is_signed), base_(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -320,8 +318,8 @@ struct vvp_fun_part_var_state_s {
|
||||||
vvp_vector4_t ref;
|
vvp_vector4_t ref;
|
||||||
};
|
};
|
||||||
|
|
||||||
vvp_fun_part_var_aa::vvp_fun_part_var_aa(unsigned w)
|
vvp_fun_part_var_aa::vvp_fun_part_var_aa(unsigned w, bool is_signed)
|
||||||
: vvp_fun_part_var(w)
|
: vvp_fun_part_var(w, is_signed)
|
||||||
{
|
{
|
||||||
context_scope_ = vpip_peek_context_scope();
|
context_scope_ = vpip_peek_context_scope();
|
||||||
context_idx_ = vpip_add_item_to_context(this, context_scope_);
|
context_idx_ = vpip_add_item_to_context(this, context_scope_);
|
||||||
|
|
@ -436,13 +434,13 @@ void compile_part_select_pv(char*label, char*source,
|
||||||
}
|
}
|
||||||
|
|
||||||
void compile_part_select_var(char*label, char*source, char*var,
|
void compile_part_select_var(char*label, char*source, char*var,
|
||||||
unsigned wid)
|
unsigned wid, bool is_signed)
|
||||||
{
|
{
|
||||||
vvp_fun_part_var*fun = 0;
|
vvp_fun_part_var*fun = 0;
|
||||||
if (vpip_peek_current_scope()->is_automatic) {
|
if (vpip_peek_current_scope()->is_automatic) {
|
||||||
fun = new vvp_fun_part_var_aa(wid);
|
fun = new vvp_fun_part_var_aa(wid, is_signed);
|
||||||
} else {
|
} else {
|
||||||
fun = new vvp_fun_part_var_sa(wid);
|
fun = new vvp_fun_part_var_sa(wid, is_signed);
|
||||||
}
|
}
|
||||||
vvp_net_t*net = new vvp_net_t;
|
vvp_net_t*net = new vvp_net_t;
|
||||||
net->fun = fun;
|
net->fun = fun;
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ class vvp_fun_part_pv : public vvp_net_fun_t {
|
||||||
class vvp_fun_part_var : public vvp_net_fun_t {
|
class vvp_fun_part_var : public vvp_net_fun_t {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit vvp_fun_part_var(unsigned wid);
|
explicit vvp_fun_part_var(unsigned wid, bool is_signed);
|
||||||
~vvp_fun_part_var();
|
~vvp_fun_part_var();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -134,6 +134,7 @@ class vvp_fun_part_var : public vvp_net_fun_t {
|
||||||
vvp_vector4_t&ref);
|
vvp_vector4_t&ref);
|
||||||
|
|
||||||
unsigned wid_;
|
unsigned wid_;
|
||||||
|
bool is_signed_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -142,7 +143,7 @@ class vvp_fun_part_var : public vvp_net_fun_t {
|
||||||
class vvp_fun_part_var_sa : public vvp_fun_part_var {
|
class vvp_fun_part_var_sa : public vvp_fun_part_var {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit vvp_fun_part_var_sa(unsigned wid);
|
explicit vvp_fun_part_var_sa(unsigned wid, bool is_signed);
|
||||||
~vvp_fun_part_var_sa();
|
~vvp_fun_part_var_sa();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -166,7 +167,7 @@ class vvp_fun_part_var_sa : public vvp_fun_part_var {
|
||||||
class vvp_fun_part_var_aa : public vvp_fun_part_var, public automatic_hooks_s {
|
class vvp_fun_part_var_aa : public vvp_fun_part_var, public automatic_hooks_s {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit vvp_fun_part_var_aa(unsigned wid);
|
explicit vvp_fun_part_var_aa(unsigned wid, bool is_signed);
|
||||||
~vvp_fun_part_var_aa();
|
~vvp_fun_part_var_aa();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue