OK, getting the flash programmer CPLD verilog finalized. This one seems to work as I want it to. It lets me have fine control over low address bits, coarse control over high ones, and control over the RD, WR, and CS going to the flash chip as well as when to drive the data lines and when to read in the read data from the flash.

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

And here is the test bench:

  1 // TOOL:   vlog2tf 
  2 // DATE:   07/11/15  10:39:08  
  3 // TITLE:   Lattice Semiconductor Corporation 
  4 // MODULE:  flashProgrammer 
  5 // DESIGN:  flashProgrammer 
  6 // FILENAME: flashProgrammer.tft 
  7 // PROJECT:  flashprog 
  8 // VERSION:  1.0 
  9 // This file is auto generated by the ispLEVER 
 10 
 11 
 12  
 13 `timescale 1 ns / 1 ns 
 14 
 15 
 16 // Define Module for Test Fixture 
 17 
 18 module flashProgrammer_tf(); 
 19 
 20 // Inputs 
 21 
 22 
 23   reg pin_ENABLE; 
 24   reg pin_CLK; 
 25   reg pin_Din; 
 26   reg pin_nCTRL; 
 27 
 28 // Outputs 
 29   wire pin_Dout; 
 30   wire [17:0] pins_A; 
 31   wire pin_nWR; 
 32   wire pin_nRD; 
 33   wire pin_nCS; 
 34 
 35 // Bidirs 
 36   wire [7:0] pins_D; 
 37 
 38 // Instantiate the UUT 
 39 
 40 
 41   flashProgrammer UUT ( 
 42     .pin_ENABLE(pin_ENABLE),  
 43     .pin_CLK(pin_CLK),  
 44     .pin_Din(pin_Din),  
 45     .pin_nCTRL(pin_nCTRL),  
 46     .pin_Dout(pin_Dout),  
 47     .pins_A(pins_A),  
 48     .pin_nWR(pin_nWR),  
 49     .pin_nRD(pin_nRD),  
 50     .pin_nCS(pin_nCS),  
 51     .pins_D(pins_D) 
 52     ); 
 53 
 54 
 55   flash simFlash ( 
 56     .A(pins_A), 
 57     .D(pins_D), 
 58     .nWR(pin_nWR), 
 59     .nRD(pin_nRD), 
 60     .nCS(pin_nCS) 
 61     ); 
 62 
 63   reg [2:0] ctrlToSend; 
 64   reg [17:0] aToSend; 
 65   reg [7:0] dToSend; 
 66   reg [3:0] cswrrdToSend; 
 67   reg [7:0] dRcvd; 
 68   reg [7:0] dShift; 
 69 
 70 
 71 
 72 
 73   initial begin 
 74 
 75 
 76     resetSequence(); 
 77     write(17'h12345, 8'haa); 
 78     simFlash.testRdD = 8'hC3; 
 79     $display("simFlash.testRdD = %h", simFlash.testRdD); 
 80     read(17'h0abcd, dRcvd); 
 81     resetSequence(); 
 82 
 83 
 84     write(17'h14567, 8'h55); 
 85     write(17'h14568, 8'h77); 
 86 
 87 
 88     simFlash.testRdD = 8'h3C; 
 89     $display("simFlash.testRdD = %h", simFlash.testRdD); 
 90     read(17'h19876, dRcvd); 
 91     simFlash.testRdD = 8'h55; 
 92     read(17'h19877, dRcvd); 
 93     #10 
 94     $finish; 
 95   end 
 96 
 97 
 98   task resetSequence; 
 99     begin 
100       aToSend = 0; 
101       dToSend = 0; 
102       pin_ENABLE = 1; 
103       pin_CLK = 0; 
104       pin_Din = 0; 
105       pin_nCTRL = 1; 
106 
107 
108       pulseClk(); 
109 
110 
111       #5  
112       pin_nCTRL = 0; // negedge resets outputs:w 
113 
114       pulseClk(); // CLK pulse resets flash_control 
115       pulseClk(); // CLK pulse resets flash_control 
116       pulseClk(); // CLK pulse resets flash_control 
117       #5  
118       pin_nCTRL = 1; // stobes chip control out 
119       #5  
120       pin_ENABLE = 0; 
121     end 
122   endtask 
123 
124 
125   task write; 
126     input [17:0] A; 
127     input [7:0] D; 
128     begin 
129       $display("Writing %h to %h.", D, A); 
130       setFullAddress(A); 
131       setCtrl(3'b000); 
132       sendData(D); 
133       setCtrl(3'b111); 
134       setDriveCsWrRd(0, 0, 1, 1); // drive, CS 
135       pulseCtrl(); 
136       setDriveCsWrRd(0, 0, 0, 1); // drive CS WR 
137       pulseCtrl(); 
138       setDriveCsWrRd(0, 0, 1, 1); // drive CS 
139       pulseCtrl();  
140       setDriveCsWrRd(1, 1, 1, 1); // done 
141       pulseCtrl(); 
142       $display("SimFlash saw %h<-%h", simFlash.testWrA, simFlash.testWrD); 
143 
144 
145       if (A != simFlash.testWrA) begin 
146         $display("ERROR!"); 
147         $finish; 
148       end 
149       if (D != simFlash.testWrD) begin 
150         $display("ERROR!"); 
151         $finish; 
152       end 
153     end 
154   endtask 
155 
156 
157   task read; 
158     input [17:0] A; 
159     output [7:0] D; 
160     begin 
161       $display("Reading %h.", A); 
162       setFullAddress(A); 
163       setCtrl(3'b111); 
164       setDriveCsWrRd(0, 0, 1, 0); // drive CS RD 
165       pulseCtrl(); 
166       setDriveCsWrRd(1, 0, 1, 0); // CS RD 
167       pulseCtrl(); 
168       setDriveCsWrRd(1, 1, 1, 1); // done 
169       pulseCtrl(); 
170       setCtrl(3'b000); 
171       recvData(); 
172       D = dShift; 
173       dShift = 8'bxxxxxxxx; 
174       $display("Read %h", D); 
175       $display("SimFlash saw %h", simFlash.testRdA); 
176       if (D != simFlash.testRdD) begin 
177         $display("ERROR!"); 
178         $finish; 
179       end 
180     end 
181   endtask 
182 
183 
184   task setFullAddress; 
185     input [17:0] A; 
186     begin 
187       if (A[3:0] != aToSend[3:0]) begin 
188         //$display("Writing A[3:0]"); 
189         setCtrl(3'b001); 
190         setAddr3_0(A[3:0]); 
191       end 
192       if (A[7:4] != aToSend[7:4]) begin 
193         //$display("Writing A[7:4]"); 
194         setCtrl(3'b010); 
195         setAddr7_4(A[7:4]); 
196       end 
197       if (A[17:8] != aToSend[17:8]) begin 
198         //$display("Writing A[17:8]"); 
199         setCtrl(3'b011); 
200         setAddr17_8(A[17:8]); 
201       end 
202     end 
203   endtask 
204 
205 
206   task setCtrl; 
207     input [2:0] regNo; 
208     begin 
209       ctrlToSend = regNo; 
210       #5 
211       pin_nCTRL = 0; 
212       pin_Din = ctrlToSend[0]; 
213       pulseClk(); 
214       pin_Din = ctrlToSend[1]; 
215       pulseClk(); 
216       pin_Din = ctrlToSend[2]; 
217       pulseClk(); 
218       #5 
219       pin_nCTRL = 1; 
220     end 
221   endtask 
222 
223   task pulseCtrl; 
224     begin 
225       #5 
226       pin_nCTRL = 0; 
227       #5 
228       pin_nCTRL = 1; 
229     end 
230   endtask 
231 
232   task pulseClk; 
233     begin 
234       #2 
235       pin_CLK = 0; 
236       #5 
237       pin_CLK = 1; 
238       #2 
239       pin_CLK = 0; 
240     end 
241   endtask 
242 
243 
244    
245 
246 
247   task setAddr3_0; 
248     input [3:0] addrPart; 
249     begin 
250       aToSend[3:0] = addrPart; 
251       pin_Din = aToSend[0]; 
252       pulseClk(); 
253       pin_Din = aToSend[1]; 
254       pulseClk(); 
255       pin_Din = aToSend[2]; 
256       pulseClk(); 
257       pin_Din = aToSend[3]; 
258       pulseClk(); 
259     end 
260   endtask 
261 
262 
263   task setAddr7_4; 
264     input [3:0] addrPart; 
265     begin 
266       aToSend[7:4] = addrPart; 
267       pin_Din = aToSend[4]; 
268       pulseClk(); 
269       pin_Din = aToSend[5]; 
270       pulseClk(); 
271       pin_Din = aToSend[6]; 
272       pulseClk(); 
273       pin_Din = aToSend[7]; 
274       pulseClk(); 
275     end 
276   endtask 
277 
278 
279   task setAddr17_8; 
280     input [9:0] addrPart; 
281     begin 
282       aToSend[17:8] = addrPart; 
283       pin_Din = aToSend[8]; 
284       pulseClk(); 
285       pin_Din = aToSend[9]; 
286       pulseClk(); 
287       pin_Din = aToSend[10]; 
288       pulseClk(); 
289       pin_Din = aToSend[11]; 
290       pulseClk(); 
291       pin_Din = aToSend[12]; 
292       pulseClk(); 
293       pin_Din = aToSend[13]; 
294       pulseClk(); 
295       pin_Din = aToSend[14]; 
296       pulseClk(); 
297       pin_Din = aToSend[15]; 
298       pulseClk(); 
299       pin_Din = aToSend[16]; 
300       pulseClk(); 
301       pin_Din = aToSend[17]; 
302       pulseClk(); 
303     end 
304   endtask 
305 
306 
307   task setDriveCsWrRd; 
308     input rqDrive; 
309     input rqCs; 
310     input rqWr; 
311     input rqRd; 
312     begin 
313       cswrrdToSend = { rqDrive, rqCs, rqWr, rqRd }; 
314       pin_Din = cswrrdToSend[0]; 
315       pulseClk(); 
316       pin_Din = cswrrdToSend[1]; 
317       pulseClk(); 
318       pin_Din = cswrrdToSend[2]; 
319       pulseClk(); 
320       pin_Din = cswrrdToSend[3]; 
321       pulseClk(); 
322     end 
323   endtask 
324 
325   task sendData; 
326     input [7:0] data; 
327     begin 
328       dToSend = data; 
329       pin_Din = dToSend[0]; 
330       pulseClk(); 
331       pin_Din = dToSend[1]; 
332       pulseClk(); 
333       pin_Din = dToSend[2]; 
334       pulseClk(); 
335       pin_Din = dToSend[3]; 
336       pulseClk(); 
337       pin_Din = dToSend[4]; 
338       pulseClk(); 
339       pin_Din = dToSend[5]; 
340       pulseClk(); 
341       pin_Din = dToSend[6]; 
342       pulseClk(); 
343       pin_Din = dToSend[7]; 
344       pulseClk(); 
345     end 
346   endtask 
347 
348   task recvData; 
349     begin 
350       pulseClk(); 
351       dShift[0] = pin_Dout; 
352       pulseClk(); 
353       dShift[1] = pin_Dout; 
354       pulseClk(); 
355       dShift[2] = pin_Dout; 
356       pulseClk(); 
357       dShift[3] = pin_Dout; 
358       pulseClk(); 
359       dShift[4] = pin_Dout; 
360       pulseClk(); 
361       dShift[5] = pin_Dout; 
362       pulseClk(); 
363       dShift[6] = pin_Dout; 
364       pulseClk(); 
365       dShift[7] = pin_Dout; 
366     end 
367 
368   endtask 
369 endmodule // flashProgrammer_tf 
370 
371 module flash( 
372   input [78:0] A, 
373   inout [7:0] D, 
374   input nWR, 
375   input nRD, 
376   input nCS, 
377 ); 
378 
379   reg [7:0] testWrD; 
380   reg [17:0] testWrA; 
381   reg [7:0] testRdD; 
382   reg [17:0] testRdA; 
383 
384   assign D = ((nRD | nCS) == 1'b0) ? testRdD : 8'bzzzzzzzz; 
385 
386   always @(posedge nRD) begin 
387     if (nCS == 1'b0) begin 
388       testRdA <= A; 
389     end 
390   end 
391 
392   always @(posedge nWR) begin 
393 
394     if (nCS == 1'b0) begin 
395       testWrA <= A; 
396       testWrD <= D; 
397     end 
398   end
399 
400 endmodule