OpenCores
URL https://opencores.org/ocsvn/ao486/ao486/trunk

Subversion Repositories ao486

[/] [ao486/] [trunk/] [rtl/] [soc/] [pit/] [pit.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright (c) 2014, Aleksander Osman
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * * Redistributions of source code must retain the above copyright notice, this
9
 *   list of conditions and the following disclaimer.
10
 *
11
 * * Redistributions in binary form must reproduce the above copyright notice,
12
 *   this list of conditions and the following disclaimer in the documentation
13
 *   and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
 
27
module pit(
28
    input               clk,
29
    input               rst_n,
30
 
31
    output              irq,
32
 
33
    //io slave 040h-043h
34
    input       [1:0]   io_address,
35
    input               io_read,
36
    output reg  [7:0]   io_readdata,
37
    input               io_write,
38
    input       [7:0]   io_writedata,
39
 
40
    //speaker port 61h
41
    input               speaker_61h_read,
42
    output      [7:0]   speaker_61h_readdata,
43
    input               speaker_61h_write,
44
    input       [7:0]   speaker_61h_writedata,
45
 
46
    //speaker output
47
    output reg          speaker_enable,
48
    output              speaker_out,
49
 
50
    //mgmt slave
51
    /*
52
    0.[7:0]: cycles in sysclock 1193181 Hz
53
    */
54
    input               mgmt_address,
55
    input               mgmt_write,
56
    input       [31:0]  mgmt_writedata
57
);
58
 
59
//------------------------------------------------------------------------------
60
 
61
reg io_read_last;
62
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) io_read_last <= 1'b0; else if(io_read_last) io_read_last <= 1'b0; else io_read_last <= io_read; end
63
wire io_read_valid = io_read && io_read_last == 1'b0;
64
 
65
//------------------------------------------------------------------------------ system clock
66
 
67
reg [7:0] cycles_in_1193181hz; //838.096ns
68
always @(posedge clk or negedge rst_n) begin
69
    if(rst_n == 1'b0)                               cycles_in_1193181hz <= 8'd25;
70
    else if(mgmt_write && mgmt_address == 1'b0)     cycles_in_1193181hz <= mgmt_writedata[7:0];
71
end
72
 
73
reg [7:0] system_counter;
74
always @(posedge clk or negedge rst_n) begin
75
    if(rst_n == 1'b0)                               system_counter <= 8'd0;
76
    else if(system_counter >= cycles_in_1193181hz)  system_counter <= 8'd0;
77
    else                                            system_counter <= system_counter + 8'd2;
78
end
79
 
80
reg system_clock;
81
always @(posedge clk or negedge rst_n) begin
82
    if(rst_n == 1'b0)                               system_clock <= 1'b0;
83
    else if(system_counter >= cycles_in_1193181hz)  system_clock <= ~(system_clock);
84
end
85
 
86
//------------------------------------------------------------------------------ read io
87
 
88
wire [7:0] io_readdata_next =
89
    (io_read_valid && io_address == 2'd0)?    counter_0_readdata :
90
    (io_read_valid && io_address == 2'd1)?    counter_1_readdata :
91
    (io_read_valid && io_address == 2'd2)?    counter_2_readdata :
92
                                              8'd0; //control address
93
 
94
always @(posedge clk or negedge rst_n) begin
95
    if(rst_n == 1'b0)   io_readdata <= 8'd0;
96
    else                io_readdata <= io_readdata_next;
97
end
98
 
99
//------------------------------------------------------------------------------ speaker
100
 
101
assign speaker_61h_readdata = { 2'b0, speaker_out, counter_1_toggle, 2'b0, speaker_enable, speaker_gate };
102
 
103
reg [5:0] counter_1_cnt;
104
always @(posedge clk or negedge rst_n) begin
105
    if(rst_n == 1'b0)                                                           counter_1_cnt <= 6'd0;
106
    else if(system_counter >= cycles_in_1193181hz && counter_1_cnt == 6'd35)    counter_1_cnt <= 6'd0;
107
    else if(system_counter >= cycles_in_1193181hz)                              counter_1_cnt <= counter_1_cnt + 6'd1;
108
end
109
 
110
reg counter_1_toggle;
111
always @(posedge clk or negedge rst_n) begin
112
    if(rst_n == 1'b0)                                                           counter_1_toggle <= 1'b0;
113
    else if(system_counter >= cycles_in_1193181hz && counter_1_cnt == 6'd35)    counter_1_toggle <= ~(counter_1_toggle);
114
end
115
 
116
 
117
reg speaker_gate;
118
always @(posedge clk or negedge rst_n) begin
119
    if(rst_n == 1'b0)           speaker_gate <= 1'b0;
120
    else if(speaker_61h_write)  speaker_gate <= speaker_61h_writedata[0];
121
end
122
 
123
always @(posedge clk or negedge rst_n) begin
124
    if(rst_n == 1'b0)           speaker_enable <= 1'b0;
125
    else if(speaker_61h_write)  speaker_enable <= speaker_61h_writedata[1];
126
end
127
 
128
//------------------------------------------------------------------------------
129
 
130
//------------------------------------------------------------------------------
131
 
132
wire [7:0] counter_0_readdata;
133
wire [7:0] counter_1_readdata;
134
wire [7:0] counter_2_readdata;
135
 
136
pit_counter pit_counter_0(
137
    .clk                (clk),
138
    .rst_n              (rst_n),
139
 
140
    .clock              (system_clock),     //input
141
    .gate               (1'b1),             //input
142
    .out                (irq),              //output
143
 
144
    .data_in            (io_writedata),                                                                                                                                         //input [7:0]
145
    .set_control_mode   (io_write && io_address == 2'd3 && io_writedata[7:6] == 2'b00 && io_writedata[5:4] != 2'b00),                                                           //input
146
    .latch_count        (io_write && io_address == 2'd3 && ((io_writedata[7:6] == 2'b00 && io_writedata[5:4] == 2'b00) || (io_writedata[7:5] == 3'b110 && io_writedata[1]))),   //input
147
    .latch_status       (io_write && io_address == 2'd3 && io_writedata[7:6] == 2'b11 && io_writedata[4] == 1'b0 && io_writedata[1]),                                           //input
148
    .write              (io_write && io_address == 2'd0),                                                                                                                       //input
149
    .read               (io_read_valid && io_address == 2'd0),                                                                                                                  //input
150
 
151
    .data_out           (counter_0_readdata)    //output [7:0]
152
);
153
 
154
pit_counter pit_counter_1(
155
    .clk                (clk),
156
    .rst_n              (rst_n),
157
 
158
    .clock              (system_clock),     //input
159
    .gate               (1'b1),             //input
160
    /* verilator lint_off PINNOCONNECT */
161
    .out                (),                 //output
162
    /* verilator lint_on PINNOCONNECT */
163
 
164
    .data_in            (io_writedata),                                                                                                                                         //input [7:0]
165
    .set_control_mode   (io_write && io_address == 2'd3 && io_writedata[7:6] == 2'b01 && io_writedata[5:4] != 2'b00),                                                           //input
166
    .latch_count        (io_write && io_address == 2'd3 && ((io_writedata[7:6] == 2'b01 && io_writedata[5:4] == 2'b00) || (io_writedata[7:5] == 3'b110 && io_writedata[2]))),   //input
167
    .latch_status       (io_write && io_address == 2'd3 && io_writedata[7:6] == 2'b11 && io_writedata[4] == 1'b0 && io_writedata[2]),                                           //input
168
    .write              (io_write && io_address == 2'd1),                                                                                                                       //input
169
    .read               (io_read_valid && io_address == 2'd1),                                                                                                                  //input
170
 
171
    .data_out           (counter_1_readdata)    //output [7:0]
172
);
173
 
174
pit_counter pit_counter_2(
175
    .clk                (clk),
176
    .rst_n              (rst_n),
177
 
178
    .clock              (system_clock),     //input
179
    .gate               (speaker_gate),     //input
180
    .out                (speaker_out),      //output
181
 
182
    .data_in            (io_writedata),                                                                                                                                         //input [7:0]
183
    .set_control_mode   (io_write && io_address == 2'd3 && io_writedata[7:6] == 2'b10 && io_writedata[5:4] != 2'b00),                                                           //input
184
    .latch_count        (io_write && io_address == 2'd3 && ((io_writedata[7:6] == 2'b10 && io_writedata[5:4] == 2'b00) || (io_writedata[7:5] == 3'b110 && io_writedata[3]))),   //input
185
    .latch_status       (io_write && io_address == 2'd3 && io_writedata[7:6] == 2'b11 && io_writedata[4] == 1'b0 && io_writedata[3]),                                           //input
186
    .write              (io_write && io_address == 2'd2),                                                                                                                       //input
187
    .read               (io_read_valid && io_address == 2'd2),                                                                                                                  //input
188
 
189
    .data_out           (counter_2_readdata)    //output [7:0]
190
);
191
 
192
//------------------------------------------------------------------------------
193
 
194
// synthesis translate_off
195
wire _unused_ok = &{ 1'b0, speaker_61h_read, speaker_61h_writedata[7:2], mgmt_writedata[31:8], 1'b0 };
196
// synthesis translate_on
197
 
198
//------------------------------------------------------------------------------
199
 
200
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.