Reading the mtvec register on RISC-V - riscv

How to read the content of the mtvec register?

mtvec is a CSR system register.
To read: It can be read by the csrrw instruction into an integer register as first and third parameter (should be the same). The second parameter is the mtvec system register index. As a shortcut csrr can be used.
E.g.
csrrw t0, mtvec, t0
to read mtvec into t0.
To write: It can also be copied from an integer register with the csrrw instruction. The first parameter specifies another integer register, which will hold the previous value afterwards.
E.g.
csrrw t0, mtvec, t1
to read old mtvec into t0 and write t1 into mtvec as new value.

Related

How does extensors M and R works CALLP on RPGLE?

I'm learning a little bit of RPGLE. But i don't have any reference of extensors M and R and how they work. I only found information about Extensor E. Please any help or any reference would be accepted!
The CALLP docs mention
For information on how operation extenders M and R are used, see
Precision Rules for Numeric Operations.
Following the link to the precision rules says
you can ensure that the decimal positions are kept by using the
"Result Decimal Positions" precision rule for the statement by coding
operation code extender (R).
Granted you have to dig down into the Default precision rules page to find out that
default and can be specified for an entire module (using control
specification keyword EXPROPTS(*MAXDIGITS) or for single free-form
expressions (using operation code extender M).
If you have the PDF version of the RPG manual, then there's an entry in the index.."operation extender" which takes you to the section about them in the "Calculation Specification - Traditional Syntax"
Operation Extender:
Entry Explanation
Blank No operation extension supplied
A Used on the DUMP operation to indicate that the operation is always performed regardless of the DEBUG option set on the H specification.
H Half adjust (round) result of numeric operation
N Record is read but not locked
Set pointer to *NULL after successful DEALLOC
P Pad the result field with blanks
D Pass operational descriptors on bound call
Date field
T Time field
Z Timestamp field
M Default precision rules
R "Result Decimal Position" precision rules
E Error handling
For CALLP, the M and R extenders affect how CONST and VALUE parameters are passed.
ctl-opt dftactgrp(*no);
callp(m) proc(2 / (7.0 / 10.0));
callp(r) proc(2 / (7.0 / 10.0));
return;
dcl-proc proc;
dcl-pi *n;
parm packed(10 : 9) const;
end-pi;
dsply (%char(parm));
end-proc;
This program displays
DSPLY 2.800000000
DSPLY 2.857142857

16-bit CPU design: Issues with implementing fetch-execute cycle

I am doing a computer architecture course on Coursera called
NandtoTetris and have been struggling with my 16-bit CPU design. The
course uses a language called HDL, which is a very simple Verilog like
language.
I have spent so many hours trying to iterate on my CPU design based on
the diagram below and I don't understand what I am doing wrong. I
tried my best to represent the fetch and execute mechanics. Does
anyone have any advice on how to solve this?
Here are the design and control syntax diagram links:
CPU IO high-level diagram:
Gate level CPU diagram:
Control instruction syntax:
Here is my code below:
// Put your code here:
// Instruction decoding:from i of “ixxaccccccdddjjj”
// Ainstruction: Instruction is 16-bit value of the constant that should be loaded into the A register
// C-instruction: The a- and c-bits code comp part, d- and j-bits code dest and jump(x-bits are ignored).
Mux16(a=outM, b=instruction, sel=instruction[15], out=aMUX); // 0 for A-instruction or 1 for a C-instruction
Not(in=instruction[15], out=aInst); // assert A instruction with op-code as true
And(a=instruction[15], b=instruction[5], out=cInst); // assert wite-to-A-C-instruction with op code AND d1-bit
Or(a=aInst, b=cInst, out=aMuxload); // assert Ainstruction or wite-to-A-C-instruction is true
ARegister(in=aMUX, load=cInst, out=addressM); // load Ainstruction or wite-to-A-C-instruction
// For C-instruction, a-bit determines if ALU will operate on A register input (0) vs M input (1)
And(a=instruction[15], b=instruction[12], out=Aselector); // assert that c instruction AND a-bit
Mux16(a=addressM, b=inM, sel=Aselector, out=aluMUX); // select A=0 or A=1
ALU(x=DregisterOut, y=aluMUX, zx=instruction[11], nx=instruction[10], zy=instruction[9], ny=instruction[8], f=instruction[7], no=instruction[6], zr=zr, ng=ng,out=outM);
// The 3 d-bits of “ixxaccccccdddjjj” ALUout determine registers are destinations for for ALUout
// Whenever there is a C-Instruction and d2 (bit 4) is a 1 the D register is loaded
And(a=instruction[15], b=instruction[4], out=writeD); // assert that c instruction AND d2-bit
DRegister(in=outM, load=writeD, out=DregisterOut); // d2 of d-bits for D register destination
// Whenever there is a C-Instruction and d3 (bit 3) is a 1 then writeM (aka RAM[A]) is true
And(a=instruction[15], b=instruction[3], out=writeM); // assert that c instruction AND d3-bit
// Programe counter to fetch next instruction
// PC logic: if (reset==1), then PC = 0
// else:
// load = comparison(instruction jump bits, ALU output zr & ng)
// if load == 1, PC = A
// else: PC ++
And(a=instruction[2], b=ng, out=JLT); // J2 test against ng: out < 0
And(a=instruction[1], b=zr, out=JEQ); // J1 test against zr: out = 0
Or(a=ng, b=zr, out=JGToutMnot)); // J0 test if ng and zr are both zero
Not(in=JGToutMnot, out=JGToutM; // J0 test if ng and zr are both zero
And(a=instruction[0], b=JGToutM, out=JGT);
Or(a=JLT, b=JEQ, out=JLE); // out <= 0
Or(a=JGT, b=JLE, out=JMP); // final jump assertion
And(a=instruction[15], b=JMP, out=PCload); // C instruction AND JMP assert to get the PC load bit
// load in all values into the programme counter if load and reset, otherwise continue increasing
PC(in=addressM, load=PCload, inc=true, reset=reset, out=pc);
It is tricky to answer these kinds of questions without doing the work for you, which isn't helpful to you in the long run.
Some general thoughts.
Consider each element in isolation (including the circles where signals come together).
Label each line between elements with a name. These will become internal control lines. It helps reduce the chances of confusion.
Be very careful about junk outputs. If you're not supposed to be putting valid data on outM, use a Mux to output false.
Potential gotcha: I seem to remember that it's a bad idea to use a design output (like outM) as an input to something else. Outputs should only be outputs. Right now you are sending the output of the ALU to outM and using outM as an input to other elements. I suggest you try outputting the ALU to a new signal "ALUout", and using that as the input for the other elements and (through a mux with false controlled by writeM) outM. But remember, writeM is an output! So the block that generates writeM needs to generate a copy of itself to use as the control to the mux. FORTUNATELY, a block can have multiple out statements!
For example, right now you're generating outM like this (I won't comment on whether it is wrong, I am just using it as an illustration):
And(a=instruction[15], b=instruction[3], out=writeM);
You can create a second output like this:
And(a=instruction[15], b=instruction[3], out=writeM, out=writeM2)
and then "clean" your outM like this:
Mux16(a=false,b=ALUout,sel=writeM2,out=outM);
Good luck!

I confuse reference operator and references, dereference operator and pointer

As I know, & is called 'reference operator' which means 'address of'. So, its role is storing address in any variable. For example, 'a=&b;'. But I know another meaning which is 'references'. As you know, references is a alias of a variable. So, in my result, & has two meaning according to position. If 'a=&b;', & means 'address of b'. If 'int &a = b;', & means 'alias of another variable'.
As I know, * is called 'dereference operator'. But It is like &, It has two meaning according to position. If 'int *a = &b', * means 'pointer variable'. If 'a=*b', * means 'dereference variable'.
Are they right????
P.S. I'm foriegner. So I'm poor at English. Sorry... my poor English.
Hi as I understand you are having confusion with the concepts of pointers and references. Let me try and break it down for you :
When we use either of these in a variable declaration, think of it as specifying the datatype of that variable.
For example,
int *a; creates a pointer variable 'a', which can hold the address of(in other words, point to) another integer variable.
Similarly int & a = b; creates a reference variable 'a' which refers to b(in other words 'a' is simply an alias to integer b).
Now it might look as they are same, infact they both serve similar functionality, but here are some differences:
A pointer has memory allocated for it to hold the address of another variable to which it points, whereas references don't actually store the address of the variable they are referencing.
Another difference would be that a pointer need not be initialized when it is declared, but a reference must be initialized when it is declared, otherwise it throws an error. ie; int * a; is ok whereas int & a; throws error.
Now for the operators, try and see them not at all associated with pointers or references(Although thats where we use them the most).
Reference operator(&) simply returns you the address of its operand variable. Whereas a dereferencing operator(*) simply assumes that the value of its argument is an address, and returns the value stored at that address.
Hope this helped you. Here are some useful references(no pun intended):
https://www.ntu.edu.sg/home/ehchua/programming/cpp/cp4_PointerReference.html
How does a C++ reference look, memory-wise?

swap two variables in verilog using XOR

I have a line of data of 264 bits in memory buffer written using Verilog HDL.
buffer[2]=264'b000100000100001000000000001000000000000001000001000000000000000000000000000000000000100000010000010000100000000000100000000010000100001100000000000000000000000000000000000010000001000001000010000000000010000000000000010001010000000000000000000000000000000000001000;
I want to transfer 10 bits within the above raw from buffer[2][147:138] bits to buffer[2][59:50], then transfer buffer[2][235:226] bits into buffer[2][147:138]
I try to do this using XOR but it dose not work
buffer[2][59:50]=buffer[2][59:50]^buffer[2][147:138];
buffer[2][147:138]=buffer[2][59:50]^buffer[2][147:138];
buffer[2][59:50]=buffer[2][59:50]^buffer[2][147:138];
buffer[2][235:226]=buffer[2][235:226]^buffer[2][147:138];
buffer[2][147:138]=buffer[2][235:226]^buffer[2][147:138];
buffer[2][235:226]=buffer[2][235:226]^buffer[2][147:138];
How can I do this without using non-blocking assignment ?
You can swap with concatenations, no xor required:
{buffer[2][147:138],buffer[2][59:50]} = {buffer[2][59:50],buffer[2][147:138]};
{buffer[2][235:226],buffer[2][147:138] = {buffer[2][147:138],buffer[2][235:226]};
Your title says swap, but your description says transfer. To transfer you can can still use the same approach:
{buffer[2][147:138],buffer[2][59:50]} = {buffer[2][235:226],buffer[2][147:138]}
// Or you can do this, beware order matters
buffer[2][59:50] = buffer[2][147:138];
buffer[2][147:138] = buffer[2][235:226];
Be careful where you do this in an always block. It can create a combinational feedback loop after synthesized if done incorrectly. The bits must first be assigned by a determinate value (ideally a flop) before doing the swap.
Just create a new variable to hold the new, rearranged, array. This should not generate any logic, you are just rearranging wires.
reg [263:0] reArrBuffer [0:2];
assign reArrBuffer =
'{buffer[0],
buffer[1],
{buffer[2][263:148], buffer[2][235:226], buffer[2][137:60], buffer[2][147:138], buffer[2][49:0]}
};
Note: You need ' in front of the first { to create an assignment pattern for an unpacked array. It can be removed if buffer and reArrBuffer is packed.

LC-3 Assembly Language - swapping values

How can I swap to values in an address. Currently I have 2 registers which contain the addresses. I then had 2 temporary variables which stores those addresses. I then loaded the values since I have the address. But I can not figure out how to swap the values. I am trying to do bubble sort. The code below is what I currently have
IF ;swapping condition
ST R2,idata ;temporily hold the smaller data
ST R1,imindata ;temporaily hold the larger data
ST R2,iminaddres ;store the values into that address
ST R2,iaddress ;finish the swaping of the two values
LD R1,iminaddres ;reput the address back into the register
LD R2,iaddres ;reput the address back into the register to be used for next cycle
How would you do it in C?
temp = a;
a = b;
b = temp;
Then understand there is a need to load those values from memory, which changes things a bit
tempa = a;
tempb = b;
b = tempa;
a = tempb;
then isolate the loads and stores
rega <= load(a);
regb <= load(b);
store(a) <= regb;
store(b) <= rega;
then implement that in assembly. This smells like a homework assignment so I wont do it for you.
If all you want to do is swap the contents of two registers, there's a simple bit-twiddling trick:
XOR R1,R2
XOR R2,R1
XOR R1,R2
This will exchange the contents of the two registers without using any memory.

Resources