[libre-riscv-dev] libre-riscv-dev Digest, Vol 3, Issue 5

lkcl lkcl at libre-riscv.org
Sun Nov 11 05:58:32 GMT 2018


On Sun, Nov 11, 2018 at 3:44 AM Daniel Benusovich
<flyingmonkeys1996 at gmail.com> wrote:
>
> Regarding the unit tests I have many questions!

 i can see :)

> In riscv-tests/rv64ui/sv_addw_elwidth.S the macro "SV_ELWIDTH_TEST"
> calls (among other macros) "SET_SV_MVL", "SET_SV_3CSRS",
> "SET_SV_VL", and, "CLR_SV_CSRS".

 yep.  that sets up the "engine", there's a hardware-macro-loop inside
SV, sits in between the decode phase and the instruction issue phase.
see the sections on mvl and vl in the spec on what they do:
  https://libre-riscv.org/simple_v_extension/specification/#mvl
  https://libre-riscv.org/simple_v_extension/specification/#vl

MVL is basically a hard limit on what VL can be set to.  if you then read this:
 https://www.sigarch.org/simd-instructions-considered-harmful/

ignore the SIMD crud, make a beeline (search the document) for the
word "setvl", that's what the SET_SV_VL macro does.

> I understand the first portion of the macro sets up your test data,
> but, I am confused as to what exactly the macros above do.
> They setup the operations to perform some addition.

 ah, no: they set the parallelism algorithm so that *any* operation
that uses anything to do with the registers programmed by the CSRs
*will* become parallelised (even if it's virtual parallelism).

 in the case of sv_addw_elwidth.S that happens to be x15, x12 and x28.

 now, the reason why immediately after the CSRs are cleared and MVL
and VL are set back to 1 is so that **ONLY** that addw is
parallelised, because that's the operation being tested.

> Clearly they are setting up how the data will be added (x15 and x12 while
> storing the result in x28) but how do the CSR registers affect the results
> of adding the same two values?

 see pseudocode here:
 https://libre-riscv.org/simple_v_extension/specification/#instructions

 you see how the ADD operation goes into a for-loop around VL?  and
how both source registers and destination register are incremented
within that loop?  it means that, thanks to the CSRs, where you see

    ADDW x28, x15, x12

 what ACTUALLY happens is:

 for i in range(3):
     ADDW x(28+i), x(15+i), x(12+i)

 ... ya dig it? :)

> The expected results change while I see wid1/2/3 and isvec1/2/3 changing.

 yes.  ok, so look at the pseudo-code again.  isvec1/2/3 basically
switches off whether the incrementing is enabled or not, for each of
the 3 registers involved.  so, if isvec=False on saaaay.... 28, then
where you see this:

    ADDW x28, x15, x12

 what ACTUALLY happens is:

 for i in range(3):
     ADDW x28, x(15+i), x(12+i)

 and if isvec=false on both x28 and x12, you get:

 for i in range(3):
     ADDW x28, x(15+i), x12

and if it's false on ALL THREE, then you get... uhnn.... this:

    ADDW x28, x15, x12

which is... basically, no looping at all.

> In addition what are the parameters wid1/2/3?

elwidth - element width - is fun.  it says, "hey uhn, you know the
operation's supposed to be 64-bit on this register, right?  well,
actually we're gonna do it as 16-bit.  or 8."

> Do these define the size of the vector?

 it defines the size (bitwidth) of the elements *in* the vector.
it's actually quite involved, i had to write a special section in the
spec:
 https://libre-riscv.org/simple_v_extension/specification/#elwidh

 basically if you think of the register file as a series of *BYTES*
(not 8-byte dwords), elwidth "typecasts" the register file to
different block sizes, in effect.  some c pseudo-code to represent
that is in the spec, i'll duplicate it here:

     typedef union {
        uint8_t  b[8];
        uint16_t s[4];
        uint32_t i[2];
        uint64_t l[1];
    } reg_t;

    // integer table: assume maximum SV 7-bit regfile size
    reg_t int_regfile[128];

so if elwidth is set to 8-bit, you'd use regfile[reg_num].b[0..7].
if a register's CSR elwidth entry is set to 16-bit, you'd use s[0..3],
and so on.


>  IsVec1/2/3 a boolean to tell the processor the registers with data
> to add represent vectors?

 yup, you got it.  more specifically, it says that *specific* register
is to be treated as just a scalar or if it's to be treated as multiple
elements (assuming VL > 1 of course).

> How does VL change the operations to be performed through
> "SET_SV_MVL" and "SET_SV_VL"?

 see the for-loop of the pseudo-code.

>  Is there a place I can go and read about how these values
> in CSR will change the operations?

there's a lovely 15,000 word spec :)

> I have been looking at the RISCV reference card/Manual can see we
? are atomically writing the immediate 2 (3 - 1) to the CSR at
>  0x4f1 ("SET_SV_MVL") and 0x4f0 ("SET_SV_VL")

 yep.  the behaviour of SET_SV_MVL is straightforward enough.  VL had
to be slightly different.  normally you're supposed to return the old
value, however to match the behaviour of RVV i had to make it return
the **NEW** value.

 it's cool.  if you want to actually see what each of these do, you
can look at processor.cc in spike-sv:
 https://git.libre-riscv.org/?p=riscv-isa-sim.git;a=blob;f=riscv/processor.cc;h=0161abec6fd5d85b0c68bd3468aebbad1ab72233;hb=refs/heads/sv

 look for "processor_t::set_csr".


> The composed information for where to find and how to process three
> registers (the sources of data to add and the destination) worth of data
> to 0x4c0 ("SET_SV_3CSRS"/"CLR_SV_CSRS"). Finding the relevant
> data in the manual is a little tough for the section without knowing where to start.

 yep, you're not looking in the manual, you want the SV spec.
basically the CSRs are 64-bit wide (in RV64), and the SV Reg CSR (and
Predicate CSR) table entries have been deliberately kept to 16-bit
wide.

 that way it's possible to fit up to 4 of them into a single CSRRW.

> Also the values of x29 and x30 are changed in some iterations of
> the macro but no changes are made to those particular registers visibly.

 haaa, gotcha :)  this is a key fundamental aspect of SV: redirection.
the goal is, to have up to 128 *actual* registers... yet make *ZERO*
and i do mean *ZERO* changes to the RV Base instruction set.

 that means having a CAM with key="original register" (5 bits) and
value="*ACTUAL* register" (7 bits).  the table's here... damn it's
out-of-date:
  https://libre-riscv.org/simple_v_extension/specification/#regcsrtable


 btw do make sure you put only the version we discussed into
sv_test_macros.h ok?  rename it so it doesn't clash with all the other
cut/paste variants.  then we can go through chopping up the other
versions to match it, ok?


> Are they this affected by the addition when certain CSR values are set?

 yyyyup!  you got it in one.

> Also what is elwidth? I see the guy literally everywhere and have no idea what it means haha.

 shorthand for "element width":
 https://libre-riscv.org/simple_v_extension/specification/#elwidth

> Sorry for all the questions at once I have spent more than a few days
> pouring over the unit test you told me to copy and want to be sure that
> any changes that are made are made with some sort of reason.

 i've been watching "Fast n Loud" a lot, recently, so i apologise for
copying their expressions...

 maan if i ever had to have a reason for every code change i ever
maaade, i'd be a wise old foool.  wise... but old, cos it would take
too lawng :)

 my point is: sometimes, understanding comes later.  if you sit on
things waiting for understanding and "reasons", you'll be still
sitting there when the big shiny lights turn out to be attached to a
truck, and you'll be stew in somebody's pot :)


> Hopefully with these guys answered I could start actually making a unit tests that will work!

 not a problem, daniel: i run a lot of the stuff that i do without
actually knowing what i'm doing, i just have a clear goal in mind and
work out ways to test that i'm on track.  get there in the end, but
ask me to explain it? pffh :)  so, actually explaining it to someone
else is a great way to clarify things, for me.

> Hope you are having a great day

 series 3, episode 4 of Fast n Loud... those guys are funny as hell.

l.



More information about the libre-riscv-dev mailing list