Subversion Repositories ngs

Rev

Rev 119 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
116 lvd 1
// part of NeoGS flash programmer project (c) 2014 lvd^NedoPC
2
//
3
// zxbus controller
4
 
5
module zxbus
6
(
7
        input  wire clk,
8
        input  wire rst_n,
9
 
117 lvd 10
        inout  wire [7:0] zxid, // zxbus DATA BUS in/out [7:0]
11
        input  wire [7:0] zxa,  // zxbus ADDRESS 7-0 in [7:0]
12
        input  wire       zxiorq_n,
13
        input  wire       zxmreq_n,
14
        input  wire       zxrd_n,
15
        input  wire       zxwr_n,
16
        output wire       zxblkiorq_n, // active low - signal to generate IORQGE
17
        output reg        zxbusin,    // controls 74hct245 buffer direction (1 - input from bus, 0 - output to zx)
18
        output reg        zxbusena_n, // 74hct245 buffer enable signal
116 lvd 19
 
117 lvd 20
        output reg        init, // positive pulse to cause reset/init to all board
21
        input  wire       init_in_progress, // 1 while init in progress
116 lvd 22
 
117 lvd 23
        output reg        led, // LED state
116 lvd 24
 
121 lvd 25
        output reg        autoinc_ena, // enable autoincrement
26
 
117 lvd 27
        output reg        wr_addr,   // to ROM controller
28
        output reg        wr_data,   //
29
        output reg        rd_data,   //
30
        output reg  [7:0] wr_buffer, //
31
        input  wire [7:0] rd_buffer  //
116 lvd 32
);
33
 
117 lvd 34
        wire iowr = ~(zxiorq_n | zxwr_n);
35
        wire iord = ~(zxiorq_n | zxrd_n);
116 lvd 36
 
117 lvd 37
        reg [2:0] iowr_r;
38
        reg [2:0] iord_r;
39
 
40
        wire iowr_begin, iowr_end;
41
        wire iord_begin, iord_end;
42
 
43
        wire io_begin, io_end;
44
 
45
        wire addr_ok;
46
 
119 lvd 47
        reg wrr;
117 lvd 48
 
119 lvd 49
 
117 lvd 50
        wire [1:0] regsel;
51
 
52
 
53
        reg [7:0] read_data;
54
 
55
 
56
        reg        zxid_oe;
57
        reg  [7:0] zxid_out;
58
        wire [7:0] zxid_in;
59
 
60
 
61
 
62
        reg [8:0] test_reg;
63
        reg [7:0] test_reg_pre;
64
        reg       test_reg_write;
65
 
66
 
67
 
68
 
69
 
70
        // register select (one of 4)
71
        assign regsel[1:0] = { zxa[7], zxa[3] };
72
 
73
 
74
 
75
        // addr decode
76
        assign addr_ok = (zxa==8'h33) || (zxa==8'h3B) || (zxa==8'hB3) || (zxa==8'hBB);
77
 
78
        // IORQGE
79
        assign zxblkiorq_n = ~addr_ok;
80
 
81
 
82
        // internal data bus control
83
        assign zxid = zxid_oe ? zxid_out : 8'bZZZZ_ZZZZ;
84
        //
85
        assign zxid_in = zxid;
86
 
87
 
88
 
89
        // resync strobes
90
        always @(posedge clk)
91
        begin
92
                iowr_r[2:0] <= { iowr_r[1:0], iowr };
93
                iord_r[2:0] <= { iord_r[1:0], iord };
94
        end
95
        //
96
        assign iowr_begin = iowr_r[1] && !iowr_r[2];
118 lvd 97
        assign iord_begin = iord_r[1] && !iord_r[2];
117 lvd 98
        //
99
        assign iowr_end = !iowr_r[1] && iowr_r[2];
100
        assign iord_end = !iord_r[1] && iord_r[2];
101
        //
102
        assign io_begin = iowr_begin || iord_begin;
103
        assign io_end   = iowr_end   || iord_end;
104
 
105
 
106
        // control ext bus buffer
107
        always @(posedge clk, negedge rst_n)
108
        if( !rst_n )
109
        begin
110
                zxbusin    <= 1'b1;
111
                zxbusena_n <= 1'b1;
112
        end
113
        else if( addr_ok && io_begin )
114
        begin
115
                zxbusin    <= ~iord_begin;
116
                zxbusena_n <= 1'b0;
117
        end
118
        else if( io_end )
119
        begin
120
                zxbusena_n <= 1'b1;
121
        end
122
 
123
        // control int bus buffer
124
        always @(posedge clk, negedge rst_n)
125
        if( !rst_n )
126
        begin
127
                zxid_oe <= 1'b0;
128
        end
129
        else if( addr_ok && io_begin )
130
        begin
131
                zxid_oe <= iord_begin;
132
        end
133
        else if( io_end )
134
        begin
135
                zxid_oe <= 1'b0;
136
        end
137
 
119 lvd 138
        // internal write strobe
139
        always @(posedge clk, negedge rst_n)
140
        if( !rst_n )
141
                wrr <= 1'b0;
142
        else
143
                wrr <= addr_ok && iowr_begin;
117 lvd 144
 
145
 
119 lvd 146
 
121 lvd 147
        // write to 33 (init/ctrl reg)
118 lvd 148
        //
117 lvd 149
        always @(posedge clk, negedge rst_n)
150
        if( !rst_n )
118 lvd 151
                led <= 1'b0;
152
        else if( init )
153
                led <= 1'b0;
119 lvd 154
        else if( wrr && regsel==2'b00 && zxid[6] )
118 lvd 155
                led <= ~led;
156
        //
157
        always @(posedge clk, negedge rst_n)
158
        if( !rst_n )
159
                init <= 1'b0;
119 lvd 160
        else if( wrr && regsel==2'b00 && zxid[7] )
118 lvd 161
                init <= 1'b1;
117 lvd 162
        else
163
                init <= 1'b0;
121 lvd 164
        //
165
        always @(posedge clk, negedge rst_n)
166
        if( !rst_n )
167
                autoinc_ena <= 1'b0;
168
        else if( wrr && regsel==2'b00 )
169
                autoinc_ena <= zxid[5];
117 lvd 170
 
171
 
172
        // write to 3B (test reg)
173
        always @(posedge clk, negedge rst_n)
174
        if( !rst_n )
175
        begin
176
                test_reg <= 9'd0;
177
        end
118 lvd 178
        else if( init )
179
        begin
180
                test_reg <= 9'd0;
181
        end
117 lvd 182
        else if( test_reg_write )
183
        begin
184
                test_reg[8:0] <= { (~test_reg_pre[7:0]), test_reg[8] };
185
        end
186
        //
187
        always @(posedge clk)
119 lvd 188
        if( wrr && regsel==2'b01 )
117 lvd 189
        begin
190
                test_reg_pre <= zxid_in;
191
                test_reg_write <= 1'b1;
192
        end
193
        else
194
        begin
195
                test_reg_write <= 1'b0;
196
        end
197
 
198
 
199
        // write to B3 (addr reg)
200
        always @(posedge clk)
119 lvd 201
        if( wrr && regsel==2'b10 )
117 lvd 202
                wr_addr <= 1'b1;
203
        else
204
                wr_addr <= 1'b0;
205
 
206
        // write to BB (data reg)
207
        always @(posedge clk)
119 lvd 208
        if( wrr && regsel==2'b11 )
117 lvd 209
                wr_data <= 1'b1;
210
        else
211
                wr_data <= 1'b0;
212
 
213
        // read from BB (data reg)
214
        always @(posedge clk)
215
        if( addr_ok && regsel==2'b11 && iord_begin )
216
                rd_data <= 1'b1;
217
        else
218
                rd_data <= 1'b0;
219
 
220
        // write data for B3 and BB
221
        always @(posedge clk)
119 lvd 222
        if( wrr && regsel[1]==1'b1 )
117 lvd 223
                wr_buffer <= zxid_in;
224
 
225
 
226
        // ports read
227
        always @*
228
        case( regsel )
118 lvd 229
                2'b00:   read_data = { init_in_progress, 7'd0 };
230
                2'b01:   read_data = test_reg[7:0];
117 lvd 231
                //2'b10:   read_data <= рег адреса (НОЛЬ!)
118 lvd 232
                2'b11:   read_data = rd_buffer;
233
                default: read_data = 8'd0;
117 lvd 234
        endcase
235
        //
236
        always @(posedge clk)
237
        if( addr_ok && iord_begin )
238
                zxid_out <= read_data;
239
 
240
 
241
 
116 lvd 242
endmodule
243