Root/lm32/logic/sakc/rtl/wb_timer/wb_timer.v

1//---------------------------------------------------------------------------
2//
3// Wishbone Timer
4//
5// Register Description:
6//
7// 0x00 TCR0
8// 0x04 COMPARE0
9// 0x08 COUNTER0
10// 0x0C TCR1
11// 0x10 COMPARE1
12// 0x14 COUNTER1
13//
14// TCRx:
15// +-------------------+-------+-------+-------+-------+
16// | 28'b0 | EN | AR | IRQEN | TRIG |
17// +-------------------+-------+-------+-------+-------+
18//
19// EN i (rw) if set to '1', COUNTERX counts upwards until it reaches
20// COMPAREX
21// AR (rw) AutoRecwstartload -- if COUNTER reaches COMPAREX, shall we
22// restart at 1, or disable this counter?
23// IRQEN (rw) Indicate interrupt condition when triggered?
24// TRIG (ro)
25//
26//---------------------------------------------------------------------------
27
28module wb_timer #(
29    parameter clk_freq = 50000000
30) (
31    input clk,
32    input reset,
33    // Wishbone interface
34    input wb_stb_i,
35    input wb_cyc_i,
36    output wb_ack_o,
37    input wb_we_i,
38    input [31:0] wb_adr_i,
39    input [3:0] wb_sel_i,
40    input [31:0] wb_dat_i,
41    output reg [31:0] wb_dat_o,
42    //
43    output [1:0] intr
44);
45
46//---------------------------------------------------------------------------
47//
48//---------------------------------------------------------------------------
49
50reg irqen0, irqen1;
51reg trig0, trig1;
52reg en0, en1;
53reg ar0, ar1;
54
55wire [31:0] tcr0 = { 28'b0, en0, ar0, irqen0, trig0 };
56wire [31:0] tcr1 = { 28'b0, en1, ar1, irqen1, trig1 };
57
58reg [31:0] counter0;
59reg [31:0] counter1;
60
61reg [31:0] compare0;
62reg [31:0] compare1;
63
64wire match0 = (counter0 == compare0);
65wire match1 = (counter1 == compare1);
66
67assign intr = { trig1, trig0 };
68
69reg ack;
70assign wb_ack_o = wb_stb_i & wb_cyc_i & ack;
71
72wire wb_rd = wb_stb_i & wb_cyc_i & ~wb_we_i;
73wire wb_wr = wb_stb_i & wb_cyc_i & wb_we_i;
74
75always @(posedge clk)
76begin
77    if (reset) begin
78        ack <= 0;
79        en0 <= 0;
80        en1 <= 0;
81        ar0 <= 0;
82        ar1 <= 0;
83        trig0 <= 0;
84        trig1 <= 0;
85        counter0 <= 0;
86        counter1 <= 0;
87        compare0 <= 32'hFFFFFFFF;
88        compare1 <= 32'hFFFFFFFF;
89    end else begin
90
91        // Handle counter 0
92        if ( en0 & ~match0) counter0 <= counter0 + 1;
93        if ( en0 & match0) trig0 <= 1;
94        if ( ar0 & match0) counter0 <= 1;
95        if (~ar0 & match0) en0 <= 0;
96
97        // Handle counter 1
98        if ( en1 & ~match1) counter1 <= counter1 + 1;
99        if ( en1 & match1) trig1 <= 1;
100        if ( ar1 & match1) counter1 <= 1;
101        if (~ar1 & match1) en1 <= 0;
102
103        // Handle WISHBONE access
104        ack <= 0;
105
106        if (wb_rd & ~ack) begin // read cycle
107            ack <= 1;
108
109            case (wb_adr_i[7:0])
110            'h00: wb_dat_o <= tcr0;
111            'h04: wb_dat_o <= compare0;
112            'h08: wb_dat_o <= counter0;
113            'h0c: wb_dat_o <= tcr1;
114            'h10: wb_dat_o <= compare1;
115            'h14: wb_dat_o <= counter1;
116            default: wb_dat_o <= 32'b0;
117            endcase
118        end else if (wb_wr & ~ack ) begin // write cycle
119            ack <= 1;
120
121            case (wb_adr_i[7:0])
122            'h00: begin
123                trig0 <= 0;
124                irqen0 <= wb_dat_i[1];
125                ar0 <= wb_dat_i[2];
126                en0 <= wb_dat_i[3];
127            end
128            'h04: compare0 <= wb_dat_i;
129            'h08: counter0 <= wb_dat_i;
130            'h0c: begin
131                trig1 <= 0;
132                irqen1 <= wb_dat_i[1];
133                ar1 <= wb_dat_i[2];
134                en1 <= wb_dat_i[3];
135            end
136            'h10: compare1 <= wb_dat_i;
137            'h14: counter1 <= wb_dat_i;
138            endcase
139        end
140    end
141end
142
143
144endmodule
145

Archive Download this file

Branches:
master



interactive