diff --git a/lib/ECP5_RAM.bsv b/lib/ECP5_RAM.bsv index e6545e1..adf703a 100644 --- a/lib/ECP5_RAM.bsv +++ b/lib/ECP5_RAM.bsv @@ -17,8 +17,12 @@ typedef enum { // ECP5_EBRPortConfig is the static configuration of an EBR port. typedef struct { - Clock clk; - Reset rstN; + // clk, if specified, is the Clock to use for the port. If + // unspecified, uses the module default clock. + Maybe#(Clock) clk; + // rstN, if specified, is the Reset to use for the port. If + // unspecified, uses the module default reset. + Maybe#(Reset) rstN; // By default, ECP5 EBRs only register the input address and write // data, giving a 1-cycle latency for operations. If // registered_output is true, the output value is also registered, @@ -34,8 +38,8 @@ typedef struct { instance DefaultValue#(ECP5_EBRPortConfig); defaultValue = ECP5_EBRPortConfig{ - clk: noClock, - rstN: noReset, + clk: defaultValue, + rstN: defaultValue, registered_output: False, chip_select_addr: 0, write_mode: Normal @@ -68,14 +72,34 @@ import "BVI" ECP5_RAM = Integer portB_width) (ECP5_EBRCoreInner); + let defClk <- exposeCurrentClock; + let defRstN <- exposeCurrentReset; + + let portA_bsv_clock = case (port_a.clk) matches + tagged Invalid: defClk; + tagged Valid .clk: clk; + endcase; + let portA_bsv_rstN = case (port_a.rstN) matches + tagged Invalid: defRstN; + tagged Valid .rstN: rstN; + endcase; + let portB_bsv_clock = case (port_b.clk) matches + tagged Invalid: defClk; + tagged Valid .clk: clk; + endcase; + let portB_bsv_rstN = case (port_b.rstN) matches + tagged Invalid: defRstN; + tagged Valid .rstN: rstN; + endcase; + default_clock no_clock; default_reset no_reset; - input_clock portA_clk(CLKA, (* unused *)CLKA_GATE) = port_a.clk; - input_reset portA_rstN(RSTA) clocked_by(portA_clk) = port_a.rstN; + input_clock portA_clk(CLKA, (* unused *)CLKA_GATE) = portA_bsv_clock; + input_reset portA_rstN(RSTA) clocked_by(portA_clk) = portA_bsv_rstN; - input_clock portB_clk(CLKB, (* unused *)CLKB_GATE) = port_b.clk; - input_reset portB_rstN(RSTB) clocked_by(portB_clk) = port_b.rstN; + input_clock portB_clk(CLKB, (* unused *)CLKB_GATE) = portB_bsv_clock; + input_reset portB_rstN(RSTB) clocked_by(portB_clk) = portB_bsv_rstN; parameter DATA_WIDTH_A = portA_width; parameter REGMODE_A = port_a.registered_output ? "OUTREG" : "NOREG";