![]() |
// RTL for one channel of a simple timer //Programmer model reg int_enable, ovf, int_pending; reg [31:0] prescalar; reg [31:0] reload; //Internal state 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; //FIXED // Write to addr==12 to clear interrupt end // Host read operations assign rdata = (addr==0) ? {int_pending, int_enable}: (addr==4) ? prescalar: (addr==8) ? reload: 0; // FIXED // 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 wire host_op = hwen && addr == 12; // 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.