Skip to content

Commit

Permalink
Use Mibuild
Browse files Browse the repository at this point in the history
Sebastien Bourdeauducq committed Feb 11, 2013
1 parent f68fcef commit 5649e88
Showing 9 changed files with 230 additions and 333 deletions.
24 changes: 2 additions & 22 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,27 +1,7 @@
PYTHON=python3

all: build/soc.bit

# We need to change to the build directory because the Xilinx tools
# tend to dump a mess of various files in the current directory.

build/soc.prj build/soc.ucf:
$(PYTHON) build.py

build/soc.ngc: build/soc.prj
cd build && xst -ifn ../soc.xst

build/soc.ngd: build/soc.ngc build/soc.ucf
cd build && ngdbuild -uc soc.ucf soc.ngc

build/soc.ncd: build/soc.ngd
cd build && map -ol high -w soc.ngd

build/soc-routed.ncd: build/soc.ncd
cd build && par -ol high -w soc.ncd soc-routed.ncd

build/soc.bit build/soc.bin: build/soc-routed.ncd
cd build && bitgen -g LCK_cycle:6 -g Binary:Yes -g INIT_9K:Yes -w soc-routed.ncd soc.bit
build/soc.bit build/soc.bin:
./build.py

load: build/soc.bit
jtag -n load.jtag
92 changes: 56 additions & 36 deletions build.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,43 +1,63 @@
#!/usr/bin/env python3

import os
from mibuild.platforms import m1
import top

# list Verilog sources before changing directory
verilog_sources = []
def add_core_dir(d):
root = os.path.join("verilog", d)
files = os.listdir(root)
for f in files:
if f[-2:] == ".v":
verilog_sources.append(os.path.join(root, f))
def add_core_files(d, files):
for f in files:
verilog_sources.append(os.path.join("verilog", d, f))
add_core_dir("generic")
add_core_dir("m1crg")
add_core_dir("s6ddrphy")
add_core_files("lm32", ["lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v",
"lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v",
"lm32_shifter.v", "lm32_multiplier_spartan6.v", "lm32_mc_arithmetic.v",
"lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v",
"lm32_dcache.v", "lm32_top.v", "lm32_debug.v", "lm32_jtag.v", "jtag_cores.v",
"jtag_tap_spartan6.v"])
add_core_dir("minimac3")
def main():
plat = m1.Platform()
soc = top.SoC()

# set pin constraints
plat.request("clk50", obj=soc.crg.clk50_pad)
plat.request("user_btn", 1, obj=soc.crg.trigger_reset)
plat.request("norflash_rst_n", obj=soc.crg.norflash_rst_n)
plat.request("vga_clock", obj=soc.crg.vga_clk_pad)
plat.request("ddram_clock", obj=soc.crg, name_map=lambda s: "ddr_clk_pad_" + s)
plat.request("eth_clocks", obj=soc.crg, name_map=lambda s: "eth_" + s + "_clk_pad")

plat.request("norflash", obj=soc.norflash)
plat.request("serial", obj=soc.uart)
plat.request("ddram", obj=soc.ddrphy, name_map=lambda s: "sd_" + s)
plat.request("eth", obj=soc.minimac, name_map=lambda s: "phy_" + s)
plat.request("vga", obj=soc.fb, name_map=lambda s: "vga_" + s)

# set extra constraints
plat.add_platform_command("""
NET "{clk50}" TNM_NET = "GRPclk50";
TIMESPEC "TSclk50" = PERIOD "GRPclk50" 20 ns HIGH 50%;
INST "m1crg/wr_bufpll" LOC = "BUFPLL_X0Y2";
INST "m1crg/rd_bufpll" LOC = "BUFPLL_X0Y3";
os.chdir("build")
PIN "m1crg/bufg_x1.O" CLOCK_DEDICATED_ROUTE = FALSE;
def str2file(filename, contents):
f = open(filename, "w")
f.write(contents)
f.close()
NET "{phy_rx_clk}" TNM_NET = "GRPphy_rx_clk";
NET "{phy_tx_clk}" TNM_NET = "GRPphy_tx_clk";
TIMESPEC "TSphy_rx_clk" = PERIOD "GRPphy_rx_clk" 40 ns HIGH 50%;
TIMESPEC "TSphy_tx_clk" = PERIOD "GRPphy_tx_clk" 40 ns HIGH 50%;
TIMESPEC "TSphy_tx_clk_io" = FROM "GRPphy_tx_clk" TO "PADS" 10 ns;
TIMESPEC "TSphy_rx_clk_io" = FROM "PADS" TO "GRPphy_rx_clk" 10 ns;
# generate source
(src_verilog, src_ucf) = top.get()
str2file("soc.v", src_verilog)
str2file("soc.ucf", src_ucf)
verilog_sources.append("build/soc.v")
NET "asfifo*/counter_read/gray_count*" TIG;
NET "asfifo*/counter_write/gray_count*" TIG;
NET "asfifo*/preset_empty*" TIG;
""",
clk50=soc.crg.clk50_pad,
phy_rx_clk=soc.crg.eth_rx_clk_pad,
phy_tx_clk=soc.crg.eth_tx_clk_pad)

# add Verilog sources
for d in ["generic", "m1crg", "s6ddrphy", "minimac3"]:
plat.add_source_dir(os.path.join("verilog", d))
plat.add_sources(os.path.join("verilog", "lm32"),
"lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v",
"lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v",
"lm32_shifter.v", "lm32_multiplier_spartan6.v", "lm32_mc_arithmetic.v",
"lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v",
"lm32_dcache.v", "lm32_top.v", "lm32_debug.v", "lm32_jtag.v", "jtag_cores.v",
"jtag_tap_spartan6.v")

plat.build_cmdline(soc.get_fragment(), clock_domains=soc.crg.get_clock_domains())

# generate XST project file
xst_prj = ""
for s in verilog_sources:
xst_prj += "verilog work ../" + s + "\n"
str2file("soc.prj", xst_prj)
if __name__ == "__main__":
main()
110 changes: 0 additions & 110 deletions constraints.py

This file was deleted.

26 changes: 18 additions & 8 deletions milkymist/m1crg/__init__.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
from fractions import Fraction

from migen.fhdl.structure import *
from mibuild.crg import CRG

class M1CRG:
class M1CRG(CRG):
def __init__(self, infreq, outfreq1x):
self.clkin = Signal()
self.clk50_pad = Signal()
self.trigger_reset = Signal()

self.eth_rx_clk_pad = Signal()
self.eth_tx_clk_pad = Signal()

self.cd_sys = ClockDomain("sys")
self.cd_sys2x_270 = ClockDomain("sys2x_270")
self.cd_sys4x_wr = ClockDomain("sys4x_wr")
self.cd_sys4x_rd = ClockDomain("sys4x_rd")
self.cd_eth_rx = ClockDomain("eth_rx")
self.cd_eth_tx = ClockDomain("eth_tx")
self.cd_vga = ClockDomain("vga")

ratio = Fraction(outfreq1x)/Fraction(infreq)
@@ -20,24 +26,29 @@ def __init__(self, infreq, outfreq1x):
Instance.Parameter("in_period", in_period),
Instance.Parameter("f_mult", ratio.numerator),
Instance.Parameter("f_div", ratio.denominator),
Instance.Input("clkin", self.clkin),
Instance.Input("clk50_pad", self.clk50_pad),
Instance.Input("trigger_reset", self.trigger_reset),

Instance.Input("eth_rx_clk_pad", self.eth_rx_clk_pad),
Instance.Input("eth_tx_clk_pad", self.eth_tx_clk_pad),

Instance.Output("sys_clk", self.cd_sys.clk),
Instance.Output("sys_rst", self.cd_sys.rst),
Instance.Output("clk2x_270", self.cd_sys2x_270.clk),
Instance.Output("clk4x_wr", self.cd_sys4x_wr.clk),
Instance.Output("clk4x_rd", self.cd_sys4x_rd.clk),
Instance.Output("eth_rx_clk", self.cd_eth_rx.clk),
Instance.Output("eth_tx_clk", self.cd_eth_tx.clk),
Instance.Output("vga_clk", self.cd_vga.clk)
]

for name in [
"ac97_rst_n",
"videoin_rst_n",
"flash_rst_n",
"norflash_rst_n",
"clk4x_wr_strb",
"clk4x_rd_strb",
"eth_clk_pad",
"ddr_clk_pad_p",
"ddr_clk_pad_n",
"eth_phy_clk_pad",
"vga_clk_pad"
]:
s = Signal(name=name)
@@ -46,6 +57,5 @@ def __init__(self, infreq, outfreq1x):

self._inst = Instance("m1crg", *inst_items)


def get_fragment(self):
return Fragment(instances=[self._inst])
6 changes: 3 additions & 3 deletions milkymist/minimac3/__init__.py
Original file line number Diff line number Diff line change
@@ -84,11 +84,11 @@ def get_fragment(self):
Instance.Output("wb_dat_o", self.membus.dat_r),
Instance.Output("wb_ack_o", self.membus.ack),

Instance.ClockPort("phy_tx_clk", "eth_tx"),
Instance.Output("phy_tx_data", self.phy_tx_data),
Instance.Output("phy_tx_en", self.phy_tx_en),
Instance.Output("phy_tx_er", self.phy_tx_er),
Instance.Input("phy_tx_clk", self.phy_tx_clk),
Instance.Input("phy_rx_clk", self.phy_rx_clk),
Instance.Output("phy_tx_er", self.phy_tx_er),
Instance.ClockPort("phy_rx_clk", "eth_rx"),
Instance.Input("phy_rx_data", self.phy_rx_data),
Instance.Input("phy_dv", self.phy_dv),
Instance.Input("phy_rx_er", self.phy_rx_er),
2 changes: 0 additions & 2 deletions milkymist/s6ddrphy/__init__.py
Original file line number Diff line number Diff line change
@@ -16,8 +16,6 @@ def __init__(self, a, ba, d):
("clk4x_wr_strb", 1, Instance.Input),
("clk4x_rd_strb", 1, Instance.Input),

("sd_clk_out_p", 1, Instance.Output),
("sd_clk_out_n", 1, Instance.Output),
("sd_a", a, Instance.Output),
("sd_ba", ba, Instance.Output),
("sd_cs_n", 1, Instance.Output),
186 changes: 86 additions & 100 deletions top.py
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@
from milkymist import m1crg, lm32, norflash, uart, s6ddrphy, dfii, asmicon, \
identifier, timer, minimac3, framebuffer, asmiprobe
from cmacros import get_macros
from constraints import Constraints

MHz = 1000000
clk_freq = (83 + Fraction(1, 3))*MHz
@@ -58,103 +57,90 @@ def interrupt_n(name):

version = get_macros("common/version.h")["VERSION"][1:-1]

def get():
#
# ASMI
#
asmicon0 = asmicon.ASMIcon(sdram_phy, sdram_geom, sdram_timing)
asmiport_wb = asmicon0.hub.get_port()
asmiport_fb = asmicon0.hub.get_port(2)
asmicon0.finalize()

#
# DFI
#
ddrphy0 = s6ddrphy.S6DDRPHY(sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d)
dfii0 = dfii.DFIInjector(csr_offset("DFII"),
sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d, sdram_phy.nphases)
dficon0 = dfi.Interconnect(dfii0.master, ddrphy0.dfi)
dficon1 = dfi.Interconnect(asmicon0.dfi, dfii0.slave)
class SoC:
def __init__(self):
#
# ASMI
#
self.asmicon = asmicon.ASMIcon(sdram_phy, sdram_geom, sdram_timing)
asmiport_wb = self.asmicon.hub.get_port()
asmiport_fb = self.asmicon.hub.get_port(2)
self.asmicon.finalize()

#
# DFI
#
self.ddrphy = s6ddrphy.S6DDRPHY(sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d)
self.dfii = dfii.DFIInjector(csr_offset("DFII"),
sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d, sdram_phy.nphases)
self.dficon0 = dfi.Interconnect(self.dfii.master, self.ddrphy.dfi)
self.dficon1 = dfi.Interconnect(self.asmicon.dfi, self.dfii.slave)

#
# WISHBONE
#
cpu0 = lm32.LM32()
norflash0 = norflash.NorFlash(25, 12)
sram0 = wishbone.SRAM(sram_size)
minimac0 = minimac3.MiniMAC(csr_offset("MINIMAC"))
wishbone2asmi0 = wishbone2asmi.WB2ASMI(l2_size//4, asmiport_wb)
wishbone2csr0 = wishbone2csr.WB2CSR()

# norflash 0x00000000 (shadow @0x80000000)
# SRAM/debug 0x10000000 (shadow @0x90000000)
# USB 0x20000000 (shadow @0xa0000000)
# Ethernet 0x30000000 (shadow @0xb0000000)
# SDRAM 0x40000000 (shadow @0xc0000000)
# CSR bridge 0x60000000 (shadow @0xe0000000)
wishbonecon0 = wishbone.InterconnectShared(
[
cpu0.ibus,
cpu0.dbus
], [
(lambda a: a[26:29] == 0, norflash0.bus),
(lambda a: a[26:29] == 1, sram0.bus),
(lambda a: a[26:29] == 3, minimac0.membus),
(lambda a: a[27:29] == 2, wishbone2asmi0.wishbone),
(lambda a: a[27:29] == 3, wishbone2csr0.wishbone)
],
register=True)

#
# CSR
#
uart0 = uart.UART(csr_offset("UART"), clk_freq, baud=115200)
identifier0 = identifier.Identifier(csr_offset("ID"), 0x4D31, version, int(clk_freq))
timer0 = timer.Timer(csr_offset("TIMER0"))
fb0 = framebuffer.Framebuffer(csr_offset("FB"), asmiport_fb)
asmiprobe0 = asmiprobe.ASMIprobe(csr_offset("ASMIPROBE"), asmicon0.hub)
csrcon0 = csr.Interconnect(wishbone2csr0.csr, [
uart0.bank.bus,
dfii0.bank.bus,
identifier0.bank.bus,
timer0.bank.bus,
minimac0.bank.bus,
fb0.bank.bus,
asmiprobe0.bank.bus
])

#
# Interrupts
#
interrupts = Fragment([
cpu0.interrupt[interrupt_n("UART")].eq(uart0.events.irq),
cpu0.interrupt[interrupt_n("TIMER0")].eq(timer0.events.irq),
cpu0.interrupt[interrupt_n("MINIMAC")].eq(minimac0.events.irq)
])

#
# Housekeeping
#
crg0 = m1crg.M1CRG(50*MHz, clk_freq)

ddrphy_strobes = Fragment([
ddrphy0.clk4x_wr_strb.eq(crg0.clk4x_wr_strb),
ddrphy0.clk4x_rd_strb.eq(crg0.clk4x_rd_strb)
])
frag = autofragment.from_local() \
+ interrupts \
+ ddrphy_strobes
cst = Constraints(crg0, norflash0, uart0, ddrphy0, minimac0, fb0)
src_verilog, vns = verilog.convert(frag,
cst.get_ios(),
name="soc",
clock_domains={
"sys": crg0.cd_sys,
"sys2x_270": crg0.cd_sys2x_270,
"sys4x_wr": crg0.cd_sys4x_wr,
"sys4x_rd": crg0.cd_sys4x_rd,
"vga": crg0.cd_vga
},
return_ns=True)
src_ucf = cst.get_ucf(vns)
return (src_verilog, src_ucf)
#
# WISHBONE
#
self.cpu = lm32.LM32()
self.norflash = norflash.NorFlash(25, 12)
self.sram = wishbone.SRAM(sram_size)
self.minimac = minimac3.MiniMAC(csr_offset("MINIMAC"))
self.wishbone2asmi = wishbone2asmi.WB2ASMI(l2_size//4, asmiport_wb)
self.wishbone2csr = wishbone2csr.WB2CSR()

# norflash 0x00000000 (shadow @0x80000000)
# SRAM/debug 0x10000000 (shadow @0x90000000)
# USB 0x20000000 (shadow @0xa0000000)
# Ethernet 0x30000000 (shadow @0xb0000000)
# SDRAM 0x40000000 (shadow @0xc0000000)
# CSR bridge 0x60000000 (shadow @0xe0000000)
self.wishbonecon = wishbone.InterconnectShared(
[
self.cpu.ibus,
self.cpu.dbus
], [
(lambda a: a[26:29] == 0, self.norflash.bus),
(lambda a: a[26:29] == 1, self.sram.bus),
(lambda a: a[26:29] == 3, self.minimac.membus),
(lambda a: a[27:29] == 2, self.wishbone2asmi.wishbone),
(lambda a: a[27:29] == 3, self.wishbone2csr.wishbone)
],
register=True)

#
# CSR
#
self.uart = uart.UART(csr_offset("UART"), clk_freq, baud=115200)
self.identifier = identifier.Identifier(csr_offset("ID"), 0x4D31, version, int(clk_freq))
self.timer = timer.Timer(csr_offset("TIMER0"))
self.fb = framebuffer.Framebuffer(csr_offset("FB"), asmiport_fb)
self.asmiprobe = asmiprobe.ASMIprobe(csr_offset("ASMIPROBE"), self.asmicon.hub)
self.csrcon = csr.Interconnect(self.wishbone2csr.csr, [
self.uart.bank.bus,
self.dfii.bank.bus,
self.identifier.bank.bus,
self.timer.bank.bus,
self.minimac.bank.bus,
self.fb.bank.bus,
self.asmiprobe.bank.bus
])

#
# Clocking
#
self.crg = m1crg.M1CRG(50*MHz, clk_freq)

def get_fragment(self):
comb = [
#
# Interrupts
#
self.cpu.interrupt[interrupt_n("UART")].eq(self.uart.events.irq),
self.cpu.interrupt[interrupt_n("TIMER0")].eq(self.timer.events.irq),
self.cpu.interrupt[interrupt_n("MINIMAC")].eq(self.minimac.events.irq),
#
# DDR PHY strobes
#
self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb),
self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb)
]
glue = Fragment(comb)
return glue + autofragment.from_attributes(self)
83 changes: 65 additions & 18 deletions verilog/m1crg/m1crg.v
Original file line number Diff line number Diff line change
@@ -4,26 +4,32 @@ module m1crg #(
parameter f_div = 0,
parameter clk2x_period = (in_period*f_div)/(2.0*f_mult)
) (
input clkin,
input clk50_pad,
input trigger_reset,

output sys_clk,
output reg sys_rst,

/* Reset off-chip devices */
output ac97_rst_n,
output videoin_rst_n,
output flash_rst_n,
/* Reset NOR flash */
output norflash_rst_n,

/* DDR PHY clocks */
output clk2x_270,
output clk4x_wr,
output clk4x_wr_strb,
output clk4x_rd,
output clk4x_rd_strb,

/* DDR off-chip clocking */
output ddr_clk_pad_p,
output ddr_clk_pad_n,

/* Ethernet PHY clock */
output reg eth_clk_pad, /* < unbuffered, to I/O */
/* Ethernet PHY clocks */
output reg eth_phy_clk_pad,
input eth_rx_clk_pad,
input eth_tx_clk_pad,
output eth_rx_clk,
output eth_tx_clk,

/* VGA clock */
output vga_clk, /* < buffered, to internal clock network */
@@ -43,9 +49,6 @@ always @(posedge sys_clk) begin
sys_rst <= rst_debounce != 20'd0;
end

assign ac97_rst_n = ~sys_rst;
assign videoin_rst_n = ~sys_rst;

/*
* We must release the Flash reset before the system reset
* because the Flash needs some time to come out of reset
@@ -64,28 +67,28 @@ always @(posedge sys_clk) begin
flash_rstcounter <= flash_rstcounter + 8'd1;
end

assign flash_rst_n = flash_rstcounter[7];
assign norflash_rst_n = flash_rstcounter[7];

/*
* Clock management. Inspired by the NWL reference design.
*/

wire sdr_clkin;
wire sdr_clk50;
wire clkdiv;

IBUF #(
.IOSTANDARD("DEFAULT")
) clk2_iob (
.I(clkin),
.O(sdr_clkin)
.I(clk50_pad),
.O(sdr_clk50)
);

BUFIO2 #(
.DIVIDE(1),
.DIVIDE_BYPASS("FALSE"),
.I_INVERT("FALSE")
) bufio2_inst2 (
.I(sdr_clkin),
.I(sdr_clk50),
.IOCLK(),
.DIVCLK(clkdiv),
.SERDESSTROBE()
@@ -135,7 +138,7 @@ PLL_ADV #(
.CLKOUT1(pllout1), /* < x4 clock for reads */
.CLKOUT2(pllout2), /* < x2 90 clock to generate memory clock, clock DQS and memory address and control signals. */
.CLKOUT3(pllout3), /* < x1 clock for system and memory controller */
.CLKOUT4(pllout4), /* < buffered clkin */
.CLKOUT4(pllout4), /* < buffered clk50 */
.CLKOUT5(),
.CLKOUTDCM0(),
.CLKOUTDCM1(),
@@ -191,11 +194,55 @@ BUFG bufg_x1(
.O(sys_clk)
);

/* Ethernet PHY */

/*
* SDRAM clock
*/

ODDR2 #(
.DDR_ALIGNMENT("NONE"),
.INIT(1'b0),
.SRTYPE("SYNC")
) sd_clk_forward_p (
.Q(sd_clk_out_p),
.C0(clk2x_270),
.C1(~clk2x_270),
.CE(1'b1),
.D0(1'b1),
.D1(1'b0),
.R(1'b0),
.S(1'b0)
);
ODDR2 #(
.DDR_ALIGNMENT("NONE"),
.INIT(1'b0),
.SRTYPE("SYNC")
) sd_clk_forward_n (
.Q(sd_clk_out_n),
.C0(clk2x_270),
.C1(~clk2x_270),
.CE(1'b1),
.D0(1'b0),
.D1(1'b1),
.R(1'b0),
.S(1'b0)
);

/*
* Ethernet PHY
*/

always @(posedge pllout4)
eth_clk_pad <= ~eth_clk_pad;

/* VGA clock */
/* Let the synthesizer insert the appropriate buffers */
assign eth_rx_clk = eth_rx_clk_pad;
assign eth_tx_clk = eth_tx_clk_pad;

/*
* VGA clock
*/

// TODO: hook up the reprogramming interface
DCM_CLKGEN #(
.CLKFXDV_DIVIDE(2),
34 changes: 0 additions & 34 deletions verilog/s6ddrphy/s6ddrphy.v
Original file line number Diff line number Diff line change
@@ -59,8 +59,6 @@ module s6ddrphy #(
output dfi_rddata_valid_w1,

/* DDR SDRAM pads */
output sd_clk_out_p,
output sd_clk_out_n,
output reg [NUM_AD-1:0] sd_a,
output reg [NUM_BA-1:0] sd_ba,
output reg sd_cs_n,
@@ -73,38 +71,6 @@ module s6ddrphy #(
inout [NUM_D/16-1:0] sd_dqs
);

/*
* SDRAM clock
*/
ODDR2 #(
.DDR_ALIGNMENT("NONE"),
.INIT(1'b0),
.SRTYPE("SYNC")
) sd_clk_forward_p (
.Q(sd_clk_out_p),
.C0(clk2x_270),
.C1(~clk2x_270),
.CE(1'b1),
.D0(1'b1),
.D1(1'b0),
.R(1'b0),
.S(1'b0)
);
ODDR2 #(
.DDR_ALIGNMENT("NONE"),
.INIT(1'b0),
.SRTYPE("SYNC")
) sd_clk_forward_n (
.Q(sd_clk_out_n),
.C0(clk2x_270),
.C1(~clk2x_270),
.CE(1'b1),
.D0(1'b0),
.D1(1'b1),
.R(1'b0),
.S(1'b0)
);

/*
* Command/address
*/

0 comments on commit 5649e88

Please sign in to comment.