qf100: add sky130 sram, rejigger bram in tests
parent
ef37383d10
commit
4e7b4ee21e
|
@ -11,34 +11,46 @@ bluespec_library(
|
||||||
"//wishbone/peripherals:spi",
|
"//wishbone/peripherals:spi",
|
||||||
"//wishbone/peripherals:gpio",
|
"//wishbone/peripherals:gpio",
|
||||||
"//systems/qf100",
|
"//systems/qf100",
|
||||||
|
"//systems/qf100:sky130_sram",
|
||||||
|
"//systems/qf100:spi_flash_emulator",
|
||||||
],
|
],
|
||||||
synthesize = {
|
synthesize = {
|
||||||
"Board": [
|
"Board": [
|
||||||
"mkQF105",
|
"mkQF105",
|
||||||
|
"mkQF100SPIFlashEmulator",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
data = [
|
data = [
|
||||||
":bram.bin",
|
":flash.bin",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
rtl_bundle(
|
rtl_bundle(
|
||||||
name = "qf100",
|
name = "qf100",
|
||||||
|
srcs = [
|
||||||
|
":sky130_sram_2kbyte_1rw1r_32x512_8.v"
|
||||||
|
],
|
||||||
outputs = {
|
outputs = {
|
||||||
"mkLanaiCPU": [],
|
"mkLanaiCPU": [],
|
||||||
"mkQF100Memory": [],
|
"mkLanaiFrontend": [],
|
||||||
"mkQF100SPI": [],
|
"mkQF100SPI": [],
|
||||||
"mkQF100GPIO": [],
|
"mkQF100GPIO": [],
|
||||||
|
"mkQF100KSC": [],
|
||||||
"mkQF100Fabric": [],
|
"mkQF100Fabric": [],
|
||||||
|
"mkQF100FlashController": [],
|
||||||
"mkQF105": [
|
"mkQF105": [
|
||||||
"mkLanaiCPU",
|
"mkLanaiCPU",
|
||||||
"mkQF100Memory",
|
"mkLanaiFrontend",
|
||||||
"mkQF100SPI",
|
"mkQF100SPI",
|
||||||
"mkQF100GPIO",
|
"mkQF100GPIO",
|
||||||
|
"mkQF100KSC",
|
||||||
"mkQF100Fabric",
|
"mkQF100Fabric",
|
||||||
|
"mkQF100FlashController",
|
||||||
|
"sky130_sram_2kbyte_1rw1r_32x512_8",
|
||||||
],
|
],
|
||||||
|
"mkQF100SPIFlashEmulator": [],
|
||||||
},
|
},
|
||||||
deps = [
|
deps = [
|
||||||
":QF100"
|
":QF100",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,6 +8,7 @@ import Connectable :: *;
|
||||||
import TieOff :: *;
|
import TieOff :: *;
|
||||||
|
|
||||||
import QF100 :: *;
|
import QF100 :: *;
|
||||||
|
import Sky130SRAM :: *;
|
||||||
|
|
||||||
import Lanai_IFC :: *;
|
import Lanai_IFC :: *;
|
||||||
import Lanai_CPU :: *;
|
import Lanai_CPU :: *;
|
||||||
|
@ -17,6 +18,14 @@ import WishboneCrossbar :: *;
|
||||||
import WishboneSPI :: *;
|
import WishboneSPI :: *;
|
||||||
import WishboneGPIO :: *;
|
import WishboneGPIO :: *;
|
||||||
|
|
||||||
|
import SPIFlashEmulator :: *;
|
||||||
|
|
||||||
|
(* synthesize *)
|
||||||
|
module mkQF100SPIFlashEmulator(SPIFlashEmulator);
|
||||||
|
let res <- mkSPIFlashEmulator("boards/qf100/flash.bin");
|
||||||
|
return res;
|
||||||
|
endmodule
|
||||||
|
|
||||||
interface CaravelUserProject;
|
interface CaravelUserProject;
|
||||||
// Logic Analyzer signals
|
// Logic Analyzer signals
|
||||||
(* always_ready, always_enabled, prefix="" *)
|
(* always_ready, always_enabled, prefix="" *)
|
||||||
|
@ -59,6 +68,10 @@ typedef struct {
|
||||||
|
|
||||||
module mkQF105Inner(CaravelUserProject);
|
module mkQF105Inner(CaravelUserProject);
|
||||||
let qf100 <- mkQF100;
|
let qf100 <- mkQF100;
|
||||||
|
let sram <- mkSky130SRAM;
|
||||||
|
|
||||||
|
mkConnection(qf100.ram_imem, sram.portB);
|
||||||
|
mkConnection(qf100.ram_dmem, sram.portA);
|
||||||
|
|
||||||
method Bit#(128) la_out = 0;
|
method Bit#(128) la_out = 0;
|
||||||
method Bit#(3) irq = 0;
|
method Bit#(3) irq = 0;
|
||||||
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
// OpenRAM SRAM model
|
||||||
|
// Words: 512
|
||||||
|
// Word size: 32
|
||||||
|
// Write size: 8
|
||||||
|
|
||||||
|
module sky130_sram_2kbyte_1rw1r_32x512_8(
|
||||||
|
`ifdef USE_POWER_PINS
|
||||||
|
vccd1,
|
||||||
|
vssd1,
|
||||||
|
`endif
|
||||||
|
// Port 0: RW
|
||||||
|
clk0,csb0,web0,wmask0,addr0,din0,dout0,
|
||||||
|
// Port 1: R
|
||||||
|
clk1,csb1,addr1,dout1
|
||||||
|
);
|
||||||
|
|
||||||
|
parameter NUM_WMASKS = 4 ;
|
||||||
|
parameter DATA_WIDTH = 32 ;
|
||||||
|
parameter ADDR_WIDTH = 9 ;
|
||||||
|
parameter RAM_DEPTH = 1 << ADDR_WIDTH;
|
||||||
|
// FIXME: This delay is arbitrary.
|
||||||
|
parameter DELAY = 3 ;
|
||||||
|
parameter VERBOSE = 1 ; //Set to 0 to only display warnings
|
||||||
|
parameter T_HOLD = 1 ; //Delay to hold dout value after posedge. Value is arbitrary
|
||||||
|
|
||||||
|
`ifdef USE_POWER_PINS
|
||||||
|
inout vccd1;
|
||||||
|
inout vssd1;
|
||||||
|
`endif
|
||||||
|
input clk0; // clock
|
||||||
|
input csb0; // active low chip select
|
||||||
|
input web0; // active low write control
|
||||||
|
input [NUM_WMASKS-1:0] wmask0; // write mask
|
||||||
|
input [ADDR_WIDTH-1:0] addr0;
|
||||||
|
input [DATA_WIDTH-1:0] din0;
|
||||||
|
output [DATA_WIDTH-1:0] dout0;
|
||||||
|
input clk1; // clock
|
||||||
|
input csb1; // active low chip select
|
||||||
|
input [ADDR_WIDTH-1:0] addr1;
|
||||||
|
output [DATA_WIDTH-1:0] dout1;
|
||||||
|
|
||||||
|
reg csb0_reg;
|
||||||
|
reg web0_reg;
|
||||||
|
reg [NUM_WMASKS-1:0] wmask0_reg;
|
||||||
|
reg [ADDR_WIDTH-1:0] addr0_reg;
|
||||||
|
reg [DATA_WIDTH-1:0] din0_reg;
|
||||||
|
reg [DATA_WIDTH-1:0] dout0;
|
||||||
|
|
||||||
|
// All inputs are registers
|
||||||
|
always @(posedge clk0)
|
||||||
|
begin
|
||||||
|
csb0_reg = csb0;
|
||||||
|
web0_reg = web0;
|
||||||
|
wmask0_reg = wmask0;
|
||||||
|
addr0_reg = addr0;
|
||||||
|
din0_reg = din0;
|
||||||
|
#(T_HOLD) dout0 = 32'bx;
|
||||||
|
if ( !csb0_reg && web0_reg && VERBOSE )
|
||||||
|
$display($time," Reading %m addr0=%b dout0=%b",addr0_reg,mem[addr0_reg]);
|
||||||
|
if ( !csb0_reg && !web0_reg && VERBOSE )
|
||||||
|
$display($time," Writing %m addr0=%b din0=%b wmask0=%b",addr0_reg,din0_reg,wmask0_reg);
|
||||||
|
end
|
||||||
|
|
||||||
|
reg csb1_reg;
|
||||||
|
reg [ADDR_WIDTH-1:0] addr1_reg;
|
||||||
|
reg [DATA_WIDTH-1:0] dout1;
|
||||||
|
|
||||||
|
// All inputs are registers
|
||||||
|
always @(posedge clk1)
|
||||||
|
begin
|
||||||
|
csb1_reg = csb1;
|
||||||
|
addr1_reg = addr1;
|
||||||
|
if (!csb0 && !web0 && !csb1 && (addr0 == addr1))
|
||||||
|
$display($time," WARNING: Writing and reading addr0=%b and addr1=%b simultaneously!",addr0,addr1);
|
||||||
|
#(T_HOLD) dout1 = 32'bx;
|
||||||
|
if ( !csb1_reg && VERBOSE )
|
||||||
|
$display($time," Reading %m addr1=%b dout1=%b",addr1_reg,mem[addr1_reg]);
|
||||||
|
end
|
||||||
|
|
||||||
|
reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
|
||||||
|
|
||||||
|
// Memory Write Block Port 0
|
||||||
|
// Write Operation : When web0 = 0, csb0 = 0
|
||||||
|
always @ (negedge clk0)
|
||||||
|
begin : MEM_WRITE0
|
||||||
|
if ( !csb0_reg && !web0_reg ) begin
|
||||||
|
if (wmask0_reg[0])
|
||||||
|
mem[addr0_reg][7:0] = din0_reg[7:0];
|
||||||
|
if (wmask0_reg[1])
|
||||||
|
mem[addr0_reg][15:8] = din0_reg[15:8];
|
||||||
|
if (wmask0_reg[2])
|
||||||
|
mem[addr0_reg][23:16] = din0_reg[23:16];
|
||||||
|
if (wmask0_reg[3])
|
||||||
|
mem[addr0_reg][31:24] = din0_reg[31:24];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// Memory Read Block Port 0
|
||||||
|
// Read Operation : When web0 = 1, csb0 = 0
|
||||||
|
always @ (negedge clk0)
|
||||||
|
begin : MEM_READ0
|
||||||
|
if (!csb0_reg && web0_reg)
|
||||||
|
dout0 <= #(DELAY) mem[addr0_reg];
|
||||||
|
end
|
||||||
|
|
||||||
|
// Memory Read Block Port 1
|
||||||
|
// Read Operation : When web1 = 1, csb1 = 0
|
||||||
|
always @ (negedge clk1)
|
||||||
|
begin : MEM_READ1
|
||||||
|
if (!csb1_reg)
|
||||||
|
dout1 <= #(DELAY) mem[addr1_reg];
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module sky130_sram_2kbyte_1rw1r_32x512_8_wrapper(
|
||||||
|
`ifdef USE_POWER_PINS
|
||||||
|
vccd1,
|
||||||
|
vssd1,
|
||||||
|
`endif
|
||||||
|
// Port 0: RW
|
||||||
|
clk0,cs0,web0,wmask0,addr0,din0,dout0,
|
||||||
|
// Port 1: R
|
||||||
|
clk1,cs1,addr1,dout1
|
||||||
|
);
|
||||||
|
|
||||||
|
parameter NUM_WMASKS = 4 ;
|
||||||
|
parameter DATA_WIDTH = 32 ;
|
||||||
|
parameter ADDR_WIDTH = 9 ;
|
||||||
|
parameter RAM_DEPTH = 1 << ADDR_WIDTH;
|
||||||
|
// FIXME: This delay is arbitrary.
|
||||||
|
parameter DELAY = 3 ;
|
||||||
|
parameter VERBOSE = 1 ; //Set to 0 to only display warnings
|
||||||
|
parameter T_HOLD = 1 ; //Delay to hold dout value after posedge. Value is arbitrary
|
||||||
|
|
||||||
|
`ifdef USE_POWER_PINS
|
||||||
|
inout vccd1;
|
||||||
|
inout vssd1;
|
||||||
|
`endif
|
||||||
|
input clk0; // clock
|
||||||
|
input cs0; // active high chip select
|
||||||
|
input web0; // active low write control
|
||||||
|
input [NUM_WMASKS-1:0] wmask0; // write mask
|
||||||
|
input [ADDR_WIDTH-1:0] addr0;
|
||||||
|
input [DATA_WIDTH-1:0] din0;
|
||||||
|
output [DATA_WIDTH-1:0] dout0;
|
||||||
|
input clk1; // clock
|
||||||
|
input cs1; // active high chip select
|
||||||
|
input [ADDR_WIDTH-1:0] addr1;
|
||||||
|
output [DATA_WIDTH-1:0] dout1;
|
||||||
|
sky130_sram_2kbyte_1rw1r_32x512_8 inner(
|
||||||
|
`ifdef USE_POWER_PINS
|
||||||
|
.vccd1(vccd1),
|
||||||
|
.vssd1(vssd1),
|
||||||
|
`endif
|
||||||
|
.clk0(clk0), .csb0(!cs0), .web0(web0), .wmask0(wmask0), .addr0(addr0), .din0(din0), .dout0(dout0),
|
||||||
|
.clk1(clk1), .csb1(!cs1), .addr1(addr1), .dout1(dout1)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
|
@ -6,7 +6,7 @@ bluespec_library(
|
||||||
"LanaiFrontend.bsv",
|
"LanaiFrontend.bsv",
|
||||||
],
|
],
|
||||||
synthesize = {
|
synthesize = {
|
||||||
#"SPIFlashController": ["mkTbFlashController"],
|
"LanaiFrontend": ["mkLanaiFrontend"],
|
||||||
},
|
},
|
||||||
deps = [
|
deps = [
|
||||||
"//lanai",
|
"//lanai",
|
||||||
|
|
|
@ -76,6 +76,7 @@ module mkFork(Fork#(t)) provisos (Routable#(t), Bits#(t, _));
|
||||||
endinterface
|
endinterface
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
(* synthesize *)
|
||||||
module mkLanaiFrontend(LanaiFrontend);
|
module mkLanaiFrontend(LanaiFrontend);
|
||||||
Fork#(Word) forkIMem <- mkFork;
|
Fork#(Word) forkIMem <- mkFork;
|
||||||
Fork#(DMemReq) forkDMem <- mkFork;
|
Fork#(DMemReq) forkDMem <- mkFork;
|
||||||
|
|
|
@ -1,6 +1,22 @@
|
||||||
load("//build/bluespec:rules.bzl", "bluespec_library", "bluesim_test")
|
load("//build/bluespec:rules.bzl", "bluespec_library", "bluesim_test")
|
||||||
load("//build/synthesis:rules.bzl", "rtl_bundle")
|
load("//build/synthesis:rules.bzl", "rtl_bundle")
|
||||||
|
|
||||||
|
bluespec_library(
|
||||||
|
name = "sky130_sram",
|
||||||
|
srcs = [
|
||||||
|
"Sky130SRAM.bsv",
|
||||||
|
],
|
||||||
|
synthesize = {
|
||||||
|
"Sky130SRAM": [
|
||||||
|
"mkSky130SRAM",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
deps = [
|
||||||
|
"//lanai",
|
||||||
|
],
|
||||||
|
visibility = [ "//visibility:public" ],
|
||||||
|
)
|
||||||
|
|
||||||
bluespec_library(
|
bluespec_library(
|
||||||
name = "qf100",
|
name = "qf100",
|
||||||
srcs = [
|
srcs = [
|
||||||
|
@ -12,14 +28,17 @@ bluespec_library(
|
||||||
"//lanai/frontend:spi_flash_controller",
|
"//lanai/frontend:spi_flash_controller",
|
||||||
"//wishbone/peripherals:spi",
|
"//wishbone/peripherals:spi",
|
||||||
"//wishbone/peripherals:gpio",
|
"//wishbone/peripherals:gpio",
|
||||||
|
"//wishbone/peripherals:kitchen_sink",
|
||||||
],
|
],
|
||||||
synthesize = {
|
synthesize = {
|
||||||
"QF100": [
|
"QF100": [
|
||||||
"mkQF100",
|
"mkQF100",
|
||||||
"mkQF100Memory",
|
"mkQF100BlockRAM",
|
||||||
"mkQF100SPI",
|
"mkQF100SPI",
|
||||||
"mkQF100GPIO",
|
"mkQF100GPIO",
|
||||||
|
"mkQF100KSC",
|
||||||
"mkQF100Fabric",
|
"mkQF100Fabric",
|
||||||
|
"mkQF100FlashController",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
visibility = [ "//visibility:public" ],
|
visibility = [ "//visibility:public" ],
|
||||||
|
@ -36,6 +55,7 @@ bluespec_library(
|
||||||
],
|
],
|
||||||
deps = [
|
deps = [
|
||||||
":qf100",
|
":qf100",
|
||||||
|
":sky130_sram",
|
||||||
],
|
],
|
||||||
synthesize = {
|
synthesize = {
|
||||||
"Tb": [
|
"Tb": [
|
||||||
|
@ -58,4 +78,5 @@ bluespec_library(
|
||||||
srcs = [
|
srcs = [
|
||||||
"SPIFlashEmulator.bsv",
|
"SPIFlashEmulator.bsv",
|
||||||
],
|
],
|
||||||
|
visibility = [ "//visibility:public" ],
|
||||||
)
|
)
|
||||||
|
|
|
@ -15,21 +15,24 @@ import RAM :: *;
|
||||||
import WishboneCrossbar :: *;
|
import WishboneCrossbar :: *;
|
||||||
import WishboneSPI :: *;
|
import WishboneSPI :: *;
|
||||||
import WishboneGPIO :: *;
|
import WishboneGPIO :: *;
|
||||||
|
import WishboneKitchenSink :: *;
|
||||||
|
|
||||||
|
|
||||||
Bit#(1) wbAddrSPI = 0;
|
Bit#(2) wbAddrSPI = 0;
|
||||||
Bit#(1) wbAddrGPIO = 1;
|
Bit#(2) wbAddrGPIO = 1;
|
||||||
|
Bit#(2) wbAddrKSC = 2;
|
||||||
|
|
||||||
function Maybe#(WishboneCrossbar::DecodedAddr#(2, 32)) decoder(Bit#(32) address);
|
function Maybe#(WishboneCrossbar::DecodedAddr#(3, 32)) decoder(Bit#(32) address);
|
||||||
return case (address) matches
|
return case (address) matches
|
||||||
32'h4001_30??: tagged Valid DecodedAddr { downstream: wbAddrSPI, address: address & 32'hff };
|
32'h4001_30??: tagged Valid DecodedAddr { downstream: wbAddrSPI, address: address & 32'hff };
|
||||||
32'h4001_08??: tagged Valid DecodedAddr { downstream: wbAddrGPIO, address: address & 32'hff };
|
32'h4001_08??: tagged Valid DecodedAddr { downstream: wbAddrGPIO, address: address & 32'hff };
|
||||||
|
32'h4001_1c??: tagged Valid DecodedAddr { downstream: wbAddrKSC, address: address & 32'hff };
|
||||||
default: tagged Invalid;
|
default: tagged Invalid;
|
||||||
endcase;
|
endcase;
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
(* synthesize *)
|
(* synthesize *)
|
||||||
module mkQF100Memory(Lanai_BlockRAM#(2048));
|
module mkQF100BlockRAM(Lanai_BlockRAM#(2048));
|
||||||
Lanai_BlockRAM#(2048) inner <- mkBlockMemory(tagged Invalid);
|
Lanai_BlockRAM#(2048) inner <- mkBlockMemory(tagged Invalid);
|
||||||
return inner;
|
return inner;
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -50,22 +53,40 @@ module mkQF100GPIO(WishboneGPIO::GPIOController#(32));
|
||||||
method oe = res.oe;
|
method oe = res.oe;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
(* synthesize *)
|
||||||
|
module mkQF100KSC(WishboneKitchenSink::KitchenSinkController#(32));
|
||||||
|
let res <- mkKitchenSinkController;
|
||||||
|
interface slave = res.slave;
|
||||||
|
endmodule
|
||||||
|
|
||||||
interface QF100Fabric;
|
interface QF100Fabric;
|
||||||
interface Wishbone::Slave#(32, 32, 4) cpu;
|
interface Wishbone::Slave#(32, 32, 4) cpu;
|
||||||
interface Wishbone::Master#(32, 32, 4) spi;
|
interface Wishbone::Master#(32, 32, 4) spi;
|
||||||
interface Wishbone::Master#(32, 32, 4) gpio;
|
interface Wishbone::Master#(32, 32, 4) gpio;
|
||||||
|
interface Wishbone::Master#(32, 32, 4) ksc;
|
||||||
endinterface
|
endinterface
|
||||||
|
|
||||||
(* synthesize *)
|
(* synthesize *)
|
||||||
module mkQF100Fabric(QF100Fabric);
|
module mkQF100Fabric(QF100Fabric);
|
||||||
WishboneCrossbar::Crossbar#(1, 2, 32, 32, 4) fabric <- mkCrossbar(decoder);
|
WishboneCrossbar::Crossbar#(1, 3, 32, 32, 4) fabric <- mkCrossbar(decoder);
|
||||||
|
|
||||||
interface cpu = fabric.upstreams[0];
|
interface cpu = fabric.upstreams[0];
|
||||||
interface spi = fabric.downstreams[wbAddrSPI];
|
interface spi = fabric.downstreams[wbAddrSPI];
|
||||||
interface gpio = fabric.downstreams[wbAddrGPIO];
|
interface gpio = fabric.downstreams[wbAddrGPIO];
|
||||||
|
interface ksc = fabric.downstreams[wbAddrKSC];
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
(* synthesize *)
|
||||||
|
module mkQF100FlashController(SPIFlashController#(16, 16));
|
||||||
|
SPIFlashController#(16, 16) fmc <- mkSPIFlashController;
|
||||||
|
return fmc;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
interface QF100;
|
interface QF100;
|
||||||
|
// RAM.
|
||||||
|
interface Client#(Word, Word) ram_imem;
|
||||||
|
interface Client#(DMemReq, Word) ram_dmem;
|
||||||
|
|
||||||
// Memory SPI.
|
// Memory SPI.
|
||||||
interface WishboneSPI::Master mspi;
|
interface WishboneSPI::Master mspi;
|
||||||
(* always_ready *)
|
(* always_ready *)
|
||||||
|
@ -91,11 +112,7 @@ module mkQF100(QF100);
|
||||||
mkConnection(cpu.imem_client, frontend.core_imem);
|
mkConnection(cpu.imem_client, frontend.core_imem);
|
||||||
mkConnection(cpu.dmem_client, frontend.core_dmem);
|
mkConnection(cpu.dmem_client, frontend.core_dmem);
|
||||||
|
|
||||||
Lanai_BlockRAM#(2048) ram <- mkQF100Memory;
|
SPIFlashController#(16, 16) fmc <- mkQF100FlashController;
|
||||||
mkConnection(frontend.ram_imem, ram.memory.imem);
|
|
||||||
mkConnection(frontend.ram_dmem, ram.memory.dmem);
|
|
||||||
|
|
||||||
SPIFlashController#(16, 64) fmc <- mkSPIFlashController;
|
|
||||||
mkConnection(frontend.fmc_imem, fmc.serverA);
|
mkConnection(frontend.fmc_imem, fmc.serverA);
|
||||||
rule fmcDMemTranslate;
|
rule fmcDMemTranslate;
|
||||||
let req <- frontend.fmc_dmem.request.get();
|
let req <- frontend.fmc_dmem.request.get();
|
||||||
|
@ -112,6 +129,9 @@ module mkQF100(QF100);
|
||||||
WishboneGPIO::GPIOController#(32) gpioCtrl <- mkQF100GPIO;
|
WishboneGPIO::GPIOController#(32) gpioCtrl <- mkQF100GPIO;
|
||||||
mkConnection(fabric.gpio, gpioCtrl.slave);
|
mkConnection(fabric.gpio, gpioCtrl.slave);
|
||||||
|
|
||||||
|
WishboneKitchenSink::KitchenSinkController#(32) ksCtrl <- mkQF100KSC;
|
||||||
|
mkConnection(fabric.ksc, ksCtrl.slave);
|
||||||
|
|
||||||
interface mspi = fmc.spi;
|
interface mspi = fmc.spi;
|
||||||
method Bool mspi_csb;
|
method Bool mspi_csb;
|
||||||
return unpack(fmc.csb);
|
return unpack(fmc.csb);
|
||||||
|
@ -120,6 +140,8 @@ module mkQF100(QF100);
|
||||||
method gpio_oe = gpioCtrl.oe;
|
method gpio_oe = gpioCtrl.oe;
|
||||||
method gpio_out = gpioCtrl.out;
|
method gpio_out = gpioCtrl.out;
|
||||||
method gpio_in = gpioCtrl.in;
|
method gpio_in = gpioCtrl.in;
|
||||||
|
interface ram_imem = frontend.ram_imem;
|
||||||
|
interface ram_dmem = frontend.ram_dmem;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
endpackage
|
endpackage
|
||||||
|
|
|
@ -0,0 +1,144 @@
|
||||||
|
package Sky130SRAM;
|
||||||
|
|
||||||
|
import FIFO :: *;
|
||||||
|
import SpecialFIFOs :: *;
|
||||||
|
import GetPut :: *;
|
||||||
|
import ClientServer :: *;
|
||||||
|
import Lanai_Memory :: *;
|
||||||
|
import Lanai_IFC :: *;
|
||||||
|
|
||||||
|
interface Sky130SRAMCore;
|
||||||
|
method Action request0(Bit#(9) addr0, Bit#(32) din0, Bool web0, Bit#(4) wmask0);
|
||||||
|
method Bit#(32) response0;
|
||||||
|
|
||||||
|
method Action request1(Bit#(9) addr1);
|
||||||
|
method Bit#(32) response1;
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
import "BVI" sky130_sram_2kbyte_1rw1r_32x512_8_wrapper =
|
||||||
|
module mkSky130SRAMCore#(Clock clk0, Reset rst0, Clock rclk1, Reset rst1)(Sky130SRAMCore);
|
||||||
|
default_clock no_clock;
|
||||||
|
default_reset no_reset;
|
||||||
|
|
||||||
|
input_clock clk0(clk0, (*unused*)clk0_gate) = clk0;
|
||||||
|
input_reset rsb0() = rst0;
|
||||||
|
input_reset rsb1() = rst1;
|
||||||
|
method request0(addr0, din0, web0, wmask0) clocked_by (clk0) enable (cs0);
|
||||||
|
method dout0 response0 clocked_by (clk0);
|
||||||
|
|
||||||
|
schedule (response0) SB (request0);
|
||||||
|
|
||||||
|
input_clock clk1(clk1, (*unused*)clk1_gate) = clk0;
|
||||||
|
method request1(addr1) clocked_by (clk1) enable (cs1);
|
||||||
|
method dout1 response1 clocked_by (clk1);
|
||||||
|
|
||||||
|
schedule (response1) SB (request1);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
interface Sky130SRAM;
|
||||||
|
interface Server#(DMemReq, Word) portA;
|
||||||
|
interface Server#(Word, Word) portB;
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
(* synthesize *)
|
||||||
|
module mkSky130SRAM(Sky130SRAM);
|
||||||
|
Clock clk <- exposeCurrentClock;
|
||||||
|
Reset rst <- exposeCurrentReset;
|
||||||
|
let core <- mkSky130SRAMCore(clk, rst, clk, rst);
|
||||||
|
|
||||||
|
FIFO#(void) inFlight0 <- mkPipelineFIFO;
|
||||||
|
FIFO#(void) inFlight1 <- mkPipelineFIFO;
|
||||||
|
|
||||||
|
interface Server portA;
|
||||||
|
interface Put request;
|
||||||
|
method Action put(DMemReq req);
|
||||||
|
inFlight0.enq(?);
|
||||||
|
|
||||||
|
Bit#(4) wmask = 0;
|
||||||
|
Bit#(32) din = 0;
|
||||||
|
Bool web = False;
|
||||||
|
if (req.data matches tagged Valid .val) begin
|
||||||
|
web = True;
|
||||||
|
case (req.width) matches
|
||||||
|
tagged Word: begin
|
||||||
|
//$display("%x: DMEM WRITE REQ, word [%x] <- %x", req.pc, req.addr, val);
|
||||||
|
wmask = 4'b1111;
|
||||||
|
din = val;
|
||||||
|
end
|
||||||
|
tagged HalfWord: begin
|
||||||
|
Bit#(32) valH = zeroExtend(val[15:0]);
|
||||||
|
//$display("%x: DMEM WRITE REQ, hword [%x] <- %x", req.pc, req.addr, valH);
|
||||||
|
case (req.addr[1]) matches
|
||||||
|
1'b1: begin
|
||||||
|
wmask = 4'b0011;
|
||||||
|
din = valH;
|
||||||
|
end
|
||||||
|
1'b0: begin
|
||||||
|
wmask = 4'b1100;
|
||||||
|
din = valH << 16;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
if (req.addr[1] == 1) begin
|
||||||
|
wmask = 4'b1100;
|
||||||
|
din = val << 16;
|
||||||
|
end else begin
|
||||||
|
wmask = 4'b0011;
|
||||||
|
din = zeroExtend(val[15:0]);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
tagged Byte: begin
|
||||||
|
Bit#(32) valB = zeroExtend(val[7:0]);
|
||||||
|
//$display("%x: DMEM WRITE REQ, byte [%x] <- %x", req.pc, req.addr, valB);
|
||||||
|
case (req.addr[1:0]) matches
|
||||||
|
2'b11: begin
|
||||||
|
wmask = 4'b0001;
|
||||||
|
din = valB;
|
||||||
|
end
|
||||||
|
2'b10: begin
|
||||||
|
wmask = 4'b0010;
|
||||||
|
din = valB << 8;
|
||||||
|
end
|
||||||
|
2'b01: begin
|
||||||
|
wmask = 4'b0100;
|
||||||
|
din = valB << 16;
|
||||||
|
end
|
||||||
|
2'b00: begin
|
||||||
|
wmask = 4'b1000;
|
||||||
|
din = valB << 24;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
core.request0(req.addr[8:0], din, !web, wmask);
|
||||||
|
endmethod
|
||||||
|
endinterface
|
||||||
|
interface Get response;
|
||||||
|
method ActionValue#(Bit#(32)) get();
|
||||||
|
inFlight0.deq;
|
||||||
|
|
||||||
|
let res = core.response0;
|
||||||
|
return res;
|
||||||
|
endmethod
|
||||||
|
endinterface
|
||||||
|
endinterface
|
||||||
|
interface Server portB;
|
||||||
|
interface Put request;
|
||||||
|
method Action put(Bit#(32) address);
|
||||||
|
inFlight1.enq(?);
|
||||||
|
core.request1(address[8:0]);
|
||||||
|
endmethod
|
||||||
|
endinterface
|
||||||
|
interface Get response;
|
||||||
|
method ActionValue#(Bit#(32)) get();
|
||||||
|
inFlight1.deq;
|
||||||
|
|
||||||
|
let res = core.response1;
|
||||||
|
return res;
|
||||||
|
endmethod
|
||||||
|
endinterface
|
||||||
|
endinterface
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
endpackage
|
|
@ -1,15 +1,22 @@
|
||||||
package Tb;
|
package Tb;
|
||||||
|
|
||||||
import QF100 :: *;
|
import Assert :: *;
|
||||||
import SPIFlashEmulator :: *;
|
import Connectable :: *;
|
||||||
import StmtFSM :: *;
|
|
||||||
import WishboneSPI :: *;
|
import WishboneSPI :: *;
|
||||||
|
|
||||||
|
import QF100 :: *;
|
||||||
|
import Lanai_Memory :: *;
|
||||||
|
import SPIFlashEmulator :: *;
|
||||||
|
|
||||||
(* synthesize *)
|
(* synthesize *)
|
||||||
module mkTbQF100(Empty);
|
module mkTbQF100(Empty);
|
||||||
QF100 qf100 <- mkQF100;
|
QF100 qf100 <- mkQF100;
|
||||||
|
Lanai_BlockRAM#(2048) bram <- mkQF100BlockRAM;
|
||||||
SPIFlashEmulator emu <- mkSPIFlashEmulator("systems/qf100/flash.bin");
|
SPIFlashEmulator emu <- mkSPIFlashEmulator("systems/qf100/flash.bin");
|
||||||
|
|
||||||
|
mkConnection(qf100.ram_imem, bram.memory.imem);
|
||||||
|
mkConnection(qf100.ram_dmem, bram.memory.dmem);
|
||||||
|
|
||||||
rule feed_qf100_in;
|
rule feed_qf100_in;
|
||||||
qf100.gpio_in(0);
|
qf100.gpio_in(0);
|
||||||
qf100.spi.miso(False);
|
qf100.spi.miso(False);
|
||||||
|
@ -22,13 +29,18 @@ module mkTbQF100(Empty);
|
||||||
emu.csb(qf100.mspi_csb);
|
emu.csb(qf100.mspi_csb);
|
||||||
endrule
|
endrule
|
||||||
|
|
||||||
Reg#(Bit#(32)) tmp <- mkReg(0);
|
Reg#(Bit#(32)) counter <- mkReg(0);
|
||||||
Stmt test = seq
|
rule upcount;
|
||||||
for (tmp <= 0; tmp <= 20000; tmp <= tmp + 1) seq
|
counter <= counter + 1;
|
||||||
noAction;
|
endrule
|
||||||
endseq
|
rule timeout;
|
||||||
endseq;
|
dynamicAssert(counter < 40_000, "Timeout.");
|
||||||
mkAutoFSM(test);
|
endrule
|
||||||
|
rule findGPIOPatern;
|
||||||
|
if (qf100.gpio_out == 3) begin
|
||||||
|
$finish(0);
|
||||||
|
end
|
||||||
|
endrule
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
endpackage
|
endpackage
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
9293fffc
|
9293fffc
|
||||||
02900008
|
02900008
|
||||||
22100020
|
22100018
|
||||||
01814001
|
|
||||||
518c0800
|
|
||||||
9196fff4
|
|
||||||
90120004
|
90120004
|
||||||
01812000
|
01812000
|
||||||
518c0000
|
518c0000
|
||||||
|
@ -14,7 +11,7 @@ c1a41a00
|
||||||
91920008
|
91920008
|
||||||
07880010
|
07880010
|
||||||
9793fffc
|
9793fffc
|
||||||
e0000134
|
e00002d4
|
||||||
00000001
|
00000001
|
||||||
01812000
|
01812000
|
||||||
518c0010
|
518c0010
|
||||||
|
@ -23,54 +20,161 @@ e0000134
|
||||||
c4a41a00
|
c4a41a00
|
||||||
94920008
|
94920008
|
||||||
04810000
|
04810000
|
||||||
54a40170
|
54a40344
|
||||||
94920004
|
94920004
|
||||||
91900000
|
91900000
|
||||||
07880010
|
07880010
|
||||||
9793fffc
|
9793fffc
|
||||||
|
e0000290
|
||||||
|
00000001
|
||||||
|
01812000
|
||||||
|
518c0000
|
||||||
|
f4820001
|
||||||
|
948c0000
|
||||||
|
01812000
|
||||||
|
518c0010
|
||||||
|
06012000
|
||||||
|
56300004
|
||||||
|
91b00000
|
||||||
|
01812000
|
||||||
|
518c0008
|
||||||
|
948c0000
|
||||||
|
01812000
|
||||||
|
518c0810
|
||||||
|
04812000
|
||||||
|
54a4000c
|
||||||
|
07880010
|
||||||
|
9793fffc
|
||||||
|
e00000f8
|
||||||
|
91a40000
|
||||||
|
07880010
|
||||||
|
9793fffc
|
||||||
|
e0000138
|
||||||
|
00000001
|
||||||
|
9293fffc
|
||||||
|
02900008
|
||||||
|
22100008
|
||||||
|
81940000
|
||||||
|
0481dead
|
||||||
|
54a4c0de
|
||||||
|
91a40000
|
||||||
e00000f0
|
e00000f0
|
||||||
00000001
|
00000001
|
||||||
|
9293fffc
|
||||||
|
02900008
|
||||||
|
22100008
|
||||||
51800000
|
51800000
|
||||||
04812000
|
04814001
|
||||||
54a40000
|
54a4080c
|
||||||
f6020001
|
06011111
|
||||||
96240000
|
56301111
|
||||||
04812000
|
9626fff4
|
||||||
54a40010
|
9626fff8
|
||||||
06812000
|
862613f8
|
||||||
56b40004
|
468d0000
|
||||||
94b40000
|
96a40000
|
||||||
8696fff4
|
|
||||||
04812000
|
|
||||||
54a40008
|
|
||||||
96240000
|
|
||||||
04812000
|
|
||||||
54a40810
|
|
||||||
06012000
|
|
||||||
5630000c
|
|
||||||
94b00000
|
|
||||||
04811111
|
|
||||||
54a41111
|
|
||||||
94b40000
|
|
||||||
56340004
|
|
||||||
94b00000
|
|
||||||
448d0000
|
|
||||||
94b6000c
|
|
||||||
e00000e0
|
|
||||||
018c0001
|
018c0001
|
||||||
|
e0000124
|
||||||
|
96240000
|
||||||
|
9293fffc
|
||||||
|
02900008
|
||||||
|
22100018
|
||||||
|
01810000
|
||||||
|
518c0324
|
||||||
|
91920008
|
||||||
|
f1820006
|
||||||
|
91920004
|
||||||
|
01810000
|
||||||
|
518c031b
|
||||||
|
91900000
|
||||||
|
07880010
|
||||||
|
9793fffc
|
||||||
|
e000019c
|
||||||
|
00000001
|
||||||
|
07880010
|
||||||
|
9793fffc
|
||||||
|
e0000138
|
||||||
|
00000001
|
||||||
|
9293fffc
|
||||||
|
02900008
|
||||||
|
22100008
|
||||||
|
8116fffc
|
||||||
|
02140000
|
||||||
|
8296fff8
|
||||||
|
9293fffc
|
||||||
|
02900008
|
||||||
|
22100030
|
||||||
|
81960008
|
||||||
|
84940000
|
||||||
|
86160004
|
||||||
|
9496fff0
|
||||||
|
9616fff4
|
||||||
|
24940010
|
||||||
|
9496ffd8
|
||||||
|
f4820001
|
||||||
|
9496ffdc
|
||||||
|
9016ffe0
|
||||||
|
04810000
|
||||||
|
54a40334
|
||||||
|
9496ffe8
|
||||||
|
9016ffec
|
||||||
|
91920004
|
||||||
|
21940028
|
||||||
|
91900000
|
||||||
|
07880010
|
||||||
|
9793fffc
|
||||||
|
e000020c
|
||||||
|
00000001
|
||||||
|
07880010
|
||||||
|
9793fffc
|
||||||
|
e0000138
|
||||||
|
00000001
|
||||||
|
9293fffc
|
||||||
|
02900008
|
||||||
|
22100020
|
||||||
|
81960004
|
||||||
|
84940000
|
||||||
|
06010000
|
||||||
|
56300334
|
||||||
|
9616ffe8
|
||||||
|
06010000
|
||||||
|
56300334
|
||||||
|
9616ffec
|
||||||
|
9496fff0
|
||||||
|
9196fff4
|
||||||
|
21940018
|
||||||
|
91900000
|
||||||
|
07880010
|
||||||
|
9793fffc
|
||||||
|
e00000d4
|
||||||
|
00000001
|
||||||
|
07880010
|
||||||
|
9793fffc
|
||||||
|
e0000138
|
||||||
|
00000001
|
||||||
|
9293fffc
|
||||||
|
02900008
|
||||||
|
22100008
|
||||||
|
0181c859
|
||||||
|
540cc8f5
|
||||||
|
01813edc
|
||||||
|
548caf6c
|
||||||
|
8116fffc
|
||||||
|
02140000
|
||||||
|
8296fff8
|
||||||
9293fffc
|
9293fffc
|
||||||
02900008
|
02900008
|
||||||
22100008
|
22100008
|
||||||
81960008
|
81960008
|
||||||
200e0000
|
200e0000
|
||||||
e6000129
|
e60002c9
|
||||||
84140000
|
84140000
|
||||||
84960004
|
84960004
|
||||||
56200000
|
56200000
|
||||||
f6a75401
|
f6a75401
|
||||||
f6b36000
|
f6b36000
|
||||||
218e0001
|
218e0001
|
||||||
e6000114
|
e60002b4
|
||||||
06300001
|
06300001
|
||||||
8116fffc
|
8116fffc
|
||||||
02140000
|
02140000
|
||||||
|
@ -80,12 +184,12 @@ e6000114
|
||||||
22100008
|
22100008
|
||||||
81960008
|
81960008
|
||||||
200e0000
|
200e0000
|
||||||
e6000165
|
e6000305
|
||||||
84140000
|
84140000
|
||||||
84960004
|
84960004
|
||||||
56200000
|
56200000
|
||||||
218e0001
|
218e0001
|
||||||
e6000158
|
e60002f8
|
||||||
f4b36401
|
f4b36401
|
||||||
8116fffc
|
8116fffc
|
||||||
02140000
|
02140000
|
||||||
|
@ -8086,107 +8190,3 @@ f4b36401
|
||||||
00000000
|
00000000
|
||||||
00000000
|
00000000
|
||||||
00000000
|
00000000
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
00000000
|
|
||||||
|
|
Loading…
Reference in New Issue