up the delay-time on ddr3 reset, put loop around dram init just for fun
[ls2.git] / hyperram_model / hbc.v
1 // Copyright 2017 Gnarly Grey LLC
2
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to
8 // permit persons to whom the Software is furnished to do so, subject to
9 // the following conditions:
10
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22
23 module hbc
24 (
25 input i_clk,
26 input i_rstn,
27
28 input i_cfg_access,
29 input i_mem_valid,
30 output o_mem_ready,
31 input [3:0] i_mem_wstrb,
32 input [31:0] i_mem_addr,
33 input [31:0] i_mem_wdata,
34 output [31:0] o_mem_rdata,
35
36 output o_csn0,
37 output o_csn1,
38 output o_clk,
39 output o_clkn,
40 output [7:0] o_dq,
41 input [7:0] i_dq,
42 output o_dq_de,
43 output o_rwds,
44 input i_rwds,
45 output o_rwds_de,
46 output o_resetn
47 );
48
49 // fsm states
50 parameter IDLE = 0;
51 parameter CAs = 1;
52 parameter WR_LATENCY = 2;
53 parameter WRITE = 3;
54 parameter READ = 4;
55 parameter DONE = 5;
56
57 // write latency
58 parameter WRITE_LATENCY = 6*2+10 - 1;
59
60 reg [2:0] state;
61 reg [47:0] ca;
62 reg [31:0] wdata;
63 reg [3:0] wstrb;
64 integer counter;
65
66 reg mem_ready;
67 reg [31:0] mem_rdata;
68 reg rwds_d;
69 wire rwds_valid;
70
71 wire [7:0] ca_words[5:0];
72 wire [7:0] wdata_words[3:0];
73 wire [3:0] wstrb_words;
74
75 // fsm
76 always @(posedge i_clk or negedge i_rstn) begin
77 if(!i_rstn) begin
78 ca <= 48'h0;
79 state <= IDLE;
80 mem_ready <= 1'b0;
81 mem_rdata <= 0;
82 counter <= 0;
83 end else begin
84 rwds_d <= i_rwds;
85 case (state)
86 IDLE : begin// wait for mem transaction
87 mem_ready <= 1'b0;
88 if(i_mem_valid && !mem_ready) begin
89 ca[47] <= ~(|i_mem_wstrb);
90 ca[46] <= i_cfg_access;
91 ca[45] <= (|i_mem_wstrb) & i_cfg_access;
92 ca[44:16] <= i_mem_addr[31:3];
93 ca[15:3] <= 0;
94 ca[2:0] <= i_mem_addr[2:0];
95 wdata <= i_mem_wdata;
96 wstrb <= i_mem_wstrb;
97 counter <= 5;
98 state <= CAs;
99 end
100 end
101 CAs: begin
102 if(counter) begin
103 counter <= counter - 1;
104 end else if(ca[47]) begin // read
105 counter <= 3;
106 state <= READ;
107 end else begin
108 if (ca[46]) begin // write to register
109 counter <= 1;
110 state <= WRITE;
111 end else begin // write to memory
112 counter <= WRITE_LATENCY;
113 state <= WR_LATENCY;
114 end
115 end
116 end
117 WR_LATENCY: begin
118 if(counter) begin
119 counter <= counter - 1;
120 end else begin
121 counter <= 3;
122 state <= WRITE;
123 end
124 end
125 WRITE: begin
126 if(counter) begin
127 counter <= counter - 1;
128 end else begin
129 state <= DONE;
130 end
131 end
132 READ : begin
133 if(rwds_valid) begin
134 case (counter)
135 3: mem_rdata[15:8] <= i_dq;
136 2: mem_rdata[7:0] <= i_dq;
137 1: mem_rdata[31:24] <= i_dq;
138 0: mem_rdata[23:16] <= i_dq;
139 endcase
140 if(counter) begin
141 counter <= counter - 1;
142 end else begin
143 state <= DONE;
144 end
145 end
146 end
147 DONE: begin
148 mem_ready <= 1'b1;
149 state <= IDLE;
150 end
151 endcase
152 end
153 end
154
155 assign rwds_valid = (rwds_d | i_rwds);
156 assign ca_words[5] = ca[47:40];
157 assign ca_words[4] = ca[39:32];
158 assign ca_words[3] = ca[31:24];
159 assign ca_words[2] = ca[23:16];
160 assign ca_words[1] = ca[15:8];
161 assign ca_words[0] = ca[7:0];
162 assign wdata_words[3] = wdata[15:8];
163 assign wdata_words[2] = wdata[7:0];
164 assign wdata_words[1] = ca[46]?wdata[15:8]:wdata[31:24];
165 assign wdata_words[0] = ca[46]?wdata[7:0]:wdata[23:16];
166 assign wstrb_words = {wstrb[1], wstrb[0], wstrb[3], wstrb[2]};
167
168 reg bus_clk;
169 always @(negedge i_clk or negedge i_rstn) begin
170 if(!i_rstn)
171 bus_clk <= 0;
172 else
173 bus_clk <= o_csn0 ? 0 : ~bus_clk;
174 end
175
176 assign o_csn0 = (state == IDLE || state == DONE);
177 assign o_csn1 = 1'b1;
178 assign o_clk = bus_clk;
179 assign o_clkn = ~o_clk;
180 assign o_resetn = i_rstn;
181 assign o_dq = (state == CAs)? ca_words[counter]:
182 (state == WRITE)? wdata_words[counter]:8'h0;
183 assign o_rwds = (state == WRITE)? ~wstrb_words[counter]:1'b0;
184 assign o_dq_de = (state == WRITE || state == CAs);
185 assign o_rwds_de = (state == WRITE) && (~ca[46]);
186 assign o_mem_ready = mem_ready;
187 assign o_mem_rdata = mem_rdata;
188
189 endmodule
190
191