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

Subversion Repositories zx_ula

[/] [zx_ula/] [branches/] [xilinx/] [spectrum_16k_with_rom_game_for_ols/] [ram.v] - Blame information for rev 27

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 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
// Revision:       Joseba Epalza Ramos <jepalza@gmail.com> 
6
//                 
7
// Create Date:    20-December-2012 
8
// Design Name:    ZX Spectrum
9
// Module Name:    Ram16K
10
// Project Name: 
11
// Target Devices: 
12
// Tool versions: 
13
// Description:    Spectrum 16k OLS (Open Logic Sniffer) Dangerous Prototypes, "http://dangerousprototypes.com"
14
//
15
// Dependencies: 
16
//
17
// Revision: 
18
// Revision 2.00 - File Created
19
// Additional Comments: GPL License policies apply to the contents of this file.
20
//
21
//////////////////////////////////////////////////////////////////////////////////
22
 
23
/*
24
This module generates a high level on "isfalling" when "a" changes from high to low.
25
*/
26
module getfedge (
27
        input clk,
28
        input a,
29
        output isfalling
30
        );
31
 
32
        reg sh = 1'b1;
33
        assign isfalling = sh & ~a;
34
        always @(posedge clk)
35
                sh <= a;
36
endmodule
37
 
38
 
39
/*
40
This module implements a shared RAM controller.
41
 
42
Notes from <jepalza>:
43
 OLS (Open Logic Sniffer) from Dangerous Prototypes, hasn't any SRAM connected in board.
44
 We need to create it into Spartan. At this point, only has enought logic to implement
45
 16k rom and 8k ram, in order to run basic Spectrum 16k!!
46
 but it's unusable with only 8k of ram. For this reason, it's best implement 8k rom and 16k ram
47
 with any of 8k rom games or demos, in the first 0x0000-0x1fff space.
48
 
49
As the ZX Spectrum needs two independent memory banks, and bus cycles may happen to both at the same
50
time, it's necessary to emulate those two banks with one chip.
51
 
52
I tried a simple round-robin multiplexing, but didn't work as expected. This module is a bit more complicated
53
as it implements a first-come-first-serve approach, with fixed priority scheme when several petitions happen
54
at the same time.
55
 
56
This may be my first 100% synchronous implementation for a FPGA (that is, only one clock and all the ff's are
57
activated at the same edge)
58
 
59
*/
60
module ram_controller (
61
        input clk,
62
        input [15:0] a1,
63
        input cs1_n,
64
        input oe1_n,
65
        input we1_n,
66
        input [7:0] din1,
67
        output [7:0] dout1
68
        );
69
 
70
        // SRAM into OLS (16k max with 8k ROM, or 8k max with 16k ROM)
71
        reg [7:0] mem [0:16383]; //[0:7900] //7900: test with spectrum rom
72
 
73
        // Permanently enable SRAM and set it to use only LSB
74
        assign sramce = 0;
75
        assign sramoe = 0;
76
 
77
        reg rsramwe = 1;
78
        assign sramwe = rsramwe;
79
 
80
        // set when there has been a high to low transition in the corresponding signal
81
        wire bank1read, bank1write;
82
        getfedge detectbank1read (clk, cs1_n | oe1_n, bank1read);
83
        getfedge detectbank1write (clk, cs1_n | we1_n, bank1write);
84
 
85
        reg [15:0] ra1;
86
        reg [7:0] rdin1;
87
 
88
        reg [7:0] rdout1;
89
        assign dout1 = rdout1;
90
 
91
        // ff's to store pending memory requests
92
        reg pendingreadb1 = 0;
93
        reg pendingwriteb1 = 0;
94
 
95
        // ff's to store current memory requests
96
        reg reqreadb1 = 0;
97
        reg reqwriteb1 = 0;
98
 
99
        reg state = 1;
100
        always @(posedge clk) begin
101
                // get requests from the two banks
102
                if (bank1read) begin
103
                        ra1 <= a1;
104
                        pendingreadb1 <= 1;
105
                        pendingwriteb1 <= 0;
106
                end
107
                else if (bank1write) begin
108
                        ra1 <= a1;
109
                        rdin1 <= din1;
110
                        pendingwriteb1 <= 1;
111
                        pendingreadb1 <= 0;
112
                end
113
 
114
                // reads from bank1 have the higher priority, then writes to bank1,
115
                // the reads from bank2, then writes from bank2.
116
                // Reads and writes to bank2 are mutually exclusive, though, as only the CPU
117
                // performs those operations. So they are with respect to bank1.
118
                case (state)
119
 
120
                                        if (reqreadb1 || reqwriteb1) begin
121
                                                if (reqwriteb1) begin       // if this is a write operation...
122
                                                        pendingwriteb1 <= 0;     // accept it, and mark pending operation as cleared
123
                                                        mem[ra1[13:0]] <= rdin1; // put data into virtual SRAM
124
                                                        rsramwe <= 0;                   // pulse /WE in SRAM to begin write
125
                                                end
126
                                                else begin
127
                                                        pendingreadb1 <= 0;  // else, this is a read operation...
128
                                                        rsramwe <= 1;        // we can read from the SRAM data bus itself. Deassert /WE to enable data output bus
129
                                                end
130
                                                state <= 1;             // if either request has been accepted, proceed to next phase.
131
                                        end
132
                                  end
133
                        1 : begin
134
                                        if (reqreadb1) begin                 // for read requests, read the SRAM data bus and store into the corresponding data output register
135
                                                rdout1 <= mem[ra1[13:0]]; // get data from SRAM OLS
136
                                        end
137
                                        if (reqwriteb1) begin   // for write requests, deassert /WE, as writting has already been happened.
138
                                                rsramwe <= 1;
139
                                        end
140
                                        reqreadb1 <= pendingreadb1;     // current request has finished, so update current requests with pending requests to serve  the next one
141
                                        reqwriteb1 <= pendingwriteb1;
142
                                        if (pendingreadb1 || pendingwriteb1)
143
                                                state <= 0;
144
                                 end
145
                endcase
146
        end
147
 
148
 
149
endmodule

powered by: WebSVN 2.1.0

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