Add new %cast/vec2/dar and %cast/vec4/dar instructions to vvp.

This commit is contained in:
Martin Whitaker 2019-09-11 21:56:27 +01:00
parent 74ff44314e
commit 1aa22735ce
6 changed files with 153 additions and 2 deletions

View File

@ -66,6 +66,8 @@ extern bool of_CASSIGN_VEC4(vthread_t thr, vvp_code_t code);
extern bool of_CASSIGN_VEC4_OFF(vthread_t thr, vvp_code_t code); extern bool of_CASSIGN_VEC4_OFF(vthread_t thr, vvp_code_t code);
extern bool of_CASSIGN_WR(vthread_t thr, vvp_code_t code); extern bool of_CASSIGN_WR(vthread_t thr, vvp_code_t code);
extern bool of_CAST2(vthread_t thr, vvp_code_t code); extern bool of_CAST2(vthread_t thr, vvp_code_t code);
extern bool of_CAST_VEC2_DAR(vthread_t thr, vvp_code_t code);
extern bool of_CAST_VEC4_DAR(vthread_t thr, vvp_code_t code);
extern bool of_CAST_VEC4_STR(vthread_t thr, vvp_code_t code); extern bool of_CAST_VEC4_STR(vthread_t thr, vvp_code_t code);
extern bool of_CMPE(vthread_t thr, vvp_code_t code); extern bool of_CMPE(vthread_t thr, vvp_code_t code);
extern bool of_CMPIE(vthread_t thr, vvp_code_t code); extern bool of_CMPIE(vthread_t thr, vvp_code_t code);

View File

@ -117,6 +117,8 @@ static const struct opcode_table_s opcode_table[] = {
{ "%cassign/vec4", of_CASSIGN_VEC4, 1,{OA_FUNC_PTR,OA_NONE, OA_NONE} }, { "%cassign/vec4", of_CASSIGN_VEC4, 1,{OA_FUNC_PTR,OA_NONE, OA_NONE} },
{ "%cassign/vec4/off",of_CASSIGN_VEC4_OFF,2,{OA_FUNC_PTR,OA_BIT1, OA_NONE} }, { "%cassign/vec4/off",of_CASSIGN_VEC4_OFF,2,{OA_FUNC_PTR,OA_BIT1, OA_NONE} },
{ "%cassign/wr", of_CASSIGN_WR, 1,{OA_FUNC_PTR,OA_NONE, OA_NONE} }, { "%cassign/wr", of_CASSIGN_WR, 1,{OA_FUNC_PTR,OA_NONE, OA_NONE} },
{ "%cast/vec2/dar", of_CAST_VEC2_DAR, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%cast/vec4/dar", of_CAST_VEC4_DAR, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%cast/vec4/str", of_CAST_VEC4_STR, 1, {OA_NUMBER, OA_NONE, OA_NONE} }, { "%cast/vec4/str", of_CAST_VEC4_STR, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%cast2", of_CAST2, 0, {OA_NONE, OA_NONE, OA_NONE} }, { "%cast2", of_CAST2, 0, {OA_NONE, OA_NONE, OA_NONE} },
{ "%cmp/e", of_CMPE, 0, {OA_NONE, OA_NONE, OA_NONE} }, { "%cmp/e", of_CMPE, 0, {OA_NONE, OA_NONE, OA_NONE} },

View File

@ -258,6 +258,20 @@ value stack.
Pop a value from the vec4 stack, convert it using Verilog rules to a Pop a value from the vec4 stack, convert it using Verilog rules to a
vector2 (binary) value, and push the result. vector2 (binary) value, and push the result.
* %cast/vec2/dar <wid>
Pop a dynamic array value from the object stack, convert it to a 2-state
vector that is <wid> bits wide, and push the result to the vec4 stack.
If the dynamic array does not fit exactly in <wid> bits, print an error
message and stop the simulation.
* %cast/vec4/dar <wid>
Pop a dynamic array value from the object stack, convert it to a 4-state
vector that is <wid> bits wide, and push the result to the vec4 stack.
If the dynamic array does not fit exactly in <wid> bits, print an error
message and stop the simulation.
* %cast/vec4/str <wid> * %cast/vec4/str <wid>
Pop a value from the string stack, convert it to a vector that is <wid> Pop a value from the string stack, convert it to a vector that is <wid>

View File

@ -1547,6 +1547,43 @@ bool of_CAST2(vthread_t thr, vvp_code_t)
return true; return true;
} }
bool do_cast_vec_dar(vthread_t thr, vvp_code_t cp, bool as_vec4)
{
unsigned wid = cp->number;
vvp_object_t obj;
thr->pop_object(obj);
vvp_darray*darray = obj.peek<vvp_darray>();
assert(darray);
vvp_vector4_t vec = darray->get_bitstream(as_vec4);
if (vec.size() != wid) {
cerr << "VVP error: size mismatch when casting dynamic array to vector." << endl;
thr->push_vec4(vvp_vector4_t(wid));
schedule_stop(0);
return false;
}
thr->push_vec4(vec);
return true;
}
/*
* %cast/vec2/dar <wid>
*/
bool of_CAST_VEC2_DAR(vthread_t thr, vvp_code_t cp)
{
return do_cast_vec_dar(thr, cp, false);
}
/*
* %cast/vec4/dar <wid>
*/
bool of_CAST_VEC4_DAR(vthread_t thr, vvp_code_t cp)
{
return do_cast_vec_dar(thr, cp, true);
}
/* /*
* %cast/vec4/str <wid> * %cast/vec4/str <wid>
*/ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012-2015 Stephen Williams (steve@icarus.com) * Copyright (c) 2012-2019 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
@ -72,6 +72,12 @@ void vvp_darray::shallow_copy(const vvp_object*)
cerr << "XXXX shallow_copy(vvp_object_t) not implemented for " << typeid(*this).name() << endl; cerr << "XXXX shallow_copy(vvp_object_t) not implemented for " << typeid(*this).name() << endl;
} }
vvp_vector4_t vvp_darray::get_bitstream(bool)
{
cerr << "XXXX get_bitstream() not implemented for " << typeid(*this).name() << endl;
return vvp_vector4_t();
}
template <class TYPE> vvp_darray_atom<TYPE>::~vvp_darray_atom() template <class TYPE> vvp_darray_atom<TYPE>::~vvp_darray_atom()
{ {
} }
@ -116,6 +122,27 @@ template <class TYPE> void vvp_darray_atom<TYPE>::shallow_copy(const vvp_object*
array_[idx] = that->array_[idx]; array_[idx] = that->array_[idx];
} }
template <class TYPE> vvp_vector4_t vvp_darray_atom<TYPE>::get_bitstream(bool)
{
const unsigned word_wid = sizeof(TYPE) * 8;
vvp_vector4_t vec(array_.size() * word_wid, BIT4_0);
unsigned adx = 0;
unsigned vdx = vec.size();
while (vdx > 0) {
TYPE word = array_[adx++];
vdx -= word_wid;
for (unsigned bdx = 0; bdx < word_wid; bdx += 1) {
if (word & 1)
vec.set_bit(vdx+bdx, BIT4_1);
word >>= 1;
}
}
return vec;
}
template class vvp_darray_atom<uint8_t>; template class vvp_darray_atom<uint8_t>;
template class vvp_darray_atom<uint16_t>; template class vvp_darray_atom<uint16_t>;
template class vvp_darray_atom<uint32_t>; template class vvp_darray_atom<uint32_t>;
@ -165,6 +192,25 @@ void vvp_darray_vec4::shallow_copy(const vvp_object*obj)
array_[idx] = that->array_[idx]; array_[idx] = that->array_[idx];
} }
vvp_vector4_t vvp_darray_vec4::get_bitstream(bool as_vec4)
{
vvp_vector4_t vec(array_.size() * word_wid_, BIT4_0);
unsigned adx = 0;
unsigned vdx = vec.size();
while (vdx > 0) {
vdx -= word_wid_;
for (unsigned bdx = 0; bdx < word_wid_; bdx += 1) {
vvp_bit4_t bit = array_[adx].value(bdx);
if (as_vec4 || (bit == BIT4_1))
vec.set_bit(vdx+bdx, bit);
}
adx++;
}
return vec;
}
vvp_darray_vec2::~vvp_darray_vec2() vvp_darray_vec2::~vvp_darray_vec2()
{ {
} }
@ -208,6 +254,24 @@ void vvp_darray_vec2::shallow_copy(const vvp_object*obj)
array_[idx] = that->array_[idx]; array_[idx] = that->array_[idx];
} }
vvp_vector4_t vvp_darray_vec2::get_bitstream(bool)
{
vvp_vector4_t vec(array_.size() * word_wid_, BIT4_0);
unsigned adx = 0;
unsigned vdx = vec.size();
while (vdx > 0) {
vdx -= word_wid_;
for (unsigned bdx = 0; bdx < word_wid_; bdx += 1) {
if (array_[adx].value(bdx))
vec.set_bit(vdx+bdx, BIT4_1);
}
adx++;
}
return vec;
}
vvp_darray_object::~vvp_darray_object() vvp_darray_object::~vvp_darray_object()
{ {
} }
@ -280,6 +344,32 @@ void vvp_darray_real::shallow_copy(const vvp_object*obj)
array_[idx] = that->array_[idx]; array_[idx] = that->array_[idx];
} }
vvp_vector4_t vvp_darray_real::get_bitstream(bool)
{
const unsigned word_wid = sizeof(double) * 8;
assert(word_wid == 64);
vvp_vector4_t vec(array_.size() * word_wid, BIT4_0);
unsigned adx = 0;
unsigned vdx = vec.size();
while (vdx > 0) {
union {
double value;
uint64_t bits;
} word;
word.value = array_[adx++];
vdx -= word_wid;
for (unsigned bdx = 0; bdx < word_wid; bdx += 1) {
if (word.bits & 1)
vec.set_bit(vdx+bdx, BIT4_1);
word.bits >>= 1;
}
}
return vec;
}
vvp_darray_string::~vvp_darray_string() vvp_darray_string::~vvp_darray_string()
{ {
} }

View File

@ -1,7 +1,7 @@
#ifndef IVL_vvp_darray_H #ifndef IVL_vvp_darray_H
#define IVL_vvp_darray_H #define IVL_vvp_darray_H
/* /*
* Copyright (c) 2012-2015 Stephen Williams (steve@icarus.com) * Copyright (c) 2012-2019 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
@ -46,6 +46,8 @@ class vvp_darray : public vvp_object {
virtual void get_word(unsigned adr, vvp_object_t&value); virtual void get_word(unsigned adr, vvp_object_t&value);
virtual void shallow_copy(const vvp_object*obj); virtual void shallow_copy(const vvp_object*obj);
virtual vvp_vector4_t get_bitstream(bool as_vec4);
}; };
template <class TYPE> class vvp_darray_atom : public vvp_darray { template <class TYPE> class vvp_darray_atom : public vvp_darray {
@ -58,6 +60,7 @@ template <class TYPE> class vvp_darray_atom : public vvp_darray {
void set_word(unsigned adr, const vvp_vector4_t&value); void set_word(unsigned adr, const vvp_vector4_t&value);
void get_word(unsigned adr, vvp_vector4_t&value); void get_word(unsigned adr, vvp_vector4_t&value);
void shallow_copy(const vvp_object*obj); void shallow_copy(const vvp_object*obj);
vvp_vector4_t get_bitstream(bool as_vec4);
private: private:
std::vector<TYPE> array_; std::vector<TYPE> array_;
@ -74,6 +77,7 @@ class vvp_darray_vec4 : public vvp_darray {
void set_word(unsigned adr, const vvp_vector4_t&value); void set_word(unsigned adr, const vvp_vector4_t&value);
void get_word(unsigned adr, vvp_vector4_t&value); void get_word(unsigned adr, vvp_vector4_t&value);
void shallow_copy(const vvp_object*obj); void shallow_copy(const vvp_object*obj);
vvp_vector4_t get_bitstream(bool as_vec4);
private: private:
std::vector<vvp_vector4_t> array_; std::vector<vvp_vector4_t> array_;
@ -91,6 +95,7 @@ class vvp_darray_vec2 : public vvp_darray {
void set_word(unsigned adr, const vvp_vector4_t&value); void set_word(unsigned adr, const vvp_vector4_t&value);
void get_word(unsigned adr, vvp_vector4_t&value); void get_word(unsigned adr, vvp_vector4_t&value);
void shallow_copy(const vvp_object*obj); void shallow_copy(const vvp_object*obj);
vvp_vector4_t get_bitstream(bool as_vec4);
private: private:
std::vector<vvp_vector2_t> array_; std::vector<vvp_vector2_t> array_;
@ -107,6 +112,7 @@ class vvp_darray_real : public vvp_darray {
void set_word(unsigned adr, double value); void set_word(unsigned adr, double value);
void get_word(unsigned adr, double&value); void get_word(unsigned adr, double&value);
void shallow_copy(const vvp_object*obj); void shallow_copy(const vvp_object*obj);
vvp_vector4_t get_bitstream(bool as_vec4);
private: private:
std::vector<double> array_; std::vector<double> array_;