OpenCores
URL https://opencores.org/ocsvn/zx_ula/zx_ula/trunk

Subversion Repositories zx_ula

[/] [zx_ula/] [branches/] [xilinx/] [spectrum_48k_for_digilent_spartan3_starter_kit_with_ps2_keyboard/] [ram.v] - Blame information for rev 10

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 10 mcleod_ide
`timescale 1ns / 1ps
2
//////////////////////////////////////////////////////////////////////////////////
3
// Company:        Dept. Architecture and Computing Technology. University of Seville
4
// Engineer:       Miguel Angel Rodriguez Jodar. rodriguj@atc.us.es
5
// 
6
// Create Date:    19:13:39 4-Apr-2012 
7
// Design Name:    ZX Spectrum
8
// Module Name:    ram32k
9
// Project Name: 
10
// Target Devices: 
11
// Tool versions: 
12
// Description: 
13
//
14
// Dependencies: 
15
//
16
// Revision: 
17
// Revision 1.00 - File Created
18
// Additional Comments: GPL License policies apply to the contents of this file.
19
//
20
//////////////////////////////////////////////////////////////////////////////////
21
 
22
/*
23
This module generates a high level on "isfalling" when "a" changes from high to low.
24
*/
25
module getfedge (
26
        input clk,
27
        input a,
28
        output isfalling
29
        );
30
 
31
        reg sh = 1'b1;
32
        assign isfalling = sh & ~a;
33
        always @(posedge clk)
34
                sh <= a;
35
endmodule
36
 
37
 
38
/*
39
This module implements a shared RAM controller. The Spartan 3 Starter Kit has two 256Kx16 SRAM chips.
40
It uses half the size of one of these chips (8 bit data bus instead of 16).
41
As the ZX Spectrum needs two independent memory banks, and bus cycles may happen to both at the same
42
time, it's necessary to emulate those two banks with one chip.
43
 
44
I tried a simple round-robin multiplexing, but didn't work as expected. This module is a bit more complicated
45
as it implements a first-come-first-serve approach, with fixed priority scheme when several petitions happen
46
at the same time.
47
 
48
Each bank can be up to 64Kx8, so implementing a 128K memory scheme is very easy (I hope so) using this module
49
and the external SRAM on board.
50
 
51
This may be my first 100% synchronous implementation for a FPGA (that is, only one clock and all the ff's are
52
activated at the same edge)
53
 
54
*/
55
module ram_controller (
56
        input clk,
57
        // Bank 1 (VRAM)
58
        input [15:0] a1,
59
        input cs1_n,
60
        input oe1_n,
61
        input we1_n,
62
        input [7:0] din1,
63
        output [7:0] dout1,
64
        // Bank 2 (upper RAM)
65
        input [15:0] a2,
66
        input cs2_n,
67
        input oe2_n,
68
        input we2_n,
69
        input [7:0] din2,
70
        output [7:0] dout2,
71
        // Outputs to actual SRAM on board
72
        output [17:0] sa,
73
        inout [7:0] sd,
74
        output sramce,
75
        output sramub,
76
        output sramlb,
77
        output sramoe,
78
        output sramwe
79
        );
80
 
81
        // Permanently enable SRAM and set it to use only LSB
82
        assign sramub = 1;
83
        assign sramlb = 0;
84
        assign sramce = 0;
85
        assign sramoe = 0;
86
 
87
        reg rsramwe = 1;
88
        assign sramwe = rsramwe;
89
 
90
        reg [17:0] rsa;
91
        reg [7:0] rsd;
92
        assign sa = rsa;
93
        assign sd = rsd;
94
 
95
        // set when there has been a high to low transition in the corresponding signal
96
        wire bank1read, bank1write, bank2read, bank2write;
97
        getfedge detectbank1read (clk, cs1_n | oe1_n, bank1read);
98
        getfedge detectbank2read (clk, cs2_n | oe2_n, bank2read);
99
        getfedge detectbank1write (clk, cs1_n | we1_n, bank1write);
100
        getfedge detectbank2write (clk, cs2_n | we2_n, bank2write);
101
 
102
        reg [15:0] ra1;
103
        reg [15:0] ra2;
104
        reg [7:0] rdin1;
105
        reg [7:0] rdin2;
106
 
107
        reg [7:0] rdout1;
108
        assign dout1 = rdout1;
109
        reg [7:0] rdout2;
110
        assign dout2 = rdout2;
111
 
112
        // ff's to store pending memory requests
113
        reg pendingreadb1 = 0;
114
        reg pendingwriteb1 = 0;
115
        reg pendingreadb2 = 0;
116
        reg pendingwriteb2 = 0;
117
 
118
        // ff's to store current memory requests
119
        reg reqreadb1 = 0;
120
        reg reqreadb2 = 0;
121
        reg reqwriteb1 = 0;
122
        reg reqwriteb2 = 0;
123
 
124
        reg state = 1;
125
        always @(posedge clk) begin
126
                // get requests from the two banks
127
                if (bank1read) begin
128
                        ra1 <= a1;
129
                        pendingreadb1 <= 1;
130
                        pendingwriteb1 <= 0;
131
                end
132
                else if (bank1write) begin
133
                        ra1 <= a1;
134
                        rdin1 <= din1;
135
                        pendingwriteb1 <= 1;
136
                        pendingreadb1 <= 0;
137
                end
138
                if (bank2read) begin
139
                        ra2 <= a2;
140
                        pendingreadb2 <= 1;
141
                        pendingwriteb2 <= 0;
142
                end
143
                else if (bank2write) begin
144
                        ra2 <= a2;
145
                        rdin2 <= din2;
146
                        pendingwriteb2 <= 1;
147
                        pendingreadb2 <= 0;
148
                end
149
 
150
                // reads from bank1 have the higher priority, then writes to bank1,
151
                // the reads from bank2, then writes from bank2.
152
                // Reads and writes to bank2 are mutually exclusive, though, as only the CPU
153
                // performs those operations. So they are with respect to bank1.
154
                case (state)
155
 
156
                                        if (reqreadb1 || reqwriteb1) begin
157
                                                rsa <= {2'b00,ra1};     // operation to bank1 accepted. We put the memory address on the SRAM address bus
158
                                                if (reqwriteb1) begin  // if this is a write operation...
159
                                                        pendingwriteb1 <= 0;   // accept it, and mark pending operation as cleared
160
                                                        rsd <= rdin1;       // put the data to be written in the SRAM data bus
161
                                                        rsramwe <= 0;              // pulse /WE in SRAM to begin write
162
                                                end
163
                                                else begin
164
                                                        pendingreadb1 <= 0;  // else, this is a read operation...
165
                                                        rsd <= 8'bzzzzzzzz;  // disconnect the output bus from the data register to the SRAM data bus, so
166
                                                        rsramwe <= 1;        // we can read from the SRAM data bus itself. Deassert /WE to enable data output bus
167
                                                end
168
                                                state <= 1;             // if either request has been accepted, proceed to next phase.
169
                                   end
170
                                   else if (reqreadb2 || reqwriteb2) begin      // do the same with requests to bank 2...
171
                                                rsa <= {2'b01,ra2};
172
                                                if (reqwriteb2) begin
173
                                                        pendingwriteb2 <= 0;
174
                                                        rsd <= rdin2;
175
                                                        rsramwe <= 0;
176
                                                end
177
                                                else begin
178
                                                        pendingreadb2 <= 0;
179
                                                        rsd <= 8'bzzzzzzzz;
180
                                                        rsramwe <= 1;
181
                                                end
182
                                                state <= 1;
183
                                        end
184
                                  end
185
                        1 : begin
186
                                        if (reqreadb1) begin            // for read requests, read the SRAM data bus and store into the corresponding data output register
187
                                                rdout1 <= sd;
188
                                        end
189
                                        else if (reqreadb2) begin
190
                                                rdout2 <= sd;
191
                                        end
192
                                        if (reqwriteb1) begin   // for write requests, deassert /WE, as writting has already been happened.
193
                                                rsramwe <= 1;
194
                                        end
195
                                        else if (reqwriteb2) begin
196
                                                rsramwe <= 1;
197
                                        end
198
                                        reqreadb1 <= pendingreadb1;     // current request has finished, so update current requests with pending requests to serve  the next one
199
                                        reqreadb2 <= pendingreadb2;
200
                                        reqwriteb1 <= pendingwriteb1;
201
                                        reqwriteb2 <= pendingwriteb2;
202
                                        if (pendingreadb1 || pendingreadb2 || pendingwriteb1 || pendingwriteb2)
203
                                                state <= 0;
204
                                 end
205
                endcase
206
        end
207
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.