1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
module extram_wb
#(parameter PAGE_SIZE = 10,
parameter ADDR_WIDTH = 16)
(input clk, input rst,
input wb_clk, input wb_rst,
input cyc_i, input stb_i,
input [ADDR_WIDTH-1:0] adr_i,
input we_i,
input [31:0] dat_i,
output reg [31:0] dat_o,
output reg ack_o,
inout [17:0] RAM_D,
output [PAGE_SIZE-2:0] RAM_A,
output RAM_CE1n, output RAM_CENn,
output RAM_CLK, output RAM_WEn,
output RAM_OEn, output RAM_LDn );
wire read_acc = stb_i & cyc_i & ~we_i;
wire write_acc = stb_i & cyc_i & we_i;
wire acc = stb_i & cyc_i;
assign RAM_CLK = ~wb_clk; // 50 MHz for now, eventually should be 200 MHz
assign RAM_LDn = 0; // No burst for now
assign RAM_CENn = 0; // Use CE1n as our main CE
reg [PAGE_SIZE-2:1] RAM_addr_reg;
always @(posedge wb_clk)
if(acc)
RAM_addr_reg[PAGE_SIZE-2:1] <= adr_i[PAGE_SIZE-1:2];
assign RAM_A[PAGE_SIZE-2:1] = RAM_addr_reg;
reg [31:0] ram_out;
always @(posedge wb_clk)
if(write_acc)
ram_out <= dat_i;
// RAM access state machine
localparam RAM_idle = 0;
localparam RAM_read_1 = 1;
localparam RAM_read_2 = 2;
localparam RAM_read_3 = 3;
localparam RAM_read_4 = 4;
localparam RAM_write_1 = 6;
localparam RAM_write_2 = 7;
localparam RAM_write_3 = 8;
localparam RAM_write_4 = 9;
reg myOE = 0;
reg RAM_OE = 0;
reg RAM_WE = 0;
reg RAM_EN = 0;
reg RAM_A0_reg;
reg [3:0] RAM_state;
always @(posedge wb_clk)
if(wb_rst)
begin
RAM_state <= RAM_idle;
myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
end
else
case(RAM_state)
RAM_idle :
if(read_acc & ~ack_o)
begin
RAM_state <= RAM_read_1;
myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 1; RAM_A0_reg <= 0;
end
else if(write_acc & ~ack_o)
begin
RAM_state <= RAM_write_1;
myOE <= 0; RAM_OE <= 0; RAM_WE <= 1; RAM_EN <= 1; RAM_A0_reg <= 0;
end
else
begin
myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
end
RAM_read_1 :
begin
RAM_state <= RAM_read_2;
myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 1; RAM_A0_reg <= 1;
end
RAM_read_2 :
begin
RAM_state <= RAM_read_3;
myOE <= 0; RAM_OE <= 1; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
end
RAM_read_3 :
begin
RAM_state <= RAM_read_4;
myOE <= 0; RAM_OE <= 1; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
end
RAM_read_4 :
begin
RAM_state <= RAM_idle;
myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
end
RAM_write_1 :
begin
RAM_state <= RAM_write_2;
myOE <= 1; RAM_OE <= 0; RAM_WE <= 1; RAM_EN <= 1; RAM_A0_reg <= 1;
end
RAM_write_2 :
begin
RAM_state <= RAM_write_3;
myOE <= 1; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
end
RAM_write_3 :
begin
RAM_state <= RAM_write_4;
myOE <= 1; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
end
RAM_write_4 :
begin
RAM_state <= RAM_idle;
myOE <= 0; RAM_OE <= 0; RAM_WE <= 0; RAM_EN <= 0; RAM_A0_reg <= 0;
end
default : RAM_state <= RAM_idle;
endcase // case(RAM_state)
assign RAM_A[0] = RAM_A0_reg;
assign RAM_WEn = ~RAM_WE; // ((RAM_state==RAM_write_1)||(RAM_state==RAM_write_2));
assign RAM_OEn = ~RAM_OE;
assign RAM_CE1n = ~RAM_EN; // Active low (RAM_state != RAM_idle);
assign RAM_D[17:16] = 2'bzz;
assign RAM_D[15:0] = myOE ? ((RAM_state==RAM_write_2)?ram_out[15:0]:ram_out[31:16])
: 16'bzzzz_zzzz_zzzz_zzzz;
always @(posedge wb_clk)
if(RAM_state == RAM_read_3)
dat_o[15:0] <= RAM_D[15:0];
else
dat_o[31:16] <= RAM_D[15:0];
always @(posedge wb_clk)
if(wb_rst)
ack_o <= 0;
else if((RAM_state == RAM_write_4)||(RAM_state == RAM_read_4))
ack_o <= 1;
else
ack_o <= 0;
endmodule // extram_wb
|