|
// RTL for one channel of a typical timer
// Programmers' Model State
reg int_enable, int_pending;
reg [31:0] prescalar;
reg [31:0] reload;
// Programmer-invisible internal state
reg ovf'
reg [31:0] counter, prescale;
// Host write operations
always @(posedge clk) begin
if (hwen && addr==0) int_enable <= wdata[0];
if (hwen && addr==4) prescalar <= wdata;
if (hwen && addr==8) reload <= wdata;
// Write to addr==12 to clear interrupt
end
wire host_op = hwen && addr == 12;
// Host read operations
assign rdata =
(addr==0) ? {int_pending, int_enable}:
(addr==4) ? prescalar:
(addr==8) ? reload: 0;
// A timer counts system clock cycles.
// A counter would count transitions from external input.
always @(posedge clk) begin
ovf <= (prescale == prescalar);
prescale <= (ovf) ? 0: prescale+1;
if (ovf) counter <= counter -1;
if (counter == 0) begin
int_pending <= 1;
counter <= reload;
end
if (host_op) int_pending <= 0;
end
// Interrupt generation
assign interrupt = int_pending && int_enable;
|
Timer (illustrated in RTL) : counts pre-scaled system clock. Counter: counts external event pulses (e.g. car rev counter).
Four to eight, versatile, configurable counter/timers provided in one block (only one shown in RTL).
All registers also configured as bus target read/write resources.
Interrupt cleared by host programmed I/O to host_op.
Exercise: draw programmers' model diagram for the above RTL (probably done in lecture).
| 37: (C) 2008-18, DJ Greaves, University of Cambridge, Computer Laboratory. |