|
|
`include "timescale.v"
|
`include "timescale.v"
|
`include "defines.v"
|
`include "defines.v"
|
|
|
|
|
module timer (clk, en, reset, type, preset, DN, TT, ACC);
|
module timer (clk, en, reset, type, preset, DN, TT, ACC);
|
|
|
input clk, en, reset;
|
input clk, en, reset;
|
input [`tcTypeLen-1:0] type;
|
input [`tcTypeLen-1:0] type;
|
input [`tcPresetLen-1:0] preset;
|
input [`tcPresetLen-1:0] preset;
|
|
|
output DN, TT;
|
output DN, TT;
|
output [`tcAccLen-1:0] ACC;
|
output [`tcAccLen-1:0] ACC;
|
|
|
reg DN = 0, TT = 0;
|
reg DN = 0, TT = 0;
|
reg [`tcAccLen-1:0] ACC = 0;
|
reg [`tcAccLen-1:0] ACC = 0;
|
|
|
reg [`tcTypeLen-1:0] TimerType;
|
reg [`tcTypeLen-1:0] TimerType;
|
reg [`tcTypeLen-1:0] typeNext;
|
reg [`tcTypeLen-1:0] typeNext;
|
|
|
|
|
|
|
parameter OnDelayTimer = `tcTypeLen'b0;
|
parameter OnDelayTimer = `tcTypeLen'b0;
|
parameter OffDelayTimer = `tcTypeLen'b1;
|
parameter OffDelayTimer = `tcTypeLen'b1;
|
parameter RetOnDelayTimer = `tcTypeLen'b10;
|
parameter RetOnDelayTimer = `tcTypeLen'b10;
|
parameter defaultType = `tcTypeLen'b11;
|
parameter defaultType = `tcTypeLen'b11;
|
|
|
always @ (type)
|
always @ (type)
|
begin
|
begin
|
case (type)
|
case (type)
|
|
|
`timerType1 : begin
|
`timerType1 : begin
|
typeNext = OnDelayTimer;
|
typeNext = OnDelayTimer;
|
end
|
end
|
|
|
`timerType2 : begin
|
`timerType2 : begin
|
typeNext = OffDelayTimer;
|
typeNext = OffDelayTimer;
|
end
|
end
|
|
|
`timerType3 : begin
|
`timerType3 : begin
|
typeNext = RetOnDelayTimer;
|
typeNext = RetOnDelayTimer;
|
end
|
end
|
|
|
default : begin
|
default : begin
|
|
|
$display(" Timer is defined for unknown type.\n Valid types: On-delay, Off-delay, retentive-on-delay");
|
$display("\nTimer is defined for unknown type.\n Valid types: On-delay, Off-delay, retentive-on-delay");
|
end
|
end
|
|
|
endcase
|
endcase
|
end
|
end
|
|
|
|
|
always @ (posedge clk or posedge reset)
|
always @ (posedge clk or posedge reset)
|
begin
|
begin
|
if (reset)
|
if (reset)
|
begin
|
begin
|
$write (" timer module is reset ");
|
$write ("\ntimer module is reset ");
|
TimerType = defaultType;
|
TimerType = defaultType;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
TimerType = typeNext;
|
TimerType = typeNext;
|
end
|
end
|
end
|
end
|
|
|
|
|
always @ (posedge clk)
|
always @ (posedge clk)
|
begin
|
begin
|
|
|
|
|
case (TimerType)
|
case (TimerType)
|
|
|
OnDelayTimer : begin
|
OnDelayTimer : begin
|
if (reset)
|
if (reset)
|
begin
|
begin
|
ACC = `tcAccLen'b0;
|
ACC = `tcAccLen'b0;
|
DN = 1'b0;
|
DN = 1'b0;
|
TT = 1'b0;
|
TT = 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if (en)
|
if (en)
|
begin
|
begin
|
if (ACC < preset)
|
if (ACC < preset)
|
begin
|
begin
|
ACC = ACC + 1'b1;
|
ACC = ACC + 1'b1;
|
DN = 1'b0;
|
DN = 1'b0;
|
TT = 1'b1;
|
TT = 1'b1;
|
end
|
end
|
else if (ACC >= preset)
|
else if (ACC >= preset)
|
begin
|
begin
|
ACC = ACC;
|
ACC = ACC;
|
|
|
DN = 1'b1;
|
DN = 1'b1;
|
TT = 1'b0;
|
TT = 1'b0;
|
end
|
end
|
end
|
end
|
else
|
else
|
begin
|
begin
|
ACC = `tcAccLen'b0; // if not enabled
|
ACC = `tcAccLen'b0; // if not enabled
|
DN = 1'b0;
|
DN = 1'b0;
|
TT = 1'b0;
|
TT = 1'b0;
|
end
|
end
|
end
|
end
|
end // end this case
|
end // end this case
|
|
|
OffDelayTimer : begin // not correct implementation!
|
OffDelayTimer : begin // not correct implementation!
|
if (reset)
|
if (reset)
|
begin
|
begin
|
ACC = `tcAccLen'b0;
|
ACC = `tcAccLen'b0;
|
DN = 1'b0;
|
DN = 1'b0;
|
TT = 1'b0;
|
TT = 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if (!en)
|
if (!en)
|
begin
|
begin
|
if (ACC < preset)
|
if (ACC < preset)
|
begin
|
begin
|
ACC = ACC + 1'b1;
|
ACC = ACC + 1'b1;
|
DN = 1'b0;
|
DN = 1'b0;
|
TT = 1'b1;
|
TT = 1'b1;
|
end
|
end
|
else if (ACC >= preset)
|
else if (ACC >= preset)
|
begin
|
begin
|
ACC = ACC;
|
ACC = ACC;
|
DN = 1'b1;
|
DN = 1'b1;
|
TT = 1'b0;
|
TT = 1'b0;
|
end
|
end
|
end
|
end
|
else
|
else
|
begin
|
begin
|
ACC = `tcAccLen'b0; // if not enabled
|
ACC = `tcAccLen'b0; // if not enabled
|
DN = 1'b0;
|
DN = 1'b0;
|
TT = 1'b0;
|
TT = 1'b0;
|
end
|
end
|
end
|
end
|
end // end this case
|
end // end this case
|
|
|
RetOnDelayTimer : begin
|
RetOnDelayTimer : begin
|
|
|
if (reset)
|
if (reset)
|
begin
|
begin
|
ACC = `tcAccLen'b0;
|
ACC = `tcAccLen'b0;
|
DN = 1'b0;
|
DN = 1'b0;
|
TT = 1'b0;
|
TT = 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if (en)
|
if (en)
|
begin
|
begin
|
if (ACC < preset)
|
if (ACC < preset)
|
begin
|
begin
|
ACC = ACC + 1'b1;
|
ACC = ACC + 1'b1;
|
DN = 1'b0;
|
DN = 1'b0;
|
TT = 1'b1;
|
TT = 1'b1;
|
end
|
end
|
else if (ACC >= preset)
|
else if (ACC >= preset)
|
begin
|
begin
|
ACC = ACC;
|
ACC = ACC;
|
DN = 1'b1;
|
DN = 1'b1;
|
|
|
|
|
|
|
|
|
TT = 1'b0;
|
TT = 1'b0;
|
end
|
end
|
end
|
end
|
else
|
else
|
begin
|
begin
|
ACC = ACC; // retain ACC
|
ACC = ACC; // retain ACC
|
DN = 1'b0;
|
DN = 1'b0;
|
TT = 1'b0;
|
TT = 1'b0;
|
end
|
end
|
end
|
end
|
end // end this case
|
end // end this case
|
|
|
|
|
default : begin
|
default : begin
|
if (!reset)
|
if (!reset)
|
$display(" Error in timer type ");
|
$display("\nError in timer type ");
|
end
|
end
|
|
|
endcase
|
endcase
|
|
|
end
|
end
|
|
|
|
|
endmodule
|
endmodule
|
|
|