From 1aa22735ceb7e078b603388ea5ba5a5917d4defe Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Wed, 11 Sep 2019 21:56:27 +0100 Subject: [PATCH] Add new %cast/vec2/dar and %cast/vec4/dar instructions to vvp. --- vvp/codes.h | 2 ++ vvp/compile.cc | 2 ++ vvp/opcodes.txt | 14 ++++++++ vvp/vthread.cc | 37 +++++++++++++++++++ vvp/vvp_darray.cc | 92 ++++++++++++++++++++++++++++++++++++++++++++++- vvp/vvp_darray.h | 8 ++++- 6 files changed, 153 insertions(+), 2 deletions(-) diff --git a/vvp/codes.h b/vvp/codes.h index f942b4583..c07e3fe35 100644 --- a/vvp/codes.h +++ b/vvp/codes.h @@ -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_WR(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_CMPE(vthread_t thr, vvp_code_t code); extern bool of_CMPIE(vthread_t thr, vvp_code_t code); diff --git a/vvp/compile.cc b/vvp/compile.cc index a1c06407f..bf4af8a2e 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -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/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} }, + { "%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} }, { "%cast2", of_CAST2, 0, {OA_NONE, OA_NONE, OA_NONE} }, { "%cmp/e", of_CMPE, 0, {OA_NONE, OA_NONE, OA_NONE} }, diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index 1ae454bb8..c7b2baf50 100644 --- a/vvp/opcodes.txt +++ b/vvp/opcodes.txt @@ -258,6 +258,20 @@ value stack. Pop a value from the vec4 stack, convert it using Verilog rules to a vector2 (binary) value, and push the result. +* %cast/vec2/dar + +Pop a dynamic array value from the object stack, convert it to a 2-state +vector that is bits wide, and push the result to the vec4 stack. +If the dynamic array does not fit exactly in bits, print an error +message and stop the simulation. + +* %cast/vec4/dar + +Pop a dynamic array value from the object stack, convert it to a 4-state +vector that is bits wide, and push the result to the vec4 stack. +If the dynamic array does not fit exactly in bits, print an error +message and stop the simulation. + * %cast/vec4/str Pop a value from the string stack, convert it to a vector that is diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 7cc937674..2051b1176 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -1547,6 +1547,43 @@ bool of_CAST2(vthread_t thr, vvp_code_t) 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(); + 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 + */ +bool of_CAST_VEC2_DAR(vthread_t thr, vvp_code_t cp) +{ + return do_cast_vec_dar(thr, cp, false); +} + +/* + * %cast/vec4/dar + */ +bool of_CAST_VEC4_DAR(vthread_t thr, vvp_code_t cp) +{ + return do_cast_vec_dar(thr, cp, true); +} + /* * %cast/vec4/str */ diff --git a/vvp/vvp_darray.cc b/vvp/vvp_darray.cc index 94e940f45..39222d226 100644 --- a/vvp/vvp_darray.cc +++ b/vvp/vvp_darray.cc @@ -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 * 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; } +vvp_vector4_t vvp_darray::get_bitstream(bool) +{ + cerr << "XXXX get_bitstream() not implemented for " << typeid(*this).name() << endl; + return vvp_vector4_t(); +} + template vvp_darray_atom::~vvp_darray_atom() { } @@ -116,6 +122,27 @@ template void vvp_darray_atom::shallow_copy(const vvp_object* array_[idx] = that->array_[idx]; } +template vvp_vector4_t vvp_darray_atom::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; template class vvp_darray_atom; template class vvp_darray_atom; @@ -165,6 +192,25 @@ void vvp_darray_vec4::shallow_copy(const vvp_object*obj) 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() { } @@ -208,6 +254,24 @@ void vvp_darray_vec2::shallow_copy(const vvp_object*obj) 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() { } @@ -280,6 +344,32 @@ void vvp_darray_real::shallow_copy(const vvp_object*obj) 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() { } diff --git a/vvp/vvp_darray.h b/vvp/vvp_darray.h index 2ad520222..12760791c 100644 --- a/vvp/vvp_darray.h +++ b/vvp/vvp_darray.h @@ -1,7 +1,7 @@ #ifndef 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 * 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 shallow_copy(const vvp_object*obj); + + virtual vvp_vector4_t get_bitstream(bool as_vec4); }; template class vvp_darray_atom : public vvp_darray { @@ -58,6 +60,7 @@ template class vvp_darray_atom : public vvp_darray { void set_word(unsigned adr, const vvp_vector4_t&value); void get_word(unsigned adr, vvp_vector4_t&value); void shallow_copy(const vvp_object*obj); + vvp_vector4_t get_bitstream(bool as_vec4); private: std::vector array_; @@ -74,6 +77,7 @@ class vvp_darray_vec4 : public vvp_darray { void set_word(unsigned adr, const vvp_vector4_t&value); void get_word(unsigned adr, vvp_vector4_t&value); void shallow_copy(const vvp_object*obj); + vvp_vector4_t get_bitstream(bool as_vec4); private: std::vector array_; @@ -91,6 +95,7 @@ class vvp_darray_vec2 : public vvp_darray { void set_word(unsigned adr, const vvp_vector4_t&value); void get_word(unsigned adr, vvp_vector4_t&value); void shallow_copy(const vvp_object*obj); + vvp_vector4_t get_bitstream(bool as_vec4); private: std::vector array_; @@ -107,6 +112,7 @@ class vvp_darray_real : public vvp_darray { void set_word(unsigned adr, double value); void get_word(unsigned adr, double&value); void shallow_copy(const vvp_object*obj); + vvp_vector4_t get_bitstream(bool as_vec4); private: std::vector array_;