// This CPLD is a timer circuit that generates a 500Hz tick. It takes a 2MHz
// clock in. Scales that down to 125MHz with a 4 bit counter.
// Then it counts 125 of those in a 7 bit counter that resets on 7c.
// When the reset occurs, the pin_nINT line goes from Hi-Z to low.
//
// The falling edge of pin_nCS pin brings pin_nINT back to Hi-Z.
//
// SCK and Dout are used to read the 3 bit tick counter. This is used
// to ensure that the count is kept synched. Dout is updated on the
// falling edge of SCK and the MSB is shifted first.
//
module timer (
input pin_CLK,
input pin_nCS,
input pin_SCK,
output pin_Dout,
output pin_nINT
/*
output [3:0] test_prescaler,
output [6:0] test_counter,
output [2:0] test_ticks,
output [2:0] test_tickShift,
output test_nCount,
output test_nTick,
output test_nInt,
output test_nCS0,
output test_nCS1
*/
);
/*
assign test_prescaler = prescaler;
assign test_counter = counter;
assign test_ticks = ticks;
assign test_tickShift = tickShift;
assign test_nCount = nCount;
assign test_nTick = nTick;
assign test_nInt = nInt;
assign test_nCS0 = nCS0;
assign test_nCS1 = nCS1;
*/
reg [3:0] prescaler;
reg [6:0] counter;
reg [2:0] ticks;
reg [2:0] tickShift;
reg nCount;
reg nTick;
reg nInt;
reg nCS0;
reg nCS1;
reg SCK0;
reg SCK1;
initial begin
prescaler = 0;
counter = 0;
ticks = 0;
end
assign pin_nINT = (nInt == 1'b1) ? 1'bz : 1'b0;
always @(posedge pin_CLK) begin
prescaler <= prescaler + 1;
nCount <= ~(&prescaler); // 0 once every 16 pin_CLK
nTick <= ~(counter == 7'b1111100); // 124 caused 125->0
if (nCount == 1'b0) begin
if (nTick == 1'b0) begin
counter <= 0;
ticks <= ticks+1;
end
else begin
counter <= counter+1;
end
end
nCS0 <= pin_nCS;
nCS1 <= nCS0;
// Set interrupt on the CLK. Reset it on the falling edge of
// pin_nCS+2 clocks
if ((nTick | nCount) == 1'b0) begin
nInt <= 1'b0;
end
else if ((nCS1 & (~nCS0)) == 1'b1) begin
nInt <= 1'b1;
end
SCK0 <= pin_SCK;
SCK1 <= SCK0;
if (~pin_nCS) begin
//if (SCK1 & ~SCK0) begin
if (SCK0 & ~pin_SCK) begin
tickShift[2:0] <= { tickShift[1:0], 1'b0 };
end
end
else begin
tickShift[2:0] <= ticks[2:0];
end
end
assign pin_Dout = pin_nCS ? 1'bz : tickShift[2];
endmodule
Wednesday, August 19, 2015
Timer CPLD
Here is the verilog for the 4th CPLD that I figured out I need. It's a 1ms timer. It will pull the interrupt pin low and return to Hi-Z mode when the interrupt is cleared by reading the tick counter. The tick counter is 3 bits and can be used to ensure some degree of consistency when late servicing the tick interrupt or when using shared interrupts (which I will do). It has a very small pin footprint. Just clock, read-only SPI, chip select, and the interrupt line. This one fits into the smaller M4A5-32/32 so I'll use that.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment