From 5240d288172e644fb7e06a278219052cb25d7386 Mon Sep 17 00:00:00 2001
From: Icenowy Zheng <uwu@icenowy.me>
Date: Sun, 30 Oct 2022 19:55:36 +0800
Subject: [PATCH] cpu/openc906: fixes to get it work again

We made the bus width of C906 wrong at first, and when we convert its
external interface from AXI-Lite to AXI, it's id width is wrong too.

In addition, the AXI down converter of LiteX is quite weird, so a AXI2WB
bridge is integrated into the core now, like what is done in CVA6.

Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
---
 litex/soc/cores/cpu/openc906/core.py | 86 +++++++++++++++-------------
 1 file changed, 47 insertions(+), 39 deletions(-)

diff --git a/litex/soc/cores/cpu/openc906/core.py b/litex/soc/cores/cpu/openc906/core.py
index 8a69de0fa..641f14526 100644
--- a/litex/soc/cores/cpu/openc906/core.py
+++ b/litex/soc/cores/cpu/openc906/core.py
@@ -11,6 +11,7 @@ from migen import *
 
 from litex import get_data_mod
 from litex.soc.interconnect import axi
+from litex.soc.interconnect import wishbone
 from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_RISCV64
 
 # Helpers ------------------------------------------------------------------------------------------
@@ -34,7 +35,7 @@ class OpenC906(CPU):
     name                 = "openc906"
     human_name           = "OpenC906"
     variants             = ["standard"]
-    data_width           = 64
+    data_width           = 128
     endianness           = "little"
     gcc_triple           = CPU_GCC_TRIPLE_RISCV64
     linker_output_format = "elf64-littleriscv"
@@ -62,13 +63,20 @@ class OpenC906(CPU):
             "csr":            0xa000_0000, # Region 1 too
         }
 
-    def __init__(self, platform, variant="standard"):
+    def __init__(self, platform, variant="standard", convert_periph_bus_to_wishbone=True):
         self.platform     = platform
         self.variant      = variant
         self.reset        = Signal()
         self.interrupt    = Signal(240)
-        self.axi_if       = axi.AXIInterface(data_width=64, address_width=40)
-        self.periph_buses = [self.axi_if] # Peripheral buses (Connected to main SoC's bus).
+        # Peripheral bus (Connected to main SoC's bus).
+        self.axi_if = axi_if = axi.AXIInterface(data_width=128, address_width=40, id_width=8)
+        if convert_periph_bus_to_wishbone:
+            self.wb_if = wishbone.Interface(data_width=axi_if.data_width,
+                                            adr_width=axi_if.address_width - log2_int(axi_if.data_width // 8))
+            self.submodules += axi.AXI2Wishbone(axi_if, self.wb_if)
+            self.periph_buses = [self.wb_if]
+        else:
+            self.periph_buses = [axi_if]
         self.memory_buses = []                 # Memory buses (Connected directly to LiteDRAM).
 
         # # #
@@ -97,45 +105,45 @@ class OpenC906(CPU):
             i_pad_cpu_sys_cnt  = cycle_count,
 
             # AXI.
-            o_biu_pad_awvalid  = self.axi_if.aw.valid,
-            i_pad_biu_awready  = self.axi_if.aw.ready,
-            o_biu_pad_awid     = self.axi_if.aw.id,
-            o_biu_pad_awaddr   = self.axi_if.aw.addr,
-            o_biu_pad_awlen    = self.axi_if.aw.len,
-            o_biu_pad_awsize   = self.axi_if.aw.size,
-            o_biu_pad_awburst  = self.axi_if.aw.burst,
-            o_biu_pad_awlock   = self.axi_if.aw.lock,
-            o_biu_pad_awcache  = self.axi_if.aw.cache,
-            o_biu_pad_awprot   = self.axi_if.aw.prot,
+            o_biu_pad_awvalid  = axi_if.aw.valid,
+            i_pad_biu_awready  = axi_if.aw.ready,
+            o_biu_pad_awid     = axi_if.aw.id,
+            o_biu_pad_awaddr   = axi_if.aw.addr,
+            o_biu_pad_awlen    = axi_if.aw.len,
+            o_biu_pad_awsize   = axi_if.aw.size,
+            o_biu_pad_awburst  = axi_if.aw.burst,
+            o_biu_pad_awlock   = axi_if.aw.lock,
+            o_biu_pad_awcache  = axi_if.aw.cache,
+            o_biu_pad_awprot   = axi_if.aw.prot,
 
-            o_biu_pad_wvalid   = self.axi_if.w.valid,
-            i_pad_biu_wready   = self.axi_if.w.ready,
-            o_biu_pad_wdata    = self.axi_if.w.data,
-            o_biu_pad_wstrb    = self.axi_if.w.strb,
-            o_biu_pad_wlast    = self.axi_if.w.last,
+            o_biu_pad_wvalid   = axi_if.w.valid,
+            i_pad_biu_wready   = axi_if.w.ready,
+            o_biu_pad_wdata    = axi_if.w.data,
+            o_biu_pad_wstrb    = axi_if.w.strb,
+            o_biu_pad_wlast    = axi_if.w.last,
 
-            i_pad_biu_bvalid   = self.axi_if.b.valid,
-            o_biu_pad_bready   = self.axi_if.b.ready,
-            i_pad_biu_bid      = self.axi_if.b.id,
-            i_pad_biu_bresp    = self.axi_if.b.resp,
+            i_pad_biu_bvalid   = axi_if.b.valid,
+            o_biu_pad_bready   = axi_if.b.ready,
+            i_pad_biu_bid      = axi_if.b.id,
+            i_pad_biu_bresp    = axi_if.b.resp,
 
-            o_biu_pad_arvalid  = self.axi_if.ar.valid,
-            i_pad_biu_arready  = self.axi_if.ar.ready,
-            o_biu_pad_arid     = self.axi_if.ar.id,
-            o_biu_pad_araddr   = self.axi_if.ar.addr,
-            o_biu_pad_arlen    = self.axi_if.ar.len,
-            o_biu_pad_arsize   = self.axi_if.ar.size,
-            o_biu_pad_arburst  = self.axi_if.ar.burst,
-            o_biu_pad_arlock   = self.axi_if.ar.lock,
-            o_biu_pad_arcache  = self.axi_if.ar.cache,
-            o_biu_pad_arprot   = self.axi_if.ar.prot,
+            o_biu_pad_arvalid  = axi_if.ar.valid,
+            i_pad_biu_arready  = axi_if.ar.ready,
+            o_biu_pad_arid     = axi_if.ar.id,
+            o_biu_pad_araddr   = axi_if.ar.addr,
+            o_biu_pad_arlen    = axi_if.ar.len,
+            o_biu_pad_arsize   = axi_if.ar.size,
+            o_biu_pad_arburst  = axi_if.ar.burst,
+            o_biu_pad_arlock   = axi_if.ar.lock,
+            o_biu_pad_arcache  = axi_if.ar.cache,
+            o_biu_pad_arprot   = axi_if.ar.prot,
 
-            i_pad_biu_rvalid   = self.axi_if.r.valid,
-            o_biu_pad_rready   = self.axi_if.r.ready,
-            i_pad_biu_rid      = self.axi_if.r.id,
-            i_pad_biu_rdata    = self.axi_if.r.data,
-            i_pad_biu_rresp    = self.axi_if.r.resp,
-            i_pad_biu_rlast    = self.axi_if.r.last,
+            i_pad_biu_rvalid   = axi_if.r.valid,
+            o_biu_pad_rready   = axi_if.r.ready,
+            i_pad_biu_rid      = axi_if.r.id,
+            i_pad_biu_rdata    = axi_if.r.data,
+            i_pad_biu_rresp    = axi_if.r.resp,
+            i_pad_biu_rlast    = axi_if.r.last,
         )
 
         # Add Verilog sources.