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
|
/*
* | *WISHBONE DATASHEET* |
* |---------------------------------------------------------------------------|
* | *Description* | *Specification* |
* |---------------------------------+-----------------------------------------|
* | General description | 262144x16-bit memory core (512 KB) |
* |---------------------------------+-----------------------------------------|
* | Supported cycles | SLAVE, pipelined READ/WRITE |
* |---------------------------------+-----------------------------------------|
* | Data port, size | 16-bit |
* | Data port, granularity | 16-bit |
* | Data port, maximum operand size | 16-bit |
* | Data transfer ordering | Big endian and/or little endian |
* | Data transfer ordering | Undefined |
* | Address port, size | 18-bit |
* |---------------------------------+-----------------------------------------|
* | Clock frequency constraints | NONE (determined by memory primitive, |
* | | about 100 MHz if using K6R4016V1D) |
* |---------------------------------+-----------------------------------------|
* | | *Signal name* | *WISHBONE Equiv.* |
* | |------------------+----------------------|
* | | ACK_O | ACK_O |
* | | ADR_I | ADR_I() |
* | Supported signal list and cross | CLK_I | CLK_I |
* | reference to equivalent | DAT_I | DAT_I() |
* | WISHBONE signals | DAT_O | DAT_O() |
* | | STB_I | STB_I |
* | | WE_I | WE_I |
* | | RST_I | RST_I |
* | | STALL_O | STALL_O |
* |---------------------------------+-----------------------------------------|
* | Special requirements | Circuit assumes the use of asynchronous |
* | | RAM primitive, e.g. K6R4016V1D. |
*/
`default_nettype none
module sram_slave
(
/* Interface to memory */
output wire [17:0] sram_addr,
inout wire [15:0] sram_io,
output wire sram_cs_n,
output wire sram_oe_n,
output wire sram_we_n,
/* Wishbone slave interface */
output wire ACK_O,
input wire [17:0] ADR_I,
input wire CLK_I,
input wire [15:0] DAT_I,
output wire [15:0] DAT_O,
input wire RST_I,
input wire STB_I,
input wire WE_I,
output wire STALL_O
);
reg writing;
reg [15:0] write_data;
assign sram_io = sram_we_n ? 16'hZZZZ : write_data;
reg sram_cs_not;
reg sram_oe_not;
reg sram_we_not;
assign sram_cs_n = sram_cs_not;
assign sram_oe_n = sram_oe_not;
assign sram_we_n = sram_we_not;
reg [17:0] address;
assign sram_addr = address;
reg ack;
assign ACK_O = ack;
reg stall;
assign STALL_O = stall;
reg [15:0] output_data;
assign DAT_O = output_data;
reg [2:0] state;
always @ (posedge CLK_I) begin
output_data <= sram_io;
if (RST_I) begin
sram_cs_not <= 1;
sram_oe_not <= 1;
writing <= 0;
ack <= 0;
stall <= 0;
state <= 0;
end else begin
if (state == 0 || state == 2) begin /* possibly starting new job */
if (STB_I) begin
address <= ADR_I;
sram_cs_not <= 0;
sram_oe_not <= WE_I;
writing <= WE_I;
write_data <= DAT_I;
state <= WE_I ? 1 : 2;
stall <= WE_I ? 1 : 0;
end else begin // if (STB_I)
sram_cs_not <= 1;
sram_oe_not <= 1;
writing <= 0;
state <= 0;
end
end // if (state == 0 || state == 2)
if (state == 1) begin /* performing write; it takes 2 CLK_I cycles */
state <= 2;
stall <= 0;
end
if (state == 2) begin /* finishing job */
ack <= 1;
end else begin
ack <= 0;
end
end
end // always @ (posedge CLK_I)
/*
* avoid bus congestion by only driving sram_io
* during the middle part of write cycle
*/
always @ (negedge CLK_I) begin
if (writing)
sram_we_not <= !sram_we_not;
else
sram_we_not <= 1;
end
endmodule // sram_slave
|