OK, so I’m working on the Verilog for 3 CPLDs. A memory bank switcher, a UART SPI controller, and a flash programmer that I’ll interface to an Arduino. This is my attempt to write the flash programmer.

The Arduino will use a nCTRL, Din, Dout, CLK, and ENABLE pins to control it serially.

When nCTRL is low, three bits are clocked (CLK high then low) into an address register. Then when nCTRL is high, the data is clocked into the registers addressed by the 3 bit register specified when nCTRL was low.

The comments in the header are  no longer accurate. I now have a single clock pulse after nCRTL goes high that just strobes data from the registers to the pins without changing nay register contents. So they need to be updated. But this is the preliminary verilog.

Reg 0: Data read/write Reg 1: Lowest 4 bits of the address Reg 2: Bits 8:5 of the address Reg 3: Bits 17:9 of the address Reg7: nRD, nWR, nCS, and data pin drive.

I’m sure this verilog will be very different once it’s done. I’ll post the test-bench and the final version later.

I’ll also post my C driver on the Arduino and a C# program on my PC.

  1 // This module has a set of serial registers that can be used to
  2 // interface to an 8 bit wide 2MB chip.
  3 // Usage requires a software driver that does the following:
  4 //
  5 // Reset:
  6 //    bring pin_ENABLE high,
  7 //    toggle pin_nCTRL low high low
  8 //    toggle pin_CLK low high low
  9 //    bring pin_ENABLE low
 10 //
 11 // Write A[3:0] bits of address bus;
 12 //    bring pin_nCTRL low
 13 //    put 0 on pin_Din
 14 //    toggle pin_CLK high low
 15 //    put 0 on pin_Din
 16 //    toggle pin_CLK high low
 17 //    put 1 on pin_Din
 18 //    toggle pin_CLK high low
 19 //    bring pin_nCTRL high
 20 //    put A[0] in pin_Din
 21 //    toggle pin_CLK high low
 22 //    put A[1] in pin_Din
 23 //    toggle pin_CLK high low
 24 //    put A[2] in pin_Din
 25 //    toggle pin_CLK high low
 26 //    put A[3] in pin_Din
 27 //    toggle pin_CLK high low
 28 //
 29 // Write A[7:4] bits of address bus;
 30 //    bring pin_nCTRL low
 31 //    put 0 on pin_Din
 32 //    toggle pin_CLK high low
 33 //    put 1 on pin_Din
 34 //    toggle pin_CLK high low
 35 //    put 0 on pin_Din
 36 //    toggle pin_CLK high low
 37 //    bring pin_nCTRL high
 38 //    put A[4] in pin_Din
 39 //    toggle pin_CLK high low
 40 //    put A[5] in pin_Din
 41 //    toggle pin_CLK high low
 42 //    put A[6] in pin_Din
 43 //    toggle pin_CLK high low
 44 //    put A[7] in pin_Din
 45 //    toggle pin_CLK high low
 46 //
 47 // Write A[17:8] bits of address bus;
 48 //    bring pin_nCTRL low
 49 //    put 1 on pin_Din
 50 //    toggle pin_CLK high low
 51 //    put 1 on pin_Din
 52 //    toggle pin_CLK high low
 53 //    put 0 on pin_Din
 54 //    toggle pin_CLK high low
 55 //    bring pin_nCTRL high
 56 //    put A[8] in pin_Din
 57 //    toggle pin_CLK high low
 58 //    put A[9] in pin_Din
 59 //    toggle pin_CLK high low
 60 //    put A[10] in pin_Din
 61 //    toggle pin_CLK high low
 62 //    put A[11] in pin_Din
 63 //    toggle pin_CLK high low
 64 //    put A[12] in pin_Din
 65 //    toggle pin_CLK high low
 66 //    put A[13] in pin_Din
 67 //    toggle pin_CLK high low
 68 //    put A[14] in pin_Din
 69 //    toggle pin_CLK high low
 70 //    put A[15] in pin_Din
 71 //    toggle pin_CLK high low
 72 //    put A[16] in pin_Din
 73 //    toggle pin_CLK high low
 74 //    put A[17] in pin_Din
 75 //    toggle pin_CLK high low
 76 //
 77 // Write RD* WR* CS*
 78 //    bring pin_nCTRL low
 79 //    put 1 on pin_Din
 80 //    toggle pin_CLK high low
 81 //    put 1 on pin_Din
 82 //    toggle pin_CLK high low
 83 //    put 1 on pin_Din
 84 //    toggle pin_CLK high low
 85 //    bring pin_nCTRL high
 86 //    put RD* in pin_Din
 87 //    toggle pin_CLK high low
 88 //    put WR* in pin_Din
 89 //    toggle pin_CLK high low
 90 //    put CS* in pin_Din
 91 //    toggle pin_CLK high low
 92 //
 93 // Write data bus to be asserted while WR* low;
 94 //    bring pin_nCTRL low
 95 //    put 0 on pin_Din
 96 //    toggle pin_CLK high low
 97 //    put 0 on pin_Din
 98 //    toggle pin_CLK high low
 99 //    put 0 on pin_Din
100 //    toggle pin_CLK high low
101 //    bring pin_nCTRL high
102 //    put D[0] in pin_Din
103 //    toggle pin_CLK high low
104 //    put D[1] in pin_Din
105 //    toggle pin_CLK high low
106 //    put D[2] in pin_Din
107 //    toggle pin_CLK high low
108 //    put D[3] in pin_Din
109 //    toggle pin_CLK high low
110 //    put D[4] in pin_Din
111 //    toggle pin_CLK high low
112 //    put D[5] in pin_Din
113 //    toggle pin_CLK high low
114 //    put D[6] in pin_Din
115 //    toggle pin_CLK high low
116 //    put D[7] in pin_Din
117 //    toggle pin_CLK high low
118 //
119 // Load data bus read on RD* rising edge;
120 //    bring pin_nCTRL low
121 //    put 0 on pin_Din
122 //    toggle pin_CLK high low
123 //    put 0 on pin_Din
124 //    toggle pin_CLK high low
125 //    put 0 on pin_Din
126 //    toggle pin_CLK high low
127 //    bring pin_nCTRL high
128 //    toggle pin_CLK high low
129 //    data = (data >> 1) | (pin_Dout << 7)
130 //    toggle pin_CLK high low
131 //    data = (data >> 1) | (pin_Dout << 7)
132 //    toggle pin_CLK high low
133 //    data = (data >> 1) | (pin_Dout << 7)
134 //    toggle pin_CLK high low
135 //    data = (data >> 1) | (pin_Dout << 7)
136 //    toggle pin_CLK high low
137 //    data = (data >> 1) | (pin_Dout << 7)
138 //    toggle pin_CLK high low
139 //    data = (data >> 1) | (pin_Dout << 7)
140 //    toggle pin_CLK high low
141 //    data = (data >> 1) | (pin_Dout << 7)
142 //    toggle pin_CLK high low
143 //    data = (data >> 1) | (pin_Dout << 7)
144 //  
145 //
146 
147 module cpld(
148   input pin_ENABLE,
149   input pin_CLK,
150   input pin_Din,
151   input pin_nCTRL,
152   output reg pin_Dout,
153 
154   output [17:0] pins_A,
155   output reg pin_nWR,
156   output reg pin_nRD,
157   output reg pin_nCS,
158   inout [7:0] pins_D
159   );
160 
161   reg [2:0] ctrlReg;
162   reg [7:0] dataReg;
163   reg [17:0] addrReg;
164   reg [3:0] chipReg;
165   reg nOE;
166   reg prev_n_Ctrl;
167 
168   wire nRDint;
169   wire nWRint;
170   wire nCSint;
171   wire nOEint;
172 
173   assign nRDint = chipReg[0];
174   assign nWRint = chipReg[1];
175   assign nCSint = chipReg[2];
176   assign nOEint = chipReg[3];
177 
178   assign pins_D = ((nOE | pin_ENABLE) == 1'b0) ? dataReg : 8'bzzzzzzzz;
179   assign pins_A = (pin_ENABLE == 1'b1) ? addrReg : 18'bzzzzzzzzzzzzzzzzzz;
180 
181   always @(posedge pin_CLK) begin
182 
183     prev_nCtrl <= pin_nCtrl;
184 
185     if (pin_nCTRL == 1'b0) begin
186 
187       // clocking in control
188       pin_Dout <= ctrlReg[2];
189       ctrlReg <= {pin_Din, ctrlReg[2:1]};
190 
191       if (pin_ENABLE == 1'b1) begin
192         chipReg <= 4'b1111;
193       end
194     end
195     else if (prev_nCtrl == 1'b0) begin
196 
197       // first rising pulse after nCtrl was programmed
198 
199       // If readinbg, read now
200       if (pin_nRD == 1'b0) begin
201         dataReg <= D;
202       end
203 
204       // Strobe out of the chip
205       pins_A <= reg_a;
206       pin_nRD <= nRDint;
207       pin_nWR <= nWRint;
208       pin_nCS <= nCSint;
209       nOE <= nOEint;
210     end
211     else begin
212       case (ctrlReg)
213         3'b000 : begin
214           pin_Dout <= dataReg[0];
215           dataReg <= { pin_Din, dataReg[7:1]};
216         end
217         3'b001 : begin
218           pin_Dout <= addrReg[0];
219           addrReg[3:0] <= { pin_Din, addrReg[3:1]};
220         end
221         3'b010 : begin
222           pin_Dout <= addrReg[4];
223           addrReg[7:4] <= { pin_Din, addrReg[7:5]};
224         end
225         3'b011 : begin
226           pin_Dout <= addrReg[8];
227           addrReg[17:8] <= { pin_Din, addrReg[17:9]};
228         end
229         3'b100 : begin
230         end
231         3'b101 : begin
232         end
233         3'b110 : begin
234         end
235         3'b111 : begin
236           pin_Dout <= chipReg[0];
237           chipReg <= { pin_Din, chipReg[3:1]};
238         end
239       endcase
240     end
241   end
242 
243 
244 endmodule