From 1b7cd5c2373ac74a8ee1aa5070093f225d8c7025 Mon Sep 17 00:00:00 2001 From: Cary R Date: Sun, 19 Jul 2020 21:34:04 -0700 Subject: [PATCH] Add initial support for real queues --- tgt-vvp/eval_real.c | 25 +++++++++++- vvp/codes.h | 4 +- vvp/compile.cc | 10 +++-- vvp/opcodes.txt | 6 ++- vvp/vthread.cc | 69 +++++++++++++++++++++++++++++-- vvp/vvp_darray.cc | 99 ++++++++++++++++++++++++++++----------------- vvp/vvp_darray.h | 44 +++++++++++++------- 7 files changed, 193 insertions(+), 64 deletions(-) diff --git a/tgt-vvp/eval_real.c b/tgt-vvp/eval_real.c index f42cf9b23..b6d5267ba 100644 --- a/tgt-vvp/eval_real.c +++ b/tgt-vvp/eval_real.c @@ -260,12 +260,28 @@ static void draw_select_real(ivl_expr_t expr) /* Assume the sub-expression is a signal */ ivl_signal_t sig = ivl_expr_signal(sube); - assert(ivl_signal_data_type(sig) == IVL_VT_DARRAY); + assert(ivl_signal_data_type(sig) == IVL_VT_DARRAY || ivl_signal_data_type(sig) == IVL_VT_QUEUE); draw_eval_expr_into_integer(shift, 3); fprintf(vvp_out, " %%load/dar/r v%p_0;\n", sig); } +static void real_ex_pop(ivl_expr_t expr) +{ + const char*fb; + ivl_expr_t arg; + + if (strcmp(ivl_expr_name(expr), "$ivl_darray_method$pop_back")==0) + fb = "b"; + else + fb = "f"; + + arg = ivl_expr_parm(expr, 0); + assert(ivl_expr_type(arg) == IVL_EX_SIGNAL); + + fprintf(vvp_out, " %%qpop/%s/real v%p_0;\n", fb, ivl_expr_signal(arg)); +} + static void draw_sfunc_real(ivl_expr_t expr) { switch (ivl_expr_value(expr)) { @@ -511,7 +527,12 @@ void draw_eval_real(ivl_expr_t expr) break; case IVL_EX_SFUNC: - draw_sfunc_real(expr); + if (strcmp(ivl_expr_name(expr), "$ivl_darray_method$pop_back")==0) + real_ex_pop(expr); + else if (strcmp(ivl_expr_name(expr), "$ivl_darray_method$pop_front")==0) + real_ex_pop(expr); + else + draw_sfunc_real(expr); break; case IVL_EX_SIGNAL: diff --git a/vvp/codes.h b/vvp/codes.h index c07e3fe35..200c6bfbd 100644 --- a/vvp/codes.h +++ b/vvp/codes.h @@ -1,7 +1,7 @@ #ifndef IVL_codes_H #define IVL_codes_H /* - * Copyright (c) 2001-2019 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2020 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 @@ -187,8 +187,10 @@ extern bool of_POP_VEC4(vthread_t thr, vvp_code_t code); extern bool of_POW(vthread_t thr, vvp_code_t code); extern bool of_POW_S(vthread_t thr, vvp_code_t code); extern bool of_POW_WR(vthread_t thr, vvp_code_t code); +extern bool of_QPOP_B_REAL(vthread_t thr, vvp_code_t code); extern bool of_QPOP_B_STR(vthread_t thr, vvp_code_t code); extern bool of_QPOP_B_V(vthread_t thr, vvp_code_t code); +extern bool of_QPOP_F_REAL(vthread_t thr, vvp_code_t code); extern bool of_QPOP_F_STR(vthread_t thr, vvp_code_t code); extern bool of_QPOP_F_V(vthread_t thr, vvp_code_t code); extern bool of_PROP_OBJ(vthread_t thr, vvp_code_t code); diff --git a/vvp/compile.cc b/vvp/compile.cc index 512c564d8..4225d0433 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -247,10 +247,12 @@ static const struct opcode_table_s opcode_table[] = { { "%pushi/vec4",of_PUSHI_VEC4,3,{OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%pushv/str", of_PUSHV_STR, 0,{OA_NONE, OA_NONE, OA_NONE} }, { "%putc/str/vec4",of_PUTC_STR_VEC4,2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} }, - { "%qpop/b/str",of_QPOP_B_STR,1,{OA_FUNC_PTR,OA_NONE, OA_NONE} }, - { "%qpop/b/v", of_QPOP_B_V, 1,{OA_FUNC_PTR,OA_NONE, OA_BIT2} }, - { "%qpop/f/str",of_QPOP_F_STR,1,{OA_FUNC_PTR,OA_NONE, OA_NONE} }, - { "%qpop/f/v", of_QPOP_F_V, 1,{OA_FUNC_PTR,OA_NONE, OA_BIT2} }, + { "%qpop/b/real",of_QPOP_B_REAL,1,{OA_FUNC_PTR,OA_NONE,OA_NONE} }, + { "%qpop/b/str", of_QPOP_B_STR, 1,{OA_FUNC_PTR,OA_NONE,OA_NONE} }, + { "%qpop/b/v", of_QPOP_B_V, 1,{OA_FUNC_PTR,OA_NONE,OA_BIT2} }, + { "%qpop/f/real",of_QPOP_F_REAL,1,{OA_FUNC_PTR,OA_NONE,OA_NONE} }, + { "%qpop/f/str", of_QPOP_F_STR, 1,{OA_FUNC_PTR,OA_NONE,OA_NONE} }, + { "%qpop/f/v", of_QPOP_F_V, 1,{OA_FUNC_PTR,OA_NONE,OA_BIT2} }, { "%release/net",of_RELEASE_NET,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} }, { "%release/reg",of_RELEASE_REG,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} }, { "%release/wr", of_RELEASE_WR, 2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} }, diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index 02f4ba7a7..96d4b872c 100644 --- a/vvp/opcodes.txt +++ b/vvp/opcodes.txt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2019 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2020 Stephen Williams (steve@icarus.com) * */ @@ -1005,6 +1005,10 @@ character of the string variable at . This is basically an implementation of .putc(, ) where is the 8bit vector popped from the stack. +* %qpop/b/real +* %qpop/f/real +* %qpop/b/str +* %qpop/f/str * %qpop/b/v * %qpop/f/v diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 413352b96..43123aea8 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -5012,6 +5012,30 @@ bool of_PUTC_STR_VEC4(vthread_t thr, vvp_code_t cp) return true; } +/* + * %qpop/b/real + */ +bool of_QPOP_B_REAL(vthread_t thr, vvp_code_t cp) +{ + vvp_net_t*net = cp->net; + + vvp_queue*dqueue = get_queue_object(thr, net); + assert(dqueue); + + size_t size = dqueue->get_size(); + assert(size > 0); + + double value; + dqueue->get_word(size-1, value); + dqueue->pop_back(); + + thr->push_real(value); + return true; +} + +/* + * %qpop/b/str + */ bool of_QPOP_B_STR(vthread_t thr, vvp_code_t cp) { vvp_net_t*net = cp->net; @@ -5051,6 +5075,27 @@ bool of_QPOP_B_V(vthread_t thr, vvp_code_t cp) return true; } +/* + * %qpop/f/real + */ +bool of_QPOP_F_REAL(vthread_t thr, vvp_code_t cp) +{ + vvp_net_t*net = cp->net; + + vvp_queue*dqueue = get_queue_object(thr, net); + assert(dqueue); + + double value; + dqueue->get_word(0, value); + dqueue->pop_front(); + + thr->push_real(value); + return true; +} + +/* + * %qpop/f/str + */ bool of_QPOP_F_STR(vthread_t thr, vvp_code_t cp) { vvp_net_t*net = cp->net; @@ -5704,9 +5749,17 @@ bool of_STORE_PROP_V(vthread_t thr, vvp_code_t cp) /* * %store/qb/r , */ -bool of_STORE_QB_R(vthread_t, vvp_code_t) +bool of_STORE_QB_R(vthread_t thr, vvp_code_t cp) { - fprintf(stderr, "XXXX %%store/qb/r NOT IMPLEMENTED\n"); + // Pop the double to be stored... + double value = thr->pop_real(); + + vvp_net_t*net = cp->net; + unsigned max_size = thr->words[cp->bit_idx[0]].w_int; + vvp_queue*dqueue = get_queue_object(thr, net); + + assert(dqueue); + dqueue->push_back(value, max_size); return true; } @@ -5752,9 +5805,17 @@ bool of_STORE_QB_V(vthread_t thr, vvp_code_t cp) /* * %store/qf/r , */ -bool of_STORE_QF_R(vthread_t, vvp_code_t) +bool of_STORE_QF_R(vthread_t thr, vvp_code_t cp) { - fprintf(stderr, "XXXX %%store/qf/r NOT IMPLEMENTED\n"); + // Pop the double to be stored... + double value = thr->pop_real(); + + vvp_net_t*net = cp->net; + unsigned max_size = thr->words[cp->bit_idx[0]].w_int; + vvp_queue*dqueue = get_queue_object(thr, net); + + assert(dqueue); + dqueue->push_front(value, max_size); return true; } diff --git a/vvp/vvp_darray.cc b/vvp/vvp_darray.cc index cdeb247d7..78c58188c 100644 --- a/vvp/vvp_darray.cc +++ b/vvp/vvp_darray.cc @@ -440,13 +440,61 @@ void vvp_queue::push_front(const string&, unsigned) cerr << "XXXX push_front(string) not implemented for " << typeid(*this).name() << endl; } -vvp_queue_string::~vvp_queue_string() +vvp_queue_real::~vvp_queue_real() { } -size_t vvp_queue_string::get_size() const +void vvp_queue_real::set_word(unsigned adr, double value) +{ + if (adr >= array_.size()) + return; + + list::iterator cur = array_.begin(); + while (adr > 0) { + ++ cur; + adr -= 1; + } + + *cur = value; +} + +void vvp_queue_real::get_word(unsigned adr, double&value) +{ + if (adr >= array_.size()) { + value = 0.0; + return; + } + + list::const_iterator cur = array_.begin(); + while (adr > 0) { + ++ cur; + adr -= 1; + } + + value = *cur; +} + +void vvp_queue_real::push_back(double value, unsigned max_size) +{ + if (!max_size || (array_.size() < max_size)) array_.push_back(value); + else cerr << "Warning: value " << value + << " was not added to the end of already full sized (" + << max_size << ") queue." << endl; +} + +void vvp_queue_real::push_front(double value, unsigned max_size) +{ + if (max_size && (array_.size() == max_size)) { + cerr << "Warning: value " << array_.back() + << " was removed from already full sized (" + << max_size << ") queue." << endl; + array_.pop_back(); + } + array_.push_front(value); +} + +vvp_queue_string::~vvp_queue_string() { - return array_.size(); } void vvp_queue_string::set_word(unsigned adr, const string&value) @@ -479,15 +527,15 @@ void vvp_queue_string::get_word(unsigned adr, string&value) value = *cur; } -void vvp_queue_string::push_back(const string&val, unsigned max_size) +void vvp_queue_string::push_back(const string&value, unsigned max_size) { - if (!max_size || (array_.size() < max_size)) array_.push_back(val); - else cerr << "Warning: value \"" << val + if (!max_size || (array_.size() < max_size)) array_.push_back(value); + else cerr << "Warning: value \"" << value << "\" was not added to the end of already full sized (" << max_size << ") queue." << endl; } -void vvp_queue_string::push_front(const string&val, unsigned max_size) +void vvp_queue_string::push_front(const string&value, unsigned max_size) { if (max_size && (array_.size() == max_size)) { cerr << "Warning: value \"" << array_.back() @@ -495,28 +543,13 @@ void vvp_queue_string::push_front(const string&val, unsigned max_size) << max_size << ") queue." << endl; array_.pop_back(); } - array_.push_front(val); -} - -void vvp_queue_string::pop_back(void) -{ - array_.pop_back(); -} - -void vvp_queue_string::pop_front(void) -{ - array_.pop_front(); + array_.push_front(value); } vvp_queue_vec4::~vvp_queue_vec4() { } -size_t vvp_queue_vec4::get_size() const -{ - return array_.size(); -} - void vvp_queue_vec4::set_word(unsigned adr, const vvp_vector4_t&value) { if (adr >= array_.size()) @@ -547,15 +580,15 @@ void vvp_queue_vec4::get_word(unsigned adr, vvp_vector4_t&value) value = *cur; } -void vvp_queue_vec4::push_back(const vvp_vector4_t&val, unsigned max_size) +void vvp_queue_vec4::push_back(const vvp_vector4_t&value, unsigned max_size) { - if (!max_size || (array_.size() < max_size)) array_.push_back(val); - else cerr << "Warning: value " << val + if (!max_size || (array_.size() < max_size)) array_.push_back(value); + else cerr << "Warning: value " << value << " was not added to the end of already full sized (" << max_size << ") queue." << endl; } -void vvp_queue_vec4::push_front(const vvp_vector4_t&val, unsigned max_size) +void vvp_queue_vec4::push_front(const vvp_vector4_t&value, unsigned max_size) { if (max_size && (array_.size() == max_size)) { cerr << "Warning: value " << array_.back() @@ -563,15 +596,5 @@ void vvp_queue_vec4::push_front(const vvp_vector4_t&val, unsigned max_size) << max_size << ") queue." << endl; array_.pop_back(); } - array_.push_front(val); -} - -void vvp_queue_vec4::pop_back(void) -{ - array_.pop_back(); -} - -void vvp_queue_vec4::pop_front(void) -{ - array_.pop_front(); + array_.push_front(value); } diff --git a/vvp/vvp_darray.h b/vvp/vvp_darray.h index 584c84894..881691550 100644 --- a/vvp/vvp_darray.h +++ b/vvp/vvp_darray.h @@ -167,39 +167,55 @@ class vvp_queue : public vvp_darray { virtual void pop_front(void)=0; }; -class vvp_queue_vec4 : public vvp_queue { +class vvp_queue_real : public vvp_queue { public: - ~vvp_queue_vec4(); + ~vvp_queue_real(); - size_t get_size(void) const; - void set_word(unsigned adr, const vvp_vector4_t&value); - void get_word(unsigned adr, vvp_vector4_t&value); - void push_back(const vvp_vector4_t&value, unsigned max_size); - void push_front(const vvp_vector4_t&value, unsigned max_size); - void pop_back(void); - void pop_front(void); + size_t get_size(void) const { return array_.size(); }; + void set_word(unsigned adr, double value); + void get_word(unsigned adr, double&value); + void push_back(double value, unsigned max_size); + void push_front(double value, unsigned max_size); + void pop_back(void) { array_.pop_back(); }; + void pop_front(void) { array_.pop_front(); }; private: - std::list array_; + std::list array_; }; - class vvp_queue_string : public vvp_queue { public: ~vvp_queue_string(); - size_t get_size(void) const; + size_t get_size(void) const { return array_.size(); }; void set_word(unsigned adr, const std::string&value); void get_word(unsigned adr, std::string&value); void push_back(const std::string&value, unsigned max_size); void push_front(const std::string&value, unsigned max_size); - void pop_back(void); - void pop_front(void); + void pop_back(void) { array_.pop_back(); }; + void pop_front(void) { array_.pop_front(); }; private: std::list array_; }; +class vvp_queue_vec4 : public vvp_queue { + + public: + ~vvp_queue_vec4(); + + size_t get_size(void) const { return array_.size(); }; + void set_word(unsigned adr, const vvp_vector4_t&value); + void get_word(unsigned adr, vvp_vector4_t&value); + void push_back(const vvp_vector4_t&value, unsigned max_size); + void push_front(const vvp_vector4_t&value, unsigned max_size); + void pop_back(void) { array_.pop_back(); }; + void pop_front(void) { array_.pop_front(); }; + + private: + std::list array_; +}; + #endif /* IVL_vvp_darray_H */