sergeykhbr / riscv_vhdl

Portable RISC-V System-on-Chip implementation: RTL, debugger and simulators
http://sergeykhbr.github.io/riscv_vhdl/
Apache License 2.0
626 stars 104 forks source link

Adding a Master peripheral #45

Open Mina2411 opened 1 year ago

Mina2411 commented 1 year ago

I want to add a new slave peripheral to Riscv, and I took SRAM as reference to know the modules and packages that I should modify, and I found that I should add:- 1) Index, start and end address in the memory address mapping in types_bus0_pkg. 2) Add a new device id in types_amba_pkg for my new peripheral. 3) Define the size of the peripheral in config_target_pkg. 4) Define the new slave peripheral in riscv_soc_pkg which I can't understand what this number given to the peripherals represent and to which module this number is used "I think this is the missing part that this number should be mapped to another module and get some information from this module, so if you can clarify what is the idea behind this number "SOC_PNP_SRAM"". Do I need to adjust any other modules or packages?

sergeykhbr commented 1 year ago
  1. Yes. You need to create new AXI slave slot by increasing CFG_BUS0_XSLV_TOTAL value and defining allocated memory range in the CFG_BUS_MAP.
  2. It is optional. Only if you would like to use plug'n'play feature (device descriptor visible in pnp module). You can use any values here including zeros. This IDs do not affect hardware.
  3. It is optional. config_target_pkg.sv file should be used to specify parameters that could have different value for different targets. For an example, internal SRAM in ASIC target should have 2 MB and it uses full allocated memory space in CFG_BUS_MAP but it is too big memory for FPGA board kc705. You can hardcoded parameters of your module wherever you want.
  4. It is optional the same as p.2. Only if you want that descriptor of your module was available in pnp module. You may ignore this structure and output signals of the module.

The best approach is to make step 1 and use _axislv sub-module as an AXI interface inside of your device.

Note: Most of the Verilog and SystemC files are generated by rtlgen utility (see https://github.com/sergeykhbr/rtlgen). When it will be fully finished it will implement full system generator that allows to create topology of the SoC and full customization.

Mina2411 commented 1 year ago

Hello, you mean to add a slave peripheral and fit it in the riscv soc, I need to do all the modifications in types_bus0_pkg only which is the index given to the peripheral to access the memory mapping vector in which the address range of my peripheral is described and increase CFG_BUS0_XSLV_TOTAL value afterwards. then I need to take the axi_slv as a sub module which I did already, anything else is optional which I may or may not use right? Thanks

Mina2411 commented 1 year ago

I see also that there is no axi_master interface or it is implemented in the sv version under a different name, because I wandering how the master peripherals are connected to the AXI without an interface module, so can you clarify where is this module or I need to implement one ?

sergeykhbr commented 1 year ago

Master interface is in the development to provide coherence interface and re-used in CPUs workgroup

Mina2411 commented 1 year ago

so you mean that there is no module for AXI_master interface explicitly, sorry,I am not able to understand what you mean .

Mina2411 commented 1 year ago

As I want to add a new master peripheral, how can I communicate with the AXI bus? That's why I am asking about an interface module like the axi_slv.

sergeykhbr commented 1 year ago

I cannot provide simple solution right now. You have several options that should be implemented manually:

  1. Connection to ACP port (before L2-cache). If you are developing DMA engine or another CPU and would like to provide coherence of caches of your device and CPUs of the workgroup then you need to reproduce state machine similar to _riveramba.sv file.
  2. Connection to BUS0 master port (no hardware coherency). Simplified version of the _riveramba.sv. In this case you either have two options: (a) Properly configure PMP (or MPU - memory protection unit) that allocates uncached memory regions used for inter-processor communication or (b) actively use ifence instruction and loose performance.
  3. Implementation of the master interface module at the top of my todo list, so sooner or later I will commit such module.
Mina2411 commented 1 year ago

Hello again, I mas

  1. Yes. You need to create new AXI slave slot by increasing CFG_BUS0_XSLV_TOTAL value and defining allocated memory range in the CFG_BUS_MAP.

    1. It is optional. Only if you would like to use plug'n'play feature (device descriptor visible in pnp module). You can use any values here including zeros. This IDs do not affect hardware.

    2. It is optional. config_target_pkg.sv file should be used to specify parameters that could have different value for different targets. For an example, internal SRAM in ASIC target should have 2 MB and it uses full allocated memory space in CFG_BUS_MAP but it is too big memory for FPGA board kc705. You can hardcoded parameters of your module wherever you want.

    3. It is optional the same as p.2. Only if you want that descriptor of your module was available in pnp module. You may ignore this structure and output signals of the module.

The best approach is to make step 1 and use _axislv sub-module as an AXI interface inside of your device.

Note: Most of the Verilog and SystemC files are generated by rtlgen utility (see https://github.com/sergeykhbr/rtlgen). When it will be fully finished it will implement full system generator that allows to create topology of the SoC and full customization.

Hello again, I made all the steps, and I defined the memory map for a slave peripheral as '{64'h0000100000000, 64'h0000100000100}, and The index for the peripheral to access the memory map, but when I test the peripheral by writing a value and trying to read it again to see if the peripheral is fitted in the processor or not, it always fails.I tried the same implementation of the sram to see if the problem is in my implementation or not, and it fails also. so Is there any other software "I mean in C header files or C files" or hardware steps that I should follow or the previous steps should let everything work?

sergeykhbr commented 1 year ago
Mina2411 commented 1 year ago

axi4_new_slave.txt For the testbench, I am working on it, but as you can see I made the connection the same as the connection of the sram and any other slave module. Thanks

sergeykhbr commented 1 year ago

I mean at the SoC level (file riscv_soc.sv) not inside of the slave device.

Mina2411 commented 1 year ago

riscv_soc.txt This is riscv_soc module, you can find the new peripheral under the sram module port map.

sergeykhbr commented 1 year ago

That looks good for me. But I think you should increase upper address. You cannot allocate less than 4 KB of memory on AXI bus (it is possible on APB - bus1).

Mina2411 commented 1 year ago

Hello, Yes,that was the problem, it worked now. also, I need to make my new peripheral non-cachable, so what I did that I tried to configure some CSR registers in the software program, and I did the following:-

1) configure CSR_MPU_ADDR_Register and give it the value of the base address of my new peripheral. asm("csrw 0x352, %0" : :"r"(base_address));

2) configure CSR_MPU_Mask_Register and give it the size of the peripheral. asm("csrw 0x353, %0" : :"r"(region_size));

3) configure CSR_MPU_CTRL_Register to adjust the attributes needed for the new peripheral asm("csrw 0x354, %0" : :"r"(0x10011)); //enable region/uncachable region/not an executable region/read region/write region

Actually, I added these lines of code in the main function, and it didn't work, so is there something else to be done to disable cache access when I am trying to read from or write to the peripheral?

Thank you very much for your effort.

sergeykhbr commented 1 year ago

See Physical Memory Protection (PMP) in risc-v specification. I forget to remove _mapmpu.h header file from examples that you are referring to. It was my own version of protection module before the specification updates and it is obsolete.

Mina2411 commented 1 year ago

You mean that I need to configure registers for PMP in the software program ?

sergeykhbr commented 1 year ago

No, sorry. My bad. PMP setups access rights. Edit pma.sv file to specify new IO (uncached) region.

Mina2411 commented 1 year ago

I saw the pma module, and I didn’t understand what I should do to specify uncached memory regions, or I need to add something to the module itself

sergeykhbr commented 1 year ago

In pma_pkg.sv specify constants:

localparam bit [CFG_CPU_ADDR_BITS-1:0] YOUR_DEVICE_BAR = 48'h000100000000;
localparam bit [CFG_CPU_ADDR_BITS-1:0] YOUR_DEVICE_MASK = 48'h000000000fff;// 4 KB

In pma.sv add uncahced data region:

    end else if ((i_daddr & (~YOUR_DEVICE_MASK)) == YOU_DEVICE_BAR) begin
        v_dcached = 1'b0;
Mina2411 commented 1 year ago

Hello, I tried to run the test bench of kc705_top, and I tried to monitor some internal signals"such as signals on AXI bus for example" that should change according to the software program that initialize the rom, but the signals are not assigned to any value for a long simulation time. From my understanding, the test bench of the top module will simulate the sub modules in the project which is the riscv_soc.sv which includes all the peripherals on the bus, so the software program should run during simulation time right? note that I am trying to run the simulation from a new project that I did not from the makefile. Thanks.

sergeykhbr commented 1 year ago

I am not sure that I understood your question but asic_sim, kc705_sim and a real hardware execute absolutely the same code and should show the same output. With the enabled DDR controller kc705_sim simulation works mush slower than 'unisim' asic_sim.

CPU harts after reset wait until I/D caches finish its initialization and become available. Duration of the cache initialization depends of cache sizes.

Mina2411 commented 1 year ago

I mean that I want to test the peripheral in vivado simulator (xsim) using the software program that initialize the ROM, and I am trying to monitor some internal signals that should change depending on the software program, but the problem is that the signals aren't changing, so my asking that should the test bench of the top module simulate all the submodules, and I should see how the AXI signals are changing.Also, I tried to write data in the SRAM and monitor the Axi_slave_input_signals, but they are not changing also.

sergeykhbr commented 1 year ago

Yes, whole system is simulating with the all peripheries.

Mina2411 commented 1 year ago

Hello sergey, Is there any news about the AXI master interface, or you are still working on it. Thanks.

sergeykhbr commented 1 year ago

No, sorry. I am more interested in the full-functional SD-controller right now.

Mina2411 commented 1 year ago

Hello Sergey, I want to flush and invalidate the data cache, is it implemented to configure csr registers?, as I see the flush signals in csr.sv module, but I don't know which registers to configure in the software code. Thanks

sergeykhbr commented 1 year ago

You can use fence.i instruction to flush caches