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.
// This module has a set of serial registers that can be used to
// interface to an 8 bit wide 2MB chip.
// Usage requires a software driver that does the following:
//
// Reset:
// bring pin_ENABLE high,
// toggle pin_nCTRL low high low
// toggle pin_CLK low high low
// bring pin_ENABLE low
//
// Write A[3:0] bits of address bus;
// bring pin_nCTRL low
// put 0 on pin_Din
// toggle pin_CLK high low
// put 0 on pin_Din
// toggle pin_CLK high low
// put 1 on pin_Din
// toggle pin_CLK high low
// bring pin_nCTRL high
// put A[0] in pin_Din
// toggle pin_CLK high low
// put A[1] in pin_Din
// toggle pin_CLK high low
// put A[2] in pin_Din
// toggle pin_CLK high low
// put A[3] in pin_Din
// toggle pin_CLK high low
//
// Write A[7:4] bits of address bus;
// bring pin_nCTRL low
// put 0 on pin_Din
// toggle pin_CLK high low
// put 1 on pin_Din
// toggle pin_CLK high low
// put 0 on pin_Din
// toggle pin_CLK high low
// bring pin_nCTRL high
// put A[4] in pin_Din
// toggle pin_CLK high low
// put A[5] in pin_Din
// toggle pin_CLK high low
// put A[6] in pin_Din
// toggle pin_CLK high low
// put A[7] in pin_Din
// toggle pin_CLK high low
//
// Write A[17:8] bits of address bus;
// bring pin_nCTRL low
// put 1 on pin_Din
// toggle pin_CLK high low
// put 1 on pin_Din
// toggle pin_CLK high low
// put 0 on pin_Din
// toggle pin_CLK high low
// bring pin_nCTRL high
// put A[8] in pin_Din
// toggle pin_CLK high low
// put A[9] in pin_Din
// toggle pin_CLK high low
// put A[10] in pin_Din
// toggle pin_CLK high low
// put A[11] in pin_Din
// toggle pin_CLK high low
// put A[12] in pin_Din
// toggle pin_CLK high low
// put A[13] in pin_Din
// toggle pin_CLK high low
// put A[14] in pin_Din
// toggle pin_CLK high low
// put A[15] in pin_Din
// toggle pin_CLK high low
// put A[16] in pin_Din
// toggle pin_CLK high low
// put A[17] in pin_Din
// toggle pin_CLK high low
//
// Write RD* WR* CS*
// bring pin_nCTRL low
// put 1 on pin_Din
// toggle pin_CLK high low
// put 1 on pin_Din
// toggle pin_CLK high low
// put 1 on pin_Din
// toggle pin_CLK high low
// bring pin_nCTRL high
// put RD* in pin_Din
// toggle pin_CLK high low
// put WR* in pin_Din
// toggle pin_CLK high low
// put CS* in pin_Din
// toggle pin_CLK high low
//
// Write data bus to be asserted while WR* low;
// bring pin_nCTRL low
// put 0 on pin_Din
// toggle pin_CLK high low
// put 0 on pin_Din
// toggle pin_CLK high low
// put 0 on pin_Din
// toggle pin_CLK high low
// bring pin_nCTRL high
// put D[0] in pin_Din
// toggle pin_CLK high low
// put D[1] in pin_Din
// toggle pin_CLK high low
// put D[2] in pin_Din
// toggle pin_CLK high low
// put D[3] in pin_Din
// toggle pin_CLK high low
// put D[4] in pin_Din
// toggle pin_CLK high low
// put D[5] in pin_Din
// toggle pin_CLK high low
// put D[6] in pin_Din
// toggle pin_CLK high low
// put D[7] in pin_Din
// toggle pin_CLK high low
//
// Load data bus read on RD* rising edge;
// bring pin_nCTRL low
// put 0 on pin_Din
// toggle pin_CLK high low
// put 0 on pin_Din
// toggle pin_CLK high low
// put 0 on pin_Din
// toggle pin_CLK high low
// bring pin_nCTRL high
// toggle pin_CLK high low
// data = (data >> 1) | (pin_Dout << 7)
// toggle pin_CLK high low
// data = (data >> 1) | (pin_Dout << 7)
// toggle pin_CLK high low
// data = (data >> 1) | (pin_Dout << 7)
// toggle pin_CLK high low
// data = (data >> 1) | (pin_Dout << 7)
// toggle pin_CLK high low
// data = (data >> 1) | (pin_Dout << 7)
// toggle pin_CLK high low
// data = (data >> 1) | (pin_Dout << 7)
// toggle pin_CLK high low
// data = (data >> 1) | (pin_Dout << 7)
// toggle pin_CLK high low
// data = (data >> 1) | (pin_Dout << 7)
//
//
module cpld(
input pin_ENABLE,
input pin_CLK,
input pin_Din,
input pin_nCTRL,
output reg pin_Dout,
output [17:0] pins_A,
output reg pin_nWR,
output reg pin_nRD,
output reg pin_nCS,
inout [7:0] pins_D
);
reg [2:0] ctrlReg;
reg [7:0] dataReg;
reg [17:0] addrReg;
reg [3:0] chipReg;
reg nOE;
reg prev_n_Ctrl;
wire nRDint;
wire nWRint;
wire nCSint;
wire nOEint;
assign nRDint = chipReg[0];
assign nWRint = chipReg[1];
assign nCSint = chipReg[2];
assign nOEint = chipReg[3];
assign pins_D = ((nOE | pin_ENABLE) == 1'b0) ? dataReg : 8'bzzzzzzzz;
assign pins_A = (pin_ENABLE == 1'b1) ? addrReg : 18'bzzzzzzzzzzzzzzzzzz;
always @(posedge pin_CLK) begin
prev_nCtrl <= pin_nCtrl;
if (pin_nCTRL == 1'b0) begin
// clocking in control
pin_Dout <= ctrlReg[2];
ctrlReg <= {pin_Din, ctrlReg[2:1]};
if (pin_ENABLE == 1'b1) begin
chipReg <= 4'b1111;
end
end
else if (prev_nCtrl == 1'b0) begin
// first rising pulse after nCtrl was programmed
// If readinbg, read now
if (pin_nRD == 1'b0) begin
dataReg <= D;
end
// Strobe out of the chip
pins_A <= reg_a;
pin_nRD <= nRDint;
pin_nWR <= nWRint;
pin_nCS <= nCSint;
nOE <= nOEint;
end
else begin
case (ctrlReg)
3'b000 : begin
pin_Dout <= dataReg[0];
dataReg <= { pin_Din, dataReg[7:1]};
end
3'b001 : begin
pin_Dout <= addrReg[0];
addrReg[3:0] <= { pin_Din, addrReg[3:1]};
end
3'b010 : begin
pin_Dout <= addrReg[4];
addrReg[7:4] <= { pin_Din, addrReg[7:5]};
end
3'b011 : begin
pin_Dout <= addrReg[8];
addrReg[17:8] <= { pin_Din, addrReg[17:9]};
end
3'b100 : begin
end
3'b101 : begin
end
3'b110 : begin
end
3'b111 : begin
pin_Dout <= chipReg[0];
chipReg <= { pin_Din, chipReg[3:1]};
end
endcase
end
end
endmodule
No comments:
Post a Comment