From 74ff44314e5451c402e3aba3e9402c4c8c47639e Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Mon, 9 Sep 2019 21:39:35 +0100 Subject: [PATCH] Add new %cast/vec4/str instruction to vvp. --- vvp/codes.h | 3 ++- vvp/compile.cc | 3 ++- vvp/opcodes.txt | 8 +++++++- vvp/vthread.cc | 35 ++++++++++++++++++++++++++++++++++- 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/vvp/codes.h b/vvp/codes.h index 2b3e44cb2..f942b4583 100644 --- a/vvp/codes.h +++ b/vvp/codes.h @@ -1,7 +1,7 @@ #ifndef IVL_codes_H #define IVL_codes_H /* - * Copyright (c) 2001-2017 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-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 @@ -66,6 +66,7 @@ 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_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); extern bool of_CMPINE(vthread_t thr, vvp_code_t code); diff --git a/vvp/compile.cc b/vvp/compile.cc index 5e1cdd59a..a1c06407f 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2018 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-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 @@ -117,6 +117,7 @@ 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/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} }, { "%cmp/ne", of_CMPNE, 0, {OA_NONE, OA_NONE, OA_NONE} }, diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index fdc513c17..1ae454bb8 100644 --- a/vvp/opcodes.txt +++ b/vvp/opcodes.txt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2017 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2019 Stephen Williams (steve@icarus.com) * */ @@ -258,6 +258,12 @@ value stack. Pop a value from the vec4 stack, convert it using Verilog rules to a vector2 (binary) value, and push the result. +* %cast/vec4/str + +Pop a value from the string stack, convert it to a vector that is +bits wide, and push the result to the vec4 stack. If the string does not +fit exactly in bits, print an error message and stop the simulation. + * %cmp/s * %cmp/u * %cmp/e diff --git a/vvp/vthread.cc b/vvp/vthread.cc index fd5d4f56c..7cc937674 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2018 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-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 @@ -1547,6 +1547,39 @@ bool of_CAST2(vthread_t thr, vvp_code_t) return true; } +/* + * %cast/vec4/str + */ +bool of_CAST_VEC4_STR(vthread_t thr, vvp_code_t cp) +{ + unsigned wid = cp->number; + string str = thr->pop_str(); + + vvp_vector4_t vec(wid, BIT4_0); + + if (wid != 8*str.length()) { + cerr << "VVP error: size mismatch when casting string to vector." << endl; + thr->push_vec4(vec); + schedule_stop(0); + return false; + } + + unsigned sdx = 0; + unsigned vdx = wid; + while (vdx > 0) { + char ch = str[sdx++]; + vdx -= 8; + for (unsigned bdx = 0; bdx < 8; bdx += 1) { + if (ch & 1) + vec.set_bit(vdx+bdx, BIT4_1); + ch >>= 1; + } + } + + thr->push_vec4(vec); + return true; +} + static void do_CMPE(vthread_t thr, const vvp_vector4_t&lval, const vvp_vector4_t&rval) { assert(rval.size() == lval.size());