Author Topic: RISC-V assembly language programming tutorial on YouTube  (Read 52371 times)

0 Members and 2 Guests are viewing this topic.

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3136
  • Country: ca
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #75 on: December 13, 2018, 06:26:35 am »
Anyone want to show off their hand coding?

Of course, Intel is not slauch neither.

32-bit:

Code: [Select]
      sub eax,eax

loop: mov ecx,[esi+eax]
      adc ecx,[ebx+eax]
      mov [edi+eax],ecx
      lea eax,[eax+4]
      loop loop

6 instructions, 16 bytes, probably below 1 cycle per byte.

64-bit:

Code: [Select]
      sub eax,eax

loop: mov rcx,[rsi+rax]
      adc rcx,[rbx+rax]
      mov [rdi+rax],rcx
      lea rax,[rax+8]
      loop loop

This requires 4 REX bytes, so it's 20 bytes total, but that's where the 64-bitness helps. It'll probably run at about 0.4 bytes per cycle.
 

Online brucehoultTopic starter

  • Super Contributor
  • ***
  • Posts: 3973
  • Country: nz
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #76 on: December 13, 2018, 07:00:45 am »
Operating systems and compiler runtime libraries are always going to have a little bit of assembler in them -- at least as long as there exist CSRs that are not memory-mapped.
That's really a sign of a bad design in 2018.

I disagree.

There are very good reasons that you don't want settings that control the deep modes of operation of a processor to be able to be altered by a store instruction that can have its address arbitrarily computed. Things such as enabling or disabling MMUs, or setting the base address for an interrupt vector, or changing the register width and instruction set between 32 bits and 64 bits. These should all be recognised as special instructions early in the pipeline, with the "name" of the affected register/setting hardcoded in the instruction, not something that is discovered many cycles later, and possibly only after waiting hundreds of cycles for a memory load or other operation. You really don't want later instructions to have been already been attempted to be executed out of order -- possibly with an entirely different instruction set or opcode encoding.

Maybe you can get away with that in a single issue in-order tiny microcontroller -- and people implementing those are *welcome* to memory map everything they want -- but in that case you're stepping outside what is standard and can be depended on across *all* RISC-V implementations.
 

Online brucehoultTopic starter

  • Super Contributor
  • ***
  • Posts: 3973
  • Country: nz
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #77 on: December 13, 2018, 07:07:46 am »
Anyone want to show off their hand coding?

Why not. dsPIC33:

Code: [Select]
      dec w0,w0
      add #0,w0 ; clear carry
      do w0,loop
      mov [w1++],w4
loop: addc w4,[w2++],[w3++]

5 instructions, 15 bytes, n+3 instruction cycles (where n is the number of bytes)

Very nice.

How does gcc do on it?

I'm actually very disappointed that manufacturers of machines with condition codes don't seem to have added recognition of the C idiom for the carry flag and generated "add with carry" from it. gcc on every machine does recognise idioms for things such as rotate and generate rotate instructions even though C doesn't have an operator for it. Or maybe I just didn't find the correct idiom? Can anyone assist with that?
 

Online brucehoultTopic starter

  • Super Contributor
  • ***
  • Posts: 3973
  • Country: nz
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #78 on: December 13, 2018, 07:13:25 am »
Anyone want to show off their hand coding?

Of course, Intel is not slauch neither.

32-bit:

Code: [Select]
      sub eax,eax

loop: mov ecx,[esi+eax]
      adc ecx,[ebx+eax]
      mov [edi+eax],ecx
      lea eax,[eax+4]
      loop loop

6 instructions, 16 bytes, probably below 1 cycle per byte.

64-bit:

Code: [Select]
      sub eax,eax

loop: mov rcx,[rsi+rax]
      adc rcx,[rbx+rax]
      mov [rdi+rax],rcx
      lea rax,[rax+8]
      loop loop

This requires 4 REX bytes, so it's 20 bytes total, but that's where the 64-bitness helps. It'll probably run at about 0.4 bytes per cycle.

I'm afraid I don't understand how those work.

I thought "loop" decrements cx/ecx/rcx and loops if it's not zero. But you're using cx as a temporary to hold the result of the adc.

Also, where is the "ret", even if nothing else is needed?
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #79 on: December 13, 2018, 08:08:53 am »
MIPS doesn't have any Control and Status Register, and it's fine this way  :D
 

Online brucehoultTopic starter

  • Super Contributor
  • ***
  • Posts: 3973
  • Country: nz
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #80 on: December 13, 2018, 08:22:23 am »
MIPS doesn't have any Control and Status Register, and it's fine this way  :D

Sure it does. They live in Coprocessor #0 and are accessed using special  MTC0 and MFC0 instructions.
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #81 on: December 13, 2018, 08:24:11 am »
Multiword math.

What do you need exactly? 128bit math? and for what?
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #82 on: December 13, 2018, 08:25:27 am »
MIPS doesn't have any Control and Status Register, and it's fine this way  :D

Sure it does. They live in Coprocessor #0 and are accessed using special  MTC0 and MFC0 instructions.

exactly: the cop0 is not CPU, it's a Cop, thus it's "external" to the ISA  :D
 

Online brucehoultTopic starter

  • Super Contributor
  • ***
  • Posts: 3973
  • Country: nz
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #83 on: December 13, 2018, 08:50:26 am »
MIPS doesn't have any Control and Status Register, and it's fine this way  :D

Sure it does. They live in Coprocessor #0 and are accessed using special  MTC0 and MFC0 instructions.

exactly: the cop0 is not CPU, it's a Cop, thus it's "external" to the ISA  :D

"Coprocessor 0 (also known as the CP0 or system control coprocessor) is a required coprocessor part of the MIPS32 and MIPS64 ISA which provides the facilities needed for an operating system."

It's exactly equivalent to the RISC-V CSRs and dedicated instructions distinct from memory load/store to move values to and from the CSRs.

And you're right .. this stuff exists outside the normal portable standardised "User" ISA. @ataradov appears to be unhappy that someone -- the operating system or at least runtime library writer -- should have to write a few lines of machine-dependent assembly language to set this stuff up. It only has to be done once per SoC (at most) and Joe Average applications programmer doesn't have to know it exists.
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11219
  • Country: us
    • Personal site
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #84 on: December 13, 2018, 08:53:43 am »
@ataradov appears to be unhappy that someone -- the operating system or at least runtime library writer -- should have to write a few lines of machine-dependent assembly language to set this stuff up.
No, I'm unhappy with unnecessary proliferation of ways to access the hardware. This just makes makes things harder for no real benefit.
My RSS reader is blocked by the forum, so I won't be actively reading it. If you need to reach me, use email.
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #85 on: December 13, 2018, 09:00:48 am »
PA-RISC

on DTB we are still supporting Linux/HPPA-v2, everything else can R.I.P. and nobody (I can assure nobody) cares, except ... those who still have business with HPUX v11i2, but frankly it's just a matter of how much money they invested in this. I am specifically talking about avionics now.

If you paid 50K euro for a license (e.g. for VectorCast &C) and got a binary for HPPA, you still need to run it on HPPA until you find someone (in the circle of those who take decisions = managers) who is willing to pay for the new version. But it's just it, while in the meanwhile VectorCast&C have been ported to Intel-x86  :D

The same applies to software designed for SGI/MIPS.  I have a couple of friends who love using Autodesk software for IRIX. They do video editing, but ... they use this software simply because they want to play the retro-collector game. Autodesk-2008 is 10 years obsolete, and out of modern standards about video-editing.

Besides, a modern PC consumes less electricity than - say, an SGI Tezro or SGI Origin - and produces better results.

In short, there is no regret.  :D

We support HPPAv2 for two specific reasons: -1- the hardware is very cheap, and -2- the PCI on HPPA doesn't come with all the shit that IBM put in the BIOS in order to support ancestor video card. ISA Cards??? Yes, there is still support in modern BIOS and this makes everything a hell when you want to develop your own PCI_FPGA card.

My HP C3600 comes with a neat BIOS, there is no legacy shit, and it's cleaner than what you find on an Apple PowerMac, where the OpenFirmware a mess. Look at Linux source for the PCI.

About SGI MIPS we only support IP30: this machine runs Linux, and it's the only MIPS4 machine available since modern MIPS are all MIPS32 or MIPS64. Besides, IP30 comes with a crossbar matrix, and this is interesting.

There are no other good reasons to regret old RISC machines. Except, the manual (and I am saying THE manual) of 88K. (eight-eight key, by Motorola) which is super marvelous!  ;D
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #86 on: December 13, 2018, 09:12:34 am »
Quote from: brucehoult link=topic=156007.msg2036098#msg2036098ate=1544691026
"Coprocessor 0 (also known as the CP0 or system control coprocessor) is a required coprocessor part of the MIPS32 and MIPS64 ISA which provides the facilities needed for an operating system."

The Cop0 it's not covered by the ISA, it's * theoretically * optional. In fact, SPIM doesn't have it(1), neither MARS, and you can implement a MIPS-R2K without the Cop0, and it works.

Of course, SPIM, MARS and such a simplified CPU don't handle interrupts, thus they are useless for any practical application, except making students have a laboratory on software simulators

Yes, SPIM and MARS are widely used in universities. I used it a lot during my Erasmus in Oxford (2007-2008)

But it's not the point: the point is, let the CSR-stuff *OUT* of the ISA, so, do not implement any specific instructions like "Move CSR To/from CSR", let's have a Cop to handle it.

In m68k ... it was a mess when the 68010 redefined MOVE-CSR as a privileged instruction, while in 68000 was not privileged, and this caused a lot of troubles in Amiga Computers.



(1) can be compiled with/without Cop0 experimental support.
« Last Edit: December 13, 2018, 09:24:11 am by legacy »
 

Online brucehoultTopic starter

  • Super Contributor
  • ***
  • Posts: 3973
  • Country: nz
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #87 on: December 13, 2018, 09:14:58 am »
There are no other good reasons to regret old RISC machines. Except, the manual (and I am saying THE manual) of 88K. (eight-eight key, by Motorola) which is super marvelous!  ;D

88K is a very nice ISA, and pleasingly obsessive about sticking to the 2-read-1-write integer instruction model. There are a couple of features in it that I'm gently trying to steal for future RISC-V extensions, mostly in the "Bit Manipulation" working group.
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3136
  • Country: ca
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #88 on: December 13, 2018, 02:56:34 pm »
I'm afraid I don't understand how those work.

Good catch, we'll use DX instead of CX then.

32-bit:

Code: [Select]
      sub eax,eax

loop: mov edx,[esi+eax]
      adc edx,[ebx+eax]
      mov [edi+eax],edx
      lea eax,[eax+4]
      loop loop

64-bit:

Code: [Select]
      sub eax,eax

loop: mov rdx,[rsi+rax]
      adc rdx,[rbx+rax]
      mov [rdi+rax],rdx
      lea rax,[rax+8]
      loop loop

Surprsingly, it doesn't change the byte count.

Also, where is the "ret", even if nothing else is needed?

It's inlined. In assembler, you do not have to follow calling conventions :)

And if you really worry about byte count, you can add more CISC'iness and reduce byte count to 10, although it'll be slower.

Code: [Select]
      clc

loop: lodsd
      adc eax,[ebx]
      lea ebx,[ebx+4]
      stosd
      loop loop

 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3136
  • Country: ca
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #89 on: December 13, 2018, 03:15:23 pm »
Why not. dsPIC33:

Very nice.

How does gcc do on it?

As everywhere. Works hard but doesn't produce any magic.

C does very well on MIPS (and RISC-V too, of course), but this is not because C produces something magical, but because the instruction set is such that a human cannot improve much on what the C compiler have done.

I'm actually very disappointed that manufacturers of machines with condition codes don't seem to have added recognition of the C idiom for the carry flag and generated "add with carry" from it. gcc on every machine does recognise idioms for things such as rotate and generate rotate instructions even though C doesn't have an operator for it. Or maybe I just didn't find the correct idiom? Can anyone assist with that?

There many places like that, such as rotations. In such cases C is more difficult to code than assembler.

I look at C as a tool to convert text to assembler code. Sometimes it works well (for long expressions, for example). Sometimes it doesn't (as with long additions). But that's Ok. You can write few lines in assembler.

If you work with wood, you can do nice long cuts with a table saw, but there are small things which can only be done with a chisel. Should we re-design a table saw, so that it can do everything. Probably not. Same with C.
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #90 on: December 13, 2018, 08:35:06 pm »
LOL - "risc-v-will-stop-hackers-dead-from-getting-into-your-computer" - said someone in this article on hackaday

 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #91 on: December 13, 2018, 09:00:11 pm »
LOL - "risc-v-will-stop-hackers-dead-from-getting-into-your-computer" - said someone in this article on hackaday

Up there with "Linux doesn't need antivirus".... :-)
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #92 on: December 13, 2018, 09:27:52 pm »
My little software RISC-V emulator seems to be alive! Has churned through 3,047 instructions of a HiFive 'blink' binary. Maybe a couple of evenings play to get it this far - you couldn't do that with x86... the actual RISC-V code is < 800 lines.

(If I don't point it out in advance, somebody will point me at https://github.com/adriancable/8086tiny, which has an 8086 in 760 lines, but not an 32-bit CPU)

I had to build dummy hardware for the "AON" (Always On) Peripheral, and the "PRCI" (used for clocking control) Peripheral, and it gets as far as attempting to configure the QSPI interface on address 0x10014000.

I am sure somebody is about to ask "but why when there are so many already?"... I'm doing it because it is easier to build an understanding and verify what should be happening in hardware, rather than writing and simulating HDL, and then learning that I really didn't understand what should be happening in the 1st place.

I want to get the emulator C code to the point it models the HDL pipeline, so I can verify against it that things are as expected. Maybe I could even use it for HLS  :-//
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 
The following users thanked this post: brucehoult

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #93 on: December 13, 2018, 09:33:59 pm »
You did in two days?  :o :o :o
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #94 on: December 13, 2018, 09:56:58 pm »
You did in two days?  :o :o :o
... of spare time between the boy going to bed, and me going to bed.

It's not much to look at:

A lookup table to decode opcode:
Code: [Select]
struct opcode_entry {
  char *spec;
  int (*func)(void);
  uint32_t value;
  uint32_t mask;
} opcodes[] = {
   {"-------------------------0010111", op_auipc},
   {"-------------------------0110111", op_lui},
   {"-------------------------1101111", op_jal},
   {"-----------------000-----1100111", op_jalr},

   {"-----------------000-----1100011", op_beq},
   {"-----------------001-----1100011", op_bne},
   {"-----------------100-----1100011", op_blt},
   {"-----------------101-----1100011", op_bge},
   {"-----------------110-----1100011", op_bltu},
   {"-----------------111-----1100011", op_bgeu},

   {"-----------------000-----0000011", op_lb},
   {"-----------------001-----0000011", op_lh},
   {"-----------------010-----0000011", op_lw},
   {"-----------------100-----0000011", op_lbu},
   {"-----------------101-----0000011", op_lhu},

   {"-----------------000-----0100011", op_sb},
   {"-----------------001-----0100011", op_sh},
   {"-----------------010-----0100011", op_sw},


   {"-----------------000-----0010011", op_addi},
   {"-----------------010-----0010011", op_slti},
   {"-----------------011-----0010011", op_sltiu},
   {"-----------------100-----0010011", op_xori},
   {"-----------------110-----0010011", op_ori},
   {"-----------------111-----0010011", op_andi},
   {"0000000----------001-----0010011", op_slli},
   {"0000000----------101-----0010011", op_srli},
   {"0100000----------101-----0010011", op_srai},

   {"0000000----------000-----0110011", op_add},
   {"0100000----------000-----0110011", op_sub},
   {"0000000----------001-----0110011", op_sll},
   {"0000000----------010-----0110011", op_slt},
   {"0000000----------011-----0110011", op_sltu},
   {"0000000----------100-----0110011", op_xor},
   {"0000000----------101-----0110011", op_srl},
   {"0100000----------101-----0110011", op_sra},
   {"0000000----------110-----0110011", op_or},
   {"0000000----------111-----0110011", op_and},

   {"0000--------00000000000000001111", op_fence},
   {"00000000000000000001000000001111", op_fence_i},

   {"00000000000000000000000001110011", op_ecall},
   {"00000000000100000000000001110011", op_ebreak},

   {"-----------------001-----1110011", op_csrrw},
   {"-----------------010-----1110011", op_csrrs},
   {"-----------------011-----1110011", op_csrrc},
   {"-----------------101-----1110011", op_csrrwi},
   {"-----------------110-----1110011", op_csrrsi},
   {"-----------------111-----1110011", op_csrrci},

   {"--------------------------------", op_unknown}  // Catches all the others
};

A function to break the instruction into fields (the ugly bit):
Code: [Select]
/****************************************************************************/
static void decode(uint32_t instr) {
  int32_t broffset_12_12, broffset_11_11, broffset_10_05, broffset_04_01;
  int32_t jmpoffset_20_20, jmpoffset_19_12, jmpoffset_11_11, jmpoffset_10_01;
  rs1     = (instr >> 15) & 0x1f ;
  rs2     = (instr >> 20) & 0x1F;
  rd      = (instr >> 7)  & 0x1f;
  csrid   = (instr >> 20);
  uimm    = (instr >> 15) & 0x1f;
  shamt   = (instr >> 20) & 0x1f;
  upper20 = instr & 0xFFFFF000;
  imm12   = ((int32_t)instr) >> 20;

  jmpoffset_20_20 = (int32_t)(instr & 0x80000000)>>11;
  jmpoffset_19_12 = (instr & 0x000FF000);
  jmpoffset_11_11 = (instr & 0x00100000) >>  9;
  jmpoffset_10_01 = (instr & 0x7FE00000) >> 20;
  jmpoffset = jmpoffset_20_20 | jmpoffset_19_12 | jmpoffset_11_11 | jmpoffset_10_01;

  broffset_12_12 = (int)(instr & 0x80000000) >> 19;
  broffset_11_11 = (instr & 0x00000080) << 4;
  broffset_10_05 = (instr & 0x7E000000) >> 20;
  broffset_04_01 = (instr & 0x00000F00) >> 7;
  broffset = broffset_12_12 | broffset_11_11 | broffset_10_05 | broffset_04_01;

  imm12wr   =  instr; /* Note - becomes signed */
  imm12wr  >>= 20;
  imm12wr  &= 0xFFFE0;
  imm12wr  |= (instr >> 7)  & 0x1f;
  current_instr = instr;
}

And some small functions to actually execute the instructions:
Code: [Select]
/****************************************************************************/
static int op_beq(void) {     trace("BEQ\tr%i, r%i, %i", rs1, rs2, broffset);
  if(regs[rs1] == regs[rs2]) {
    pc += broffset;
  } else {
    pc += 4;
  }
  return 1;
}

...and then the code to acutally run an instruction:

Code: [Select]
/****************************************************************************/
static int do_op(void) {
  uint32_t instr;
  int i;
  if((pc & 3) != 0) {
    display_log("Attempt to execute unaligned code");
    return 0;
  }

  /* Fetch */
  if(!memorymap_read(pc,4, &instr)) {
    display_log("Unable to fetch instruction");
    return 0;
  }
  /* Decode */
  decode(instr);
 
  /* Execute */
  for(i = 0; i < sizeof(opcodes)/sizeof(struct opcode_entry); i++) {
     if((instr & opcodes[i].mask) == opcodes[i].value) {
       return opcodes[i].func();
     }
  }
  return 0;
}
« Last Edit: December 13, 2018, 10:09:27 pm by hamster_nz »
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9885
  • Country: us
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #95 on: December 13, 2018, 10:30:51 pm »
My little software RISC-V emulator seems to be alive! Has churned through 3,047 instructions of a HiFive 'blink' binary. Maybe a couple of evenings play to get it this far - you couldn't do that with x86... the actual RISC-V code is < 800 lines.


Your intention, at the moment, seems to be to emulate all of the instructions.  This seems like a great approach because instruction execution needs to be understood before even thinking about the other issues.

You mention coding the pipeline.  Is that where you are headed?  If so, I hope you'll publish your code as you go along. Either here or on your web site.

Instruction execution seems easy to code, the pipeline will be a lot more complex (I think...).
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #96 on: December 13, 2018, 11:26:36 pm »
Instruction execution seems easy to code, the pipeline will be a lot more complex (I think...).
For the level I am aiming at I don't think it will be too complex. All that is needed is a way to indicate if the instructions in the pipeline are no longer valid because the program counter was updated rather than incremented.

Unaligned memory accesses (which will need two cycles to execute) will a bit of complexity though, as it will stall the pipeline rather than requiring that it gets flushed.

Humm....
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9885
  • Country: us
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #97 on: December 13, 2018, 11:56:47 pm »
Instruction execution seems easy to code, the pipeline will be a lot more complex (I think...).
For the level I am aiming at I don't think it will be too complex. All that is needed is a way to indicate if the instructions in the pipeline are no longer valid because the program counter was updated rather than incremented.

Unaligned memory accesses (which will need two cycles to execute) will a bit of complexity though, as it will stall the pipeline rather than requiring that it gets flushed.

Humm....

I was wondering if you planned to implement the various registers that save state through the pipeline.  I am interesting in detecting and overcoming hazards.

What I really need is a reference book for the RISC-V that covers all the hardware details.  Not just at 10,000 feet up but right down in the dirt.  Something I can convert from text to HDL or, better yet, maybe the HDL is given.

Are there any such references?
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #98 on: December 14, 2018, 12:32:18 am »
What I really need is a reference book for the RISC-V that covers all the hardware details.  Not just at 10,000 feet up but right down in the dirt.  Something I can convert from text to HDL or, better yet, maybe the HDL is given.

Are there any such references?

I think that this is the key of the RISC-V ethos - it is just the ISA specification. What you do with it is up to you.

As long as your hardware runs the RISC-V RV32I (+ whatever extensions) you don't have to worry too much about the software tooling.

RISC-V it isn't a hardware specification - it is a specification of the interface between the software layer and digital logic layers. If you build a CPU that implements RISC-V, you have a ready-made software layer.

And if you build software that targets RISC-V, you have ready-made hardware implementations.

So that is why I am using the SiFive HiFive's FE310 as a reference for my hacks:

- I have the real hardware on my desk https://www.sifive.com/boards/hifive1 (one of the early team signature edition boards, no less!), to clear up any of my misunderstandings

- the GCC  RISC-V toolchain is all there, installed on a Linux VM that I used playing with the HiFive

- Everything about the chip is well-documented at https://www.sifive.com/chip-designer#fe310

So now all I need to do is run 'objcopy' to convert the ELF image to a binary file, then load it into in my emulator's ROM, and I am ready to debug :).

« Last Edit: December 14, 2018, 12:34:00 am by hamster_nz »
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 
The following users thanked this post: brucehoult

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3136
  • Country: ca
Re: RISC-V assembly language programming tutorial on YouTube
« Reply #99 on: December 14, 2018, 12:35:54 am »
Unaligned memory accesses (which will need two cycles to execute) will a bit of complexity though, as it will stall the pipeline rather than requiring that it gets flushed.

Since this is on FPGA, an easy solution to this is using multi-port BRAM which can fetch two consecutive words at a time (for example one port reads address (a&~3) while the next one reads addrsss (a&~3+4). Concatenating them together you get 8 bytes starting at (a&~3). Using a 4:1 mux controlled by (a&3), you can then read any unaligned 32-bit word. The mux will add some delay, but since you're going to have bigger delays elsewhere (such as in ALU), this probably doesn't matter. Of course, it'll only work if you use BRAM as your memory.
 
The following users thanked this post: hamster_nz


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf