-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmytimer.v
154 lines (131 loc) · 3.09 KB
/
mytimer.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// timer.v
module timer(
pclk,
nreset,
bus_write_en,
bus_read_en,
bus_addr,
bus_write_data, //data_in
bus_read_data //data_out
);
input pclk, nreset, bus_write_en, bus_read_en;
input [7:0] bus_addr;
input [31:0] bus_write_data;
output reg [31:0] bus_read_data;
reg [31:0] overflowReg;
reg [31:0] counterReg;
reg [31:0] controlReg;
reg [31:0] nextCounter;
reg overflowReset; // Resets counterReg when new overflow value is written
wire timerEn; // Timer Enable
//Control Bits
assign timerEn = controlReg[0];
always@(posedge pclk)
if(~nreset)
begin
overflowReset <= 1'b0;
controlReg <= 32'h00000000;
overflowReg <= 32'h00000000;
end
else begin
if(bus_write_en) begin : WRITE
case(bus_addr[3:2])
2'b00: // Timer Overflow Register
begin
overflowReg <= bus_write_data;
overflowReset <= 1'b1;
end
2'b01: // Timer Value, Read Only
begin
overflowReset <= 1'b0;
end
2'b10: // Timer Control
begin
controlReg <= bus_write_data;
overflowReset <= 1'b0;
end
2'b11: // Spare
begin
overflowReset <= 1'b0;
end
endcase
end
else if(bus_read_en) begin : READ
case(bus_addr[3:2])
2'b00: // Timer Overflow register
begin
bus_read_data <= overflowReg;
end
2'b01: // Timer Value, Read Only
begin
bus_read_data <= counterReg;
end
2'b10: // Timer Control
begin
bus_read_data <= controlReg;
end
2'b11: // Spare
begin
end
endcase
end
else
overflowReset <= 1'b0;
end
assign timerEn = controlReg[0];
always@*
nextCounter <= counterReg + 1;
always@(posedge pclk)
if(~nreset)
begin
counterReg <= 32'h00000000;
end
else begin
if(overflowReset)
begin
counterReg <= 32'h00000000;
end
else if(timerEn)
begin
if(counterReg == overflowReg)
counterReg <= 32'h00000000;
else
counterReg <= nextCounter;
end
end
endmodule
// timerWrapper.v
module timerWrapper(// APB Bus Interface
PCLK,
PENABLE,
PSEL,
PRESETN,
PWRITE,
PREADY,
PSLVERR,
PADDR,
PWDATA,
PRDATA,
// Test Interface
TPS);
// APB Bus Interface
input PCLK,PENABLE, PSEL, PRESETN, PWRITE;
input [31:0] PWDATA;
input [7:0] PADDR;
output [31:0] PRDATA;
output PREADY, PSLVERR;
// Test Interface
output [4:0] TPS; // Use for your debugging
assign BUS_WRITE_EN = (PENABLE && PWRITE && PSEL);
assign BUS_READ_EN = (!PWRITE && PSEL); //Data is ready during first cycle to make it availble on the bus when PENABLE is asserted
assign PREADY = 1'b1;
assign PSLVERR = 1'b0;
timer timer_0( .pclk(PCLK),
.nreset(PRESETN),
.bus_write_en(BUS_WRITE_EN),
.bus_read_en(BUS_READ_EN),
.bus_addr(PADDR),
.bus_write_data(PWDATA),
.bus_read_data(PRDATA)
);
endmodule