]> git.sesse.net Git - pistorm/blob - rtl/pistorm.v
Add Meson build files.
[pistorm] / rtl / pistorm.v
1 /*
2  * Copyright 2020 Claude Schwarz
3  * Copyright 2020 Niklas Ekström - rewrite in Verilog
4  */
5 module pistorm(
6     output reg      PI_TXN_IN_PROGRESS, // GPIO0
7     output reg      PI_IPL_ZERO,        // GPIO1
8     input   [1:0]   PI_A,       // GPIO[3..2]
9     input           PI_CLK,     // GPIO4
10     output reg      PI_RESET,   // GPIO5
11     input           PI_RD,      // GPIO6
12     input           PI_WR,      // GPIO7
13     inout   [15:0]  PI_D,       // GPIO[23..8]
14
15     output reg      LTCH_A_0,
16     output reg      LTCH_A_8,
17     output reg      LTCH_A_16,
18     output reg      LTCH_A_24,
19     output reg      LTCH_A_OE_n,
20     output reg      LTCH_D_RD_U,
21     output reg      LTCH_D_RD_L,
22     output reg      LTCH_D_RD_OE_n,
23     output reg      LTCH_D_WR_U,
24     output reg      LTCH_D_WR_L,
25     output reg      LTCH_D_WR_OE_n,
26
27     input           M68K_CLK,
28     output  reg [2:0] M68K_FC,
29
30     output reg      M68K_AS_n,
31     output reg      M68K_UDS_n,
32     output reg      M68K_LDS_n,
33     output reg      M68K_RW,
34
35     input           M68K_DTACK_n,
36     input           M68K_BERR_n,
37
38     input           M68K_VPA_n,
39     output reg      M68K_E,
40     output reg      M68K_VMA_n,
41
42     input   [2:0]   M68K_IPL_n,
43
44     inout           M68K_RESET_n,
45     inout           M68K_HALT_n,
46
47     input           M68K_BR_n,
48     output reg      M68K_BG_n,
49     input           M68K_BGACK_n
50   );
51
52   wire c200m = PI_CLK;
53   reg [2:0] c7m_sync;
54 //  wire c7m = M68K_CLK;
55   wire c7m = c7m_sync[2];
56
57   localparam REG_DATA = 2'd0;
58   localparam REG_ADDR_LO = 2'd1;
59   localparam REG_ADDR_HI = 2'd2;
60   localparam REG_STATUS = 2'd3;
61
62   initial begin
63     PI_TXN_IN_PROGRESS <= 1'b0;
64     PI_IPL_ZERO <= 1'b0;
65
66     PI_RESET <= 1'b0;
67
68     M68K_FC <= 3'd0;
69
70     M68K_RW <= 1'b1;
71
72     M68K_E <= 1'b0;
73     M68K_VMA_n <= 1'b1;
74
75     M68K_BG_n <= 1'b1;
76   end
77
78   reg [1:0] rd_sync;
79   reg [1:0] wr_sync;
80
81   always @(posedge c200m) begin
82     rd_sync <= {rd_sync[0], PI_RD};
83     wr_sync <= {wr_sync[0], PI_WR};
84   end
85
86   wire rd_rising = !rd_sync[1] && rd_sync[0];
87   wire wr_rising = !wr_sync[1] && wr_sync[0];
88
89   reg [15:0] data_out;
90   assign PI_D = PI_A == REG_STATUS && PI_RD ? data_out : 16'bz;
91
92   always @(posedge c200m) begin
93     if (rd_rising && PI_A == REG_STATUS) begin
94       data_out <= {ipl, 13'd0};
95     end
96   end
97
98   reg [15:0] status;
99   wire reset_out = !status[1];
100
101   assign M68K_RESET_n = reset_out ? 1'b0 : 1'bz;
102   assign M68K_HALT_n = reset_out ? 1'b0 : 1'bz;
103
104   reg op_req = 1'b0;
105   reg op_rw = 1'b1;
106   reg op_uds_n = 1'b1;
107   reg op_lds_n = 1'b1;
108
109   always @(*) begin
110     LTCH_D_WR_U <= PI_A == REG_DATA && PI_WR;
111     LTCH_D_WR_L <= PI_A == REG_DATA && PI_WR;
112
113     LTCH_A_0 <= PI_A == REG_ADDR_LO && PI_WR;
114     LTCH_A_8 <= PI_A == REG_ADDR_LO && PI_WR;
115
116     LTCH_A_16 <= PI_A == REG_ADDR_HI && PI_WR;
117     LTCH_A_24 <= PI_A == REG_ADDR_HI && PI_WR;
118
119     LTCH_D_RD_OE_n <= !(PI_A == REG_DATA && PI_RD);
120   end
121
122   reg a0;
123
124   always @(posedge c200m) begin
125     c7m_sync <= {c7m_sync[1:0], M68K_CLK};
126   end
127
128   wire c7m_rising = !c7m_sync[2] && c7m_sync[1];
129   wire c7m_falling = c7m_sync[2] && !c7m_sync[1];
130
131   reg [2:0] ipl;
132   reg [2:0] ipl_1;
133   reg [2:0] ipl_2;
134
135   always @(posedge c200m) begin
136     if (c7m_falling) begin
137       ipl_1 <= ~M68K_IPL_n;
138       ipl_2 <= ipl_1;
139     end
140
141     if (ipl_2 == ipl_1)
142       ipl <= ipl_2;
143
144     PI_IPL_ZERO <= ipl == 3'd0;
145   end
146
147   always @(posedge c200m) begin
148     PI_RESET <= reset_out ? 1'b1 : M68K_RESET_n;
149   end
150
151   reg [3:0] e_counter = 4'd0;
152
153   always @(negedge c7m) begin
154     if (e_counter == 4'd9)
155       e_counter <= 4'd0;
156     else
157       e_counter <= e_counter + 4'd1;
158   end
159
160   always @(negedge c7m) begin
161     if (e_counter == 4'd9)
162       M68K_E <= 1'b0;
163     else if (e_counter == 4'd5)
164       M68K_E <= 1'b1;
165   end
166
167   reg [2:0] state = 3'd0;
168   reg [2:0] PI_TXN_IN_PROGRESS_delay;
169
170   always @(posedge c200m) begin
171
172     if (wr_rising) begin
173       case (PI_A)
174         REG_ADDR_LO: begin
175           a0 <= PI_D[0];
176           PI_TXN_IN_PROGRESS <= 1'b1;
177         end
178         REG_ADDR_HI: begin
179           op_req <= 1'b1;
180           op_rw <= PI_D[9];
181           op_uds_n <= PI_D[8] ? a0 : 1'b0;
182           op_lds_n <= PI_D[8] ? !a0 : 1'b0;
183         end
184         REG_STATUS: begin
185           status <= PI_D;
186         end
187       endcase
188     end
189
190     case (state)
191       3'd0: begin // S0
192         M68K_RW <= 1'b1; // S7 -> S0
193 //        if (c7m_falling) begin
194 //          if (op_req) begin
195             state <= 2'd1;
196 //          end
197 //        end
198       end
199
200       3'd1: begin // S1
201         if (op_req) begin
202           if(c7m_rising) begin
203             state <= 3'd2;
204           end
205         end
206       end
207       3'd2: begin // S2
208         M68K_RW <= op_rw; // S1 -> S2
209         LTCH_D_WR_OE_n <= op_rw;
210         LTCH_A_OE_n <= 1'b0;
211         M68K_AS_n <= 1'b0;
212         M68K_UDS_n <= op_rw ? op_uds_n : 1'b1;
213         M68K_LDS_n <= op_rw ? op_lds_n : 1'b1;
214         if (c7m_falling) begin
215           M68K_UDS_n <= op_uds_n;
216           M68K_LDS_n <= op_lds_n;
217           state <= 3'd3;
218         end
219       end
220
221       3'd3: begin // S3
222         op_req <= 1'b0;
223         if(c7m_rising) begin
224           if (!M68K_DTACK_n || (!M68K_VMA_n && e_counter == 4'd8)) begin
225             state <= 3'd4;
226             PI_TXN_IN_PROGRESS_delay[2:0] <= 3'b111;
227           end
228           else begin
229             if (!M68K_VPA_n && e_counter == 4'd2) begin
230               M68K_VMA_n <= 1'b0;
231             end
232           end
233         end
234       end
235       3'd4: begin // S4
236         PI_TXN_IN_PROGRESS_delay <= {PI_TXN_IN_PROGRESS_delay[1:0],1'b0};
237         PI_TXN_IN_PROGRESS <= PI_TXN_IN_PROGRESS_delay[2];
238         LTCH_D_RD_U <= 1'b1;
239         LTCH_D_RD_L <= 1'b1;
240         if (c7m_falling) begin
241           state <= 3'd5;
242           PI_TXN_IN_PROGRESS <= 1'b0;
243         end
244       end
245
246       3'd5: begin // S5
247         LTCH_D_RD_U <= 1'b0;
248         LTCH_D_RD_L <= 1'b0;
249         if (c7m_rising) begin
250           state <= 3'd6;
251         end
252       end
253        
254       3'd6: begin // S6
255         if (c7m_falling) begin
256           M68K_VMA_n <= 1'b1;
257           state <= 3'd7;
258         end
259       end
260        
261       3'd7: begin // S7
262         LTCH_D_WR_OE_n <= 1'b1;
263         LTCH_A_OE_n <= 1'b1;
264         M68K_AS_n <= 1'b1;
265         M68K_UDS_n <= 1'b1;
266         M68K_LDS_n <= 1'b1;
267 //        if(c7m_rising) begin
268 //          M68K_RW <= 1'b1; // S7 -> S0
269           state <= 3'd0;
270 //        end
271       end
272     endcase
273   end
274
275 endmodule