2 * Copyright 2020 Claude Schwarz
3 * Copyright 2020 Niklas Ekström - rewrite in Verilog
6 output reg PI_TXN_IN_PROGRESS, // GPIO0
7 output reg PI_IPL_ZERO, // GPIO1
8 input [1:0] PI_A, // GPIO[3..2]
10 output reg PI_RESET, // GPIO5
13 inout [15:0] PI_D, // GPIO[23..8]
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,
28 output reg [2:0] M68K_FC,
31 output reg M68K_UDS_n,
32 output reg M68K_LDS_n,
40 output reg M68K_VMA_n,
42 input [2:0] M68K_IPL_n,
54 // wire c7m = M68K_CLK;
55 wire c7m = c7m_sync[2];
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;
63 PI_TXN_IN_PROGRESS <= 1'b0;
81 always @(posedge c200m) begin
82 rd_sync <= {rd_sync[0], PI_RD};
83 wr_sync <= {wr_sync[0], PI_WR};
86 wire rd_rising = !rd_sync[1] && rd_sync[0];
87 wire wr_rising = !wr_sync[1] && wr_sync[0];
90 assign PI_D = PI_A == REG_STATUS && PI_RD ? data_out : 16'bz;
92 always @(posedge c200m) begin
93 if (rd_rising && PI_A == REG_STATUS) begin
94 data_out <= {ipl, 13'd0};
99 wire reset_out = !status[1];
101 assign M68K_RESET_n = reset_out ? 1'b0 : 1'bz;
102 assign M68K_HALT_n = reset_out ? 1'b0 : 1'bz;
110 LTCH_D_WR_U <= PI_A == REG_DATA && PI_WR;
111 LTCH_D_WR_L <= PI_A == REG_DATA && PI_WR;
113 LTCH_A_0 <= PI_A == REG_ADDR_LO && PI_WR;
114 LTCH_A_8 <= PI_A == REG_ADDR_LO && PI_WR;
116 LTCH_A_16 <= PI_A == REG_ADDR_HI && PI_WR;
117 LTCH_A_24 <= PI_A == REG_ADDR_HI && PI_WR;
119 LTCH_D_RD_OE_n <= !(PI_A == REG_DATA && PI_RD);
124 always @(posedge c200m) begin
125 c7m_sync <= {c7m_sync[1:0], M68K_CLK};
128 wire c7m_rising = !c7m_sync[2] && c7m_sync[1];
129 wire c7m_falling = c7m_sync[2] && !c7m_sync[1];
135 always @(posedge c200m) begin
136 if (c7m_falling) begin
137 ipl_1 <= ~M68K_IPL_n;
144 PI_IPL_ZERO <= ipl == 3'd0;
147 always @(posedge c200m) begin
148 PI_RESET <= reset_out ? 1'b1 : M68K_RESET_n;
151 reg [3:0] e_counter = 4'd0;
153 always @(negedge c7m) begin
154 if (e_counter == 4'd9)
157 e_counter <= e_counter + 4'd1;
160 always @(negedge c7m) begin
161 if (e_counter == 4'd9)
163 else if (e_counter == 4'd5)
167 reg [2:0] state = 3'd0;
168 reg [2:0] PI_TXN_IN_PROGRESS_delay;
170 always @(posedge c200m) begin
176 PI_TXN_IN_PROGRESS <= 1'b1;
181 op_uds_n <= PI_D[8] ? a0 : 1'b0;
182 op_lds_n <= PI_D[8] ? !a0 : 1'b0;
192 M68K_RW <= 1'b1; // S7 -> S0
193 // if (c7m_falling) begin
208 M68K_RW <= op_rw; // S1 -> S2
209 LTCH_D_WR_OE_n <= op_rw;
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;
224 if (!M68K_DTACK_n || (!M68K_VMA_n && e_counter == 4'd8)) begin
226 PI_TXN_IN_PROGRESS_delay[2:0] <= 3'b111;
229 if (!M68K_VPA_n && e_counter == 4'd2) begin
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];
240 if (c7m_falling) begin
242 PI_TXN_IN_PROGRESS <= 1'b0;
249 if (c7m_rising) begin
255 if (c7m_falling) begin
262 LTCH_D_WR_OE_n <= 1'b1;
267 // if(c7m_rising) begin
268 // M68K_RW <= 1'b1; // S7 -> S0