Closed mithro closed 5 years ago
I'm looking at adding a minimal
and lite
variants to picorv32 config.
diff --git a/litex/soc/cores/cpu/picorv32/core.py b/litex/soc/cores/cpu/picorv32/core.py
index 7fe830d6..d003bffb 100644
--- a/litex/soc/cores/cpu/picorv32/core.py
+++ b/litex/soc/cores/cpu/picorv32/core.py
@@ -9,7 +9,7 @@ class PicoRV32(Module):
name = "picorv32"
endianness = "little"
gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf")
- gcc_flags = "-D__picorv32__ -mno-save-restore -march=rv32im -mabi=ilp32"
+ gcc_flags = "-D__picorv32__ -mno-save-restore -march=rv32i -mabi=ilp32"
linker_output_format = "elf32-littleriscv"
def __init__(self, platform, progaddr_reset, variant):
@@ -31,19 +31,19 @@ class PicoRV32(Module):
self.specials += Instance("picorv32",
# parameters
- p_ENABLE_COUNTERS=1,
- p_ENABLE_COUNTERS64=1,
- p_ENABLE_REGS_16_31=1,
- p_ENABLE_REGS_DUALPORT=1,
+ p_ENABLE_COUNTERS=0,
+ p_ENABLE_COUNTERS64=0,
+ p_ENABLE_REGS_16_31=1, # Register file, so no difference?
+ p_ENABLE_REGS_DUALPORT=1, # Register file, so no difference?
p_LATCHED_MEM_RDATA=0,
- p_TWO_STAGE_SHIFT=1,
+ p_TWO_STAGE_SHIFT=0,
p_TWO_CYCLE_COMPARE=0,
p_TWO_CYCLE_ALU=0,
- p_CATCH_MISALIGN=1,
+ p_CATCH_MISALIGN=0,
p_CATCH_ILLINSN=1,
p_ENABLE_PCPI=0,
- p_ENABLE_MUL=1,
- p_ENABLE_DIV=1,
+ p_ENABLE_MUL=0,
+ p_ENABLE_DIV=0,
p_ENABLE_FAST_MUL=0,
p_ENABLE_IRQ=1,
p_ENABLE_IRQ_QREGS=1,
Before;
Info: Device utilisation:
Info: ICESTORM_LC: 5668/ 5280 107%
Info: ICESTORM_RAM: 4/ 30 13%
Info: SB_IO: 7/ 96 7%
Info: SB_GB: 8/ 8 100%
Info: ICESTORM_PLL: 0/ 1 0%
Info: SB_WARMBOOT: 0/ 1 0%
Info: ICESTORM_DSP: 0/ 8 0%
Info: ICESTORM_HFOSC: 0/ 1 0%
Info: ICESTORM_LFOSC: 0/ 1 0%
Info: SB_I2C: 0/ 2 0%
Info: SB_SPI: 0/ 2 0%
Info: IO_I3C: 0/ 2 0%
Info: SB_LEDDA_IP: 0/ 1 0%
Info: SB_RGBA_DRV: 0/ 1 0%
Info: ICESTORM_SPRAM: 4/ 4 100%
After;
Info: Device utilisation:
Info: ICESTORM_LC: 3967/ 5280 75%
Info: ICESTORM_RAM: 4/ 30 13%
Info: SB_IO: 7/ 96 7%
Info: SB_GB: 8/ 8 100%
Info: ICESTORM_PLL: 0/ 1 0%
Info: SB_WARMBOOT: 0/ 1 0%
Info: ICESTORM_DSP: 0/ 8 0%
Info: ICESTORM_HFOSC: 0/ 1 0%
Info: ICESTORM_LFOSC: 0/ 1 0%
Info: SB_I2C: 0/ 2 0%
Info: SB_SPI: 0/ 2 0%
Info: IO_I3C: 0/ 2 0%
Info: SB_LEDDA_IP: 0/ 1 0%
Info: SB_RGBA_DRV: 0/ 1 0%
Info: ICESTORM_SPRAM: 4/ 4 100%
FYI - @cr1901
Disabling p_ENABLE_REGS_16_31=0
and p_ENABLE_REGS_DUALPORT=0
actually seems to make it use more resources;
Info: Device utilisation:
Info: ICESTORM_LC: 5000/ 5280 94%
Info: ICESTORM_RAM: 0/ 30 0%
Info: SB_IO: 7/ 96 7%
Info: SB_GB: 8/ 8 100%
Info: ICESTORM_PLL: 0/ 1 0%
Info: SB_WARMBOOT: 0/ 1 0%
Info: ICESTORM_DSP: 0/ 8 0%
Info: ICESTORM_HFOSC: 0/ 1 0%
Info: ICESTORM_LFOSC: 0/ 1 0%
Info: SB_I2C: 0/ 2 0%
Info: SB_SPI: 0/ 2 0%
Info: IO_I3C: 0/ 2 0%
Info: SB_LEDDA_IP: 0/ 1 0%
Info: SB_RGBA_DRV: 0/ 1 0%
Info: ICESTORM_SPRAM: 4/ 4 100%
The increase in ICESTORM_LC
usage seems to be caused by setting p_ENABLE_REGS_DUALPORT=0
to zero.
Using p_ENABLE_REGS_16_31=0
and p_ENABLE_REGS_DUALPORT=1
gives you;
Info: Device utilisation:
Info: ICESTORM_LC: 3988/ 5280 75%
Info: ICESTORM_RAM: 4/ 30 13%
Info: SB_IO: 7/ 96 7%
Info: SB_GB: 8/ 8 100%
Info: ICESTORM_PLL: 0/ 1 0%
Info: SB_WARMBOOT: 0/ 1 0%
Info: ICESTORM_DSP: 0/ 8 0%
Info: ICESTORM_HFOSC: 0/ 1 0%
Info: ICESTORM_LFOSC: 0/ 1 0%
Info: SB_I2C: 0/ 2 0%
Info: SB_SPI: 0/ 2 0%
Info: IO_I3C: 0/ 2 0%
Info: SB_LEDDA_IP: 0/ 1 0%
Info: SB_RGBA_DRV: 0/ 1 0%
Info: ICESTORM_SPRAM: 4/ 4 100%
So, looks like p_ENABLE_REGS_16_31=0
increases the ICESTORM_LC
usage from 3967 -> 3988!?
Setting p_ENABLE_IRQ_QREGS=0
and p_ENABLE_IRQ_TIMER=0
ended up with;
Info: Device utilisation:
Info: ICESTORM_LC: 3872/ 5280 73%
Info: ICESTORM_RAM: 4/ 30 13%
Info: SB_IO: 7/ 96 7%
Info: SB_GB: 8/ 8 100%
Info: ICESTORM_PLL: 0/ 1 0%
Info: SB_WARMBOOT: 0/ 1 0%
Info: ICESTORM_DSP: 0/ 8 0%
Info: ICESTORM_HFOSC: 0/ 1 0%
Info: ICESTORM_LFOSC: 0/ 1 0%
Info: SB_I2C: 0/ 2 0%
Info: SB_SPI: 0/ 2 0%
Info: IO_I3C: 0/ 2 0%
Info: SB_LEDDA_IP: 0/ 1 0%
Info: SB_RGBA_DRV: 0/ 1 0%
Info: ICESTORM_SPRAM: 4/ 4 100%
So they also seem to increase the resource usage....
Scratch that 3872 is less than 3967, so it saves about 95 ICESTORM_LC
cells....
Setting p_CATCH_ILLINSN=0
ended up with;
Info: Device utilisation:
Info: ICESTORM_LC: 3922/ 5280 74%
Info: ICESTORM_RAM: 4/ 30 13%
Info: SB_IO: 7/ 96 7%
Info: SB_GB: 8/ 8 100%
Info: ICESTORM_PLL: 0/ 1 0%
Info: SB_WARMBOOT: 0/ 1 0%
Info: ICESTORM_DSP: 0/ 8 0%
Info: ICESTORM_HFOSC: 0/ 1 0%
Info: ICESTORM_LFOSC: 0/ 1 0%
Info: SB_I2C: 0/ 2 0%
Info: SB_SPI: 0/ 2 0%
Info: IO_I3C: 0/ 2 0%
Info: SB_LEDDA_IP: 0/ 1 0%
Info: SB_RGBA_DRV: 0/ 1 0%
Info: ICESTORM_SPRAM: 4/ 4 100%
Setting p_CATCH_MISALIGN=1
definately increases the resource usage.
The smallest configuration I have gotten so far is the following;
Info: Device utilisation:
Info: ICESTORM_LC: 3872/ 5280 73%
Info: ICESTORM_RAM: 4/ 30 13%
Info: SB_IO: 7/ 96 7%
Info: SB_GB: 8/ 8 100%
Info: ICESTORM_PLL: 0/ 1 0%
Info: SB_WARMBOOT: 0/ 1 0%
Info: ICESTORM_DSP: 0/ 8 0%
Info: ICESTORM_HFOSC: 0/ 1 0%
Info: ICESTORM_LFOSC: 0/ 1 0%
Info: SB_I2C: 0/ 2 0%
Info: SB_SPI: 0/ 2 0%
Info: IO_I3C: 0/ 2 0%
Info: SB_LEDDA_IP: 0/ 1 0%
Info: SB_RGBA_DRV: 0/ 1 0%
Info: ICESTORM_SPRAM: 4/ 4 100%
It comes from the following patch;
diff --git a/litex/soc/cores/cpu/picorv32/core.py b/litex/soc/cores/cpu/picorv32/core.py
index 7fe830d6..b94fb7d7 100644
--- a/litex/soc/cores/cpu/picorv32/core.py
+++ b/litex/soc/cores/cpu/picorv32/core.py
@@ -9,7 +9,7 @@ class PicoRV32(Module):
name = "picorv32"
endianness = "little"
gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf")
- gcc_flags = "-D__picorv32__ -mno-save-restore -march=rv32im -mabi=ilp32"
+ gcc_flags = "-D__picorv32__ -mno-save-restore -march=rv32i -mabi=ilp32"
linker_output_format = "elf32-littleriscv"
def __init__(self, platform, progaddr_reset, variant):
@@ -31,23 +31,25 @@ class PicoRV32(Module):
self.specials += Instance("picorv32",
# parameters
- p_ENABLE_COUNTERS=1,
- p_ENABLE_COUNTERS64=1,
+ p_ENABLE_COUNTERS=0,
+ p_ENABLE_COUNTERS64=0,
+ # Changing REGS has no effect as on FPGAs, the registers are
+ # implemented using a register file stored in DPRAM.
p_ENABLE_REGS_16_31=1,
p_ENABLE_REGS_DUALPORT=1,
p_LATCHED_MEM_RDATA=0,
- p_TWO_STAGE_SHIFT=1,
+ p_TWO_STAGE_SHIFT=0,
p_TWO_CYCLE_COMPARE=0,
p_TWO_CYCLE_ALU=0,
- p_CATCH_MISALIGN=1,
+ p_CATCH_MISALIGN=0,
p_CATCH_ILLINSN=1,
p_ENABLE_PCPI=0,
- p_ENABLE_MUL=1,
- p_ENABLE_DIV=1,
+ p_ENABLE_MUL=0,
+ p_ENABLE_DIV=0,
p_ENABLE_FAST_MUL=0,
p_ENABLE_IRQ=1,
- p_ENABLE_IRQ_QREGS=1,
- p_ENABLE_IRQ_TIMER=1,
+ p_ENABLE_IRQ_QREGS=0,
+ p_ENABLE_IRQ_TIMER=0,
p_ENABLE_TRACE=0,
p_MASKED_IRQ=0x00000000,
p_LATCHED_IRQ=0xffffffff,
Other random comments;
I tried disabling the XIP spiflash core (using the following patch) and got the following resource usage;
Info: Device utilisation:
Info: ICESTORM_LC: 3708/ 5280 70%
Info: ICESTORM_RAM: 4/ 30 13%
Info: SB_IO: 3/ 96 3%
Info: SB_GB: 8/ 8 100%
Info: ICESTORM_PLL: 0/ 1 0%
Info: SB_WARMBOOT: 0/ 1 0%
Info: ICESTORM_DSP: 0/ 8 0%
Info: ICESTORM_HFOSC: 0/ 1 0%
Info: ICESTORM_LFOSC: 0/ 1 0%
Info: SB_I2C: 0/ 2 0%
Info: SB_SPI: 0/ 2 0%
Info: IO_I3C: 0/ 2 0%
Info: SB_LEDDA_IP: 0/ 1 0%
Info: SB_RGBA_DRV: 0/ 1 0%
Info: ICESTORM_SPRAM: 4/ 4 100%
diff --git a/targets/ice40_up5k_b_evn/base.py b/targets/ice40_up5k_b_evn/base.py
index d638094..dbaa814 100644
--- a/targets/ice40_up5k_b_evn/base.py
+++ b/targets/ice40_up5k_b_evn/base.py
@@ -78,14 +78,14 @@ class BaseSoC(SoCCore):
# self.submodules.cas = cas.ControlAndStatus(platform, clk_freq)
# SPI flash peripheral
- self.submodules.spiflash = spi_flash.SpiFlashSingle(
- platform.request("spiflash"),
- dummy=platform.spiflash_read_dummy_bits,
- div=platform.spiflash_clock_div)
+# self.submodules.spiflash = spi_flash.SpiFlashSingle(
+# platform.request("spiflash"),
+# dummy=platform.spiflash_read_dummy_bits,
+# div=platform.spiflash_clock_div)
self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size)
self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size)
- self.register_mem("spiflash", self.mem_map["spiflash"],
- self.spiflash.bus, size=platform.spiflash_total_size)
+# self.register_mem("spiflash", self.mem_map["spiflash"],
+# self.spiflash.bus, size=platform.spiflash_total_size)
bios_size = 0x8000
self.add_constant("ROM_DISABLE", 1)
So it looks like that core only uses 164 ICESTOM_LC
parts?
Looks like disabling the following, decreases the resource count;
+ kwargs['ident'] = False
+ kwargs['with_timer'] = False
+ kwargs['with_ctrl'] = False
To;
Info: Device utilisation:
Info: ICESTORM_LC: 3270/ 5280 61%
Info: ICESTORM_RAM: 4/ 30 13%
Info: SB_IO: 3/ 96 3%
Info: SB_GB: 8/ 8 100%
Info: ICESTORM_PLL: 0/ 1 0%
Info: SB_WARMBOOT: 0/ 1 0%
Info: ICESTORM_DSP: 0/ 8 0%
Info: ICESTORM_HFOSC: 0/ 1 0%
Info: ICESTORM_LFOSC: 0/ 1 0%
Info: SB_I2C: 0/ 2 0%
Info: SB_SPI: 0/ 2 0%
Info: IO_I3C: 0/ 2 0%
Info: SB_LEDDA_IP: 0/ 1 0%
Info: SB_RGBA_DRV: 0/ 1 0%
Info: ICESTORM_SPRAM: 4/ 4 100%
Doing that seems to remove all interrupt sources, see the warning below;
Warning: Wire top.\picorv32.irq [31] is used but has no driver.
Warning: Wire top.\picorv32.irq [30] is used but has no driver.
Warning: Wire top.\picorv32.irq [29] is used but has no driver.
Warning: Wire top.\picorv32.irq [28] is used but has no driver.
Warning: Wire top.\picorv32.irq [27] is used but has no driver.
Warning: Wire top.\picorv32.irq [26] is used but has no driver.
Warning: Wire top.\picorv32.irq [25] is used but has no driver.
Warning: Wire top.\picorv32.irq [24] is used but has no driver.
Warning: Wire top.\picorv32.irq [23] is used but has no driver.
Warning: Wire top.\picorv32.irq [22] is used but has no driver.
Warning: Wire top.\picorv32.irq [21] is used but has no driver.
Warning: Wire top.\picorv32.irq [20] is used but has no driver.
Warning: Wire top.\picorv32.irq [19] is used but has no driver.
Warning: Wire top.\picorv32.irq [18] is used but has no driver.
Warning: Wire top.\picorv32.irq [17] is used but has no driver.
Warning: Wire top.\picorv32.irq [16] is used but has no driver.
Warning: Wire top.\picorv32.irq [15] is used but has no driver.
Warning: Wire top.\picorv32.irq [14] is used but has no driver.
Warning: Wire top.\picorv32.irq [13] is used but has no driver.
Warning: Wire top.\picorv32.irq [12] is used but has no driver.
Warning: Wire top.\picorv32.irq [11] is used but has no driver.
Warning: Wire top.\picorv32.irq [10] is used but has no driver.
Warning: Wire top.\picorv32.irq [9] is used but has no driver.
Warning: Wire top.\picorv32.irq [8] is used but has no driver.
Warning: Wire top.\picorv32.irq [7] is used but has no driver.
Warning: Wire top.\picorv32.irq [6] is used but has no driver.
Warning: Wire top.\picorv32.irq [5] is used but has no driver.
Warning: Wire top.\picorv32.irq [4] is used but has no driver.
Warning: Wire top.\picorv32.irq [3] is used but has no driver.
Warning: Wire top.\picorv32.irq [1] is used but has no driver.
Warning: Wire top.\picorv32.irq [0] is used but has no driver.
Re-enabling the timer ends up with;
Info: Device utilisation:
Info: ICESTORM_LC: 3604/ 5280 68%
Info: ICESTORM_RAM: 4/ 30 13%
Info: SB_IO: 3/ 96 3%
Info: SB_GB: 8/ 8 100%
Info: ICESTORM_PLL: 0/ 1 0%
Info: SB_WARMBOOT: 0/ 1 0%
Info: ICESTORM_DSP: 0/ 8 0%
Info: ICESTORM_HFOSC: 0/ 1 0%
Info: ICESTORM_LFOSC: 0/ 1 0%
Info: SB_I2C: 0/ 2 0%
Info: SB_SPI: 0/ 2 0%
Info: IO_I3C: 0/ 2 0%
Info: SB_LEDDA_IP: 0/ 1 0%
Info: SB_RGBA_DRV: 0/ 1 0%
Info: ICESTORM_SPRAM: 4/ 4 100%
So it looks like a lot of resources is going into the FIFO buffers for the UART. https://github.com/enjoy-digital/litex/blob/f916705313f6b556f66d931a0c2b0d5d18825f09/litex/soc/cores/uart.py#L165-L166
Change the values from the default of 16, to the value of 2 does the following:
Info: ICESTORM_LC: 3604/ 5280 68%
- Before Info: ICESTORM_LC: 3090/ 5280 58%
- After The issue seems to be the FIFOs provided by stream.py
(see below) are not getting mapped to the block ram inside the iCE40.
https://github.com/enjoy-digital/litex/blob/f916705313f6b556f66d931a0c2b0d5d18825f09/litex/soc/interconnect/stream.py#L58-L108
The actual FIFOs come from the migen.genlib.fifo
module.
I'm guessing the issue is actually with the Verilog code being emitted by the migen.genlib.fhdl.specials.Memory
object.
This seems to be the Verilog code generated for the FIFOs used in the UART;
reg [9:0] storage[0:15];
reg [9:0] memdat;
always @(posedge sys_clk) begin
if (uart_tx_fifo_wrport_we)
storage[uart_tx_fifo_wrport_adr] <= uart_tx_fifo_wrport_dat_w;
memdat <= storage[uart_tx_fifo_wrport_adr];
end
always @(posedge sys_clk) begin
end
assign uart_tx_fifo_wrport_dat_r = memdat;
assign uart_tx_fifo_rdport_dat_r = storage[uart_tx_fifo_rdport_adr];
reg [9:0] storage_1[0:15];
reg [9:0] memdat_1;
always @(posedge sys_clk) begin
if (uart_rx_fifo_wrport_we)
storage_1[uart_rx_fifo_wrport_adr] <= uart_rx_fifo_wrport_dat_w;
memdat_1 <= storage_1[uart_rx_fifo_wrport_adr];
end
always @(posedge sys_clk) begin
end
assign uart_rx_fifo_wrport_dat_r = memdat_1;
assign uart_rx_fifo_rdport_dat_r = storage_1[uart_rx_fifo_rdport_adr];
With just the change in https://github.com/enjoy-digital/litex/pull/118 the resource count goes from Info: ICESTORM_LC: 5668/ 5280 107%
to Info: ICESTORM_LC: 5005/ 5280 94%
.
The changes in https://github.com/enjoy-digital/litex/compare/master...mithro:picorv32-minimal?expand=1 seem to reduce the resource usage down to Info: ICESTORM_LC: 3129/ 5280 59%
.
This the minimal picorv32 shown at https://github.com/mithro/litex/blob/01ce22b0c15e281983084eec60ba11c6babac176/litex/soc/cores/cpu/picorv32/core.py and pull request #118 a pretty normal litex-soc using XIP spiflash has the following usage;
Info: Device utilisation:
Info: ICESTORM_LC: 3439/ 5280 65%
Info: ICESTORM_RAM: 6/ 30 20%
Info: SB_IO: 7/ 96 7%
Info: SB_GB: 8/ 8 100%
Info: ICESTORM_PLL: 0/ 1 0%
Info: SB_WARMBOOT: 0/ 1 0%
Info: ICESTORM_DSP: 0/ 8 0%
Info: ICESTORM_HFOSC: 0/ 1 0%
Info: ICESTORM_LFOSC: 0/ 1 0%
Info: SB_I2C: 0/ 2 0%
Info: SB_SPI: 0/ 2 0%
Info: IO_I3C: 0/ 2 0%
Info: SB_LEDDA_IP: 0/ 1 0%
Info: SB_RGBA_DRV: 0/ 1 0%
Info: ICESTORM_SPRAM: 4/ 4 100%
This is small enough I'm going to hand over to @cr1901 to create a proper variant and check things actually work.
Thanks for the number. To allow the FIFO to use block_ram, you can probably add buffered=True
to https://github.com/enjoy-digital/litex/blob/master/litex/soc/cores/uart.py#L160. But for small configuration, we should probably reduce FIFO depth as you did.
Sorry, i just saw https://github.com/enjoy-digital/litex/pull/118 :)
@cr1901 - so what is the status here now?
@mithro This can be safely closed.
Was looking at that "variants" the picorv32 supported and found out it is not checking (or using) the variant CPU config at all.
See https://github.com/enjoy-digital/litex/blob/a44181e7166da1d15d68ffe00d6ed36db0dda72a/litex/soc/cores/cpu/picorv32/core.py#L15