koyamanx / rv32x_dev Goto Github PK
View Code? Open in Web Editor NEWRISC-V implementation in NSL for FPGA. (rv32xSoC)
License: GNU General Public License v3.0
RISC-V implementation in NSL for FPGA. (rv32xSoC)
License: GNU General Public License v3.0
mtime is read-only register in CLINT, after taking timer interrupt then reset mtime.
Otherwise, timer interrupt want arises at the correct interval.
No way to reset it from software.
We implemented minstret for rdinstret instruction.
Some instruction such as ecall never retire in practice, However in current version of implementation counts up instret counter on all of instructions except for flushed instructions.
This behaviour must be fixed.
Some delegation of exceptions is missing like for example, page fault.
Future work must be implement all of delegation. (some exception delegation is not impractical ex. delegate illegal instruction exception to supervisor mode)
mtime register is read-only register, so map read port of clint.
Current implementation allows occurrence of trap even when bus is accessed.
This may produce unwanted execution behavior.
For example, assume following instructions are in pipeline.
IF | DE | EX | MEM | WB |
---|---|---|---|---|
interrupt handler | x | x | page fault | x |
In this case, page fault in memory stage overtakes interrupt handler.
Which is not correct behavior, since interrupts has higher precedence than synchronous exceptions.
In addition, it will destruct the context in the first trap.
To avoid this situation, we need to disable interrupt and exception from occurring during data memory access.
This will lead to little bit lower responsiveness of interrupts.
Or flush memory stage if trap is taken. (natural way?)
This requires facilities to cancel bus transfer(memory access).
Currently, no arbitration is taken place on memory access from Instruction Bus and Data Bus.
For simulation purpose, it can be managed because, memory access is processed in software(cpp top module)
However, running on FPGA, it needs dual port ram or arbitration on simultaneous access of memory.
Even with dual port RAM, SDRAM region must require arbitration.
CSR instructions may generate illegal instruction if instruction is accessing CSRs not mapped on CSR address space or writing value to read-only CSRs.
In current implementation, evaluation of illegal instruction is taken place at execute stage of the pipeline.
However CSR instructions are issued at writeback stage, so it complicates handling of illegal instruction exception.
This is not required on most of the cases, but as a implementation note,
SV32 paging translates 32 bit VA(Virtual Address) to 34 bit PA(Physical Address),
current implementation assumes 32 bits for physical address space.
The codes below clears other bits in CSR if uimm operation.
Line 419 in 82e03ad
Line 426 in 82e03ad
Line 437 in 82e03ad
Since 5 bits uimm is zero extended to create new CSR value.
However CSR value with uimm is concatenation of previous CSR value with 5 bit uimm like code below.
new_CSR = {prev_CSR[31:5], uimm[4:0]};
So that value in upper 27 bits of CSR won't be cleared on CSR write with uimm.
csr_addr[9:8] encodes the lowest privilege level that can access the CSR.
Check this fields to verify if current operating mode has right privilege to access them.
Although current implementation has only Machine mode available so it is not required right now.
However, implementing other lower privileged level upon Machine mode, this mechanism must be implemented altogether.
Lines 324 to 346 in 14e15de
Dcache_unit module serves as controller to memory operations onto cache unit inside and outside memory unit.
It's reasonable to change name for readability.
checking data memory's address range with check_daddr_range facility is not appropriate?
This facility must be done in PMP module.
check_daddr_range checks which address range is mapped(valid) in dmem accesses, however checking these attributes is not suitable feature of cpu core itself but PMP facilities(supposingly)
PMP -> raise access fault if not valid or mapped.
Bus error can be used for non-mapped region since these region is connected to default slave and always make error response (in AHB-Lite)
Current design does not check whether accessing address is mapped to register or memory regions.
This will hang simulator, since accessing vacant region and does not assert dmem_valid.
Add mechanism to check valid address range of MMIO devices and CLINT to avoid this situation.
Also consider to implement bus timeout.
Supervisor mode interrputs takes over machine mode interrupts when s-mode interrputs happend during processing m-mode interrupts.
fix condition for supervisor_interrupt_enabled and priority encoder for interrupt not to take less privileged interrupts when processing higher.
Operating system like xv6-riscv uses UART16550a.
It can be useful to make UART module UART16550a compliant.
We implement minimum features required for booting xv6-riscv for now.
For example,
slli x1, x1, 0x20
does not process as illegal instruction which should be.
The code above let x1 <= x1 << 0x0 which must be handled as illegal instruction exception on valid implementation.
Although, this code cannot be assembled by "GNU as" however similar code appears at rv32mi-p-shamt in riscv-tests.
This behaviour is caused because current implementation does not check some fields precisely by the decoder.
Making sure following condition must produce illegal instruction exceptions.
rv32x_dev/core/rv32x_mcore.nsl
Lines 111 to 119 in b47d284
rv32x_dev/core/rv32x_mcore.nsl
Lines 190 to 195 in b47d284
Current simulator print waveform (VCD file) for simulation.
So it's too slow for running practical program.
Make compilation switch to disable and enable output of VCD file.
Attribute | Valid write | Invalid write |
---|---|---|
WIRI | Ignore | Ignore |
WPRI | Ignore | Ignore |
WLRL | Write | Write |
WARL | Write | Modified to valid |
Lines 421 to 449 in b47d284
We use xip structure for xie.
So fields name of xie is not correct.
This mistake does not raise problem because xie and xip uses same format except for its name.
However understandability of codes, it should be changed to correct name.
Current implementation of fence instruction is executed as nop.
However, with D$, we need to guarantee that external devices observe memory instruction execution order.
No external device access memory implicitly so no problem arises for now.
For simulating practical application on this simulator, GDB is often useful.
To enable debugging with GDB, integrate RSP server to simulation top module, give access to internal structure of simulator to GDB.
RSP server sample resides in simulation/rsp_server/main.c
UART does not have interrupt enable flag in status register, PLIC can mask or unmask interrupt however, it may sometimes useful for having interrupt enable in UART module.
This simulator exits its simulation when writing exit code to memory location 0x80001000.
Then, exit code is returned to your environment.
0x80001000 is used in riscv-tests as symbol name of 'tohost' to indicate end of tests.
However, for more practical program, writing to fixed location is not suitable.
Provides options for how to exit simulator.
Consider following options.
Current design of UART module does not contain FIFO inside meaning every time UART module finishes its operation,
It will generates interrupt signal.
This causes performance of processor.
In addition, UART RXD will lose received data if processor takes that data before another data arrives.
Exception like environment call from x mode does not flush memory stage, so if memory stage has at least one wait cycle, operation privilege mode of memory stage changed to trapped privilege mode.
Need to cancel until memory stage on all exception or store independent privilege mode prior to trap for memory stage during memory operation handling.
spec says on unprivileged ISA V20191214-draft p.49 that "For LR and SC, the A extensions requires that the address held in rs1 be naturally aligned to the size of the operand.
If not aligned, address-misaligned exception or access-fault exception will be generated.
The access-fault exception can be generated for memory access that would otherwise be able to complete except for the misalignment, if misaligned access should not be emulated."
So, in this implementation. we shall generate address-misaligned exception for them.
Current implementation evaluate whether instruction address misaligned or not at ifetch stage (right before sending address to BUS)
However, in RISCV privileged specification on p.41 at (riscv-tests@14f08f8)
Instruction address misaligned exceptions are raised by control-flow instructions with misaligned
targets, rather than by the act of fetching an instruction. Therefore, these exceptions have lower
priority than other instruction address exceptions.
With this design choice and to retain exception handing priority, we need to evaluate misaligned target at address calculation.
Otherwise, exception priority in execute stage (address calculation stage) will change.
Evaluation of misaligned targets must be done in the same stage as target address calculation (namely execute stage for this implementation).
Temporary disabled D$ at commit(89467eb)
Problem are under investigation, however we note some for investigation.
SV32 are enabled,
0x0000_0000 -> 0x8000a0000 mapping for R, W, X, U, V.
Priv mode are User,
Instruction at address of VA:0x00000010(PA:0x8000a010) are wrong,
eg. instruction at 0x0000_0000 are li a7, 7
however, actually executed are li gp, 7. (only one byte is not correct)
Executing xv6's initcode(before user proc init) will always fault with invalid system call number at 0x00000000, because it writes to gp instead of a7.
Loading memory location at 0x0000_0000 are correct.
So we think that writeback of D$ is not work correctly when two-level paging enabled.
if not existed, then raise {INSTRUCTION,STORE,LOAD}_ACCESS_FAULT?
or Implementation defined BUS-ERROR exception?
or deadlock if bus does support timeout.
Need more information on ACCESS_FAULT.
This implementation installs data cache, so checking accessing address location are cacheable(memory location) or non-cacheable(I/O).
Otherwise, data cache holds invalid data of I/O registers.
Data cache is instantiated in 'rv32x_mcore' module however memory map is set in 'rv32x_integration' module.
So need some way to test whether cacheable or not.
If cacheable, memory access is done through data cache.
if non-cacheable, memory access is done directly without data cache.
Lines 285 to 288 in fb14d58
Lines 292 to 295 in fb14d58
Lines 299 to 302 in fb14d58
Lines 306 to 309 in fb14d58
Line 313 in fb14d58
Line 326 in fb14d58
According to privileged specification, highest priority is Instruction address breakpoint so ecall is lower priority than Instruction address breakpoint.
In this implementation, ecall is taken place at execute and instruction fetch at ifetch.
In this case, instruction in ifetch stage is the instruction which must not be executed and flushed by ecall.
Assume the instruction flow below in pipeline.
Ifetch | Decode | Execute | Memory | Writeback |
---|---|---|---|---|
break point address | some instruction | ecall | some instruction | some instruction |
In this flow, ecall must change instruction flow with flushing ifetch and decode so no break point address exception arises now.
However, in this implementation, break point address exception is taken place, and ecall exception lost.
This implementation causes problem in the case where multiple sources of exception arises simultaneously in multiple stages.
However, priority encoder does not take these cases into account, need to change priority order carefully with checking which stages rises exceptions.
One way to solve this problem is change order of statements in alt construct so that exception in preceding instruction is accepted and following instruction is flushed.
NOTE: the priority order in stage must be preserved.
rv32x_dev/core/rv32x_mcore.nsl
Lines 132 to 141 in 2109a63
Implement interrupt request to context1 in PLIC so that core0 can use context1' interrupt request line to implement supervisor external interrupt.
Implementing interrupt request line to context1 is straightforward, just copy and paste interrupt request for context0.
Some signals requires renaming.
Lint check does not take place on this project now, however we should add lint check for design correctness.
A module with only combinational logic will generate UNUSED warning on m_clock, so -Wno-UNUSED flag must be added.
Currently, memory blocks in BTB module does not infer for most of FPGA boards, since it does not register output port of memory and writing all of blocks simultaneously on flush.
So, with assumption that this module never be inferred, it has small amount of entries(32 entries).
However, to improve performance as respect to clock frequency and hit rates of BTB, it must use inferred block ram with more entries.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.