2 * TODO: optimize for multiple writes in sequence
5 module memory_interface
9 sram_cs_n
, sram_be_n
, sram_oe_n
, sram_we_n
,
24 // Flash-SRAM-Ethernet bus
25 output reg [22:0] fse_a
; // Mainboard common bus address
26 inout wire [31:0] fse_d
; // Mainboard common bus data
27 output wire flash_cs_n
; // Flash ROM CS#
28 output wire enet_aen
; // Ethernet Access Enable
29 output wire sram_cs_n
; // SRAM CS#
30 output reg [3:0] sram_be_n
; // SRAM byte enables
31 output wire sram_oe_n
; // SRAM OE#
32 output wire sram_we_n
; // SRAM WE#
35 input wire transfer_request
;
36 input wire [31:0] address
;
38 input wire [31:0] wrdata
;
39 input wire [ 3:0] wrmask
;
41 output wire wait_request
;
42 output wire read_data_valid
;
43 // output reg [31:0] read_data;
44 output wire [31:0] read_data
; // XXX a bit reckless!
46 parameter N
= 4; // 0 1 2 3 4 5
47 parameter MAX_CYCLES
= (1 << (N
- 1)) - 1; // X 0 1 3 7 15
50 * @ 200MHz/5ns the address must be asserted for two cycles but
51 * apparently that isn't enough...
53 parameter READ_CYCLES
= 0; // 25MHz
54 parameter LATENCY
= 1; // data is ready LATENCY cycles from accepted request
56 /* How many cycles to assert the data and address
57 * *while* writing, that is, not counting setup and teardown
59 parameter WRITE_CYCLES
= 1; // 25MHz
63 parameter WRITE_PREPARE
= 2;
64 parameter WRITE_DO
= 3;
65 parameter DELAY_WRITE
= 4;
67 // Encode {cs_n,oe_n,we_n} as a command
68 parameter SRAM_CMD_READ
= 3'b001; // 'h1
69 parameter SRAM_CMD_WRITE
= 3'b010; // 'h2
70 parameter SRAM_CMD_PRE_WRITE
= 3'b011; // 'h3
71 parameter SRAM_CMD_NOP
= 3'b111; // 'h7
73 reg [31:0] state
= IDLE
;
77 reg [LATENCY
:0] read_data_pipeline
;
78 /* XXX really should be LATENCY-1 but then the read_data_pipeline assignment
79 * below fails for LATENCY == 1 It doesn't really affect anything
82 assign flash_cs_n
= 1'b1; // Disable flash ROM
83 assign enet_aen
= 1'b1; // Disable Ethernet
84 assign {sram_cs_n
,sram_oe_n
,sram_we_n
} = sram_cmd
;
85 assign fse_d
= sram_oe_n ? fse_d_out
: 32'hZZZZZZZZ
;
87 assign wait_request
= state
!= IDLE
;
88 assign read_data_valid
= read_data_pipeline
[LATENCY
-1];
89 assign read_data
= fse_d
;
92 always @(posedge clkin
) begin
94 //if(debug)$display("%06d MI: fse_d %x", $time, fse_d);
95 countdown
<= countdown
- 1;
96 read_data_pipeline
<= {read_data_pipeline
[LATENCY
-1:0], 1'b0};
99 if(debug
)$display("%06d MI: read data %x", $time, read_data
);
103 sram_cmd
<= SRAM_CMD_READ
;
105 if (transfer_request
)
107 if(debug
)$display("%06d MI: got a read command for address %x", $time, address
);
108 fse_a
<= address
; // XXX Notice, only 20-bit are valid for SRAM (18 if aligned)
110 if (READ_CYCLES
) begin
111 countdown
<= READ_CYCLES
- 2; // These underflow downcounters always use T - 2
114 // I _can_ run @100+ MHz with a ~ 25 ns latency (strange)
115 read_data_pipeline
[0] <= 1;
118 if(debug
)$display("%06d MI: got a write command for address %x <- %x mask %x", $time, address
, wrdata
, wrmask
);
119 fse_a
<= address
; // Notice, only 18-bit are valid for SRAM
121 sram_be_n
<= ~wrmask
;
122 if (|read_data_pipeline
) begin
123 /* If there is an outstanding read command we have to wait
125 state
<= DELAY_WRITE
;
127 sram_cmd
<= SRAM_CMD_PRE_WRITE
;
128 state
<= WRITE_PREPARE
;
133 READ
: if (countdown
[N
]) begin
134 read_data_pipeline
[0] <= 1;
138 DELAY_WRITE
: if (~|read_data_pipeline
) begin
139 sram_cmd
<= SRAM_CMD_PRE_WRITE
;
140 state
<= WRITE_PREPARE
;
144 sram_cmd
<= SRAM_CMD_WRITE
;
145 countdown
<= WRITE_CYCLES
- 2;// These underflow downcounters always use T - 2
149 WRITE_DO
: if (countdown
[N
]) begin
150 if(debug
)$display("%06d MI: done writing", $time);
151 sram_cmd
<= SRAM_CMD_PRE_WRITE
;