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

Subversion Repositories s80186

[/] [s80186/] [trunk/] [fpga/] [timer/] [Timer.sv] - Rev 2

Compare with Previous | Blame | View Log

// Copyright Jamie Iles, 2017
//
// This file is part of s80x86.
//
// s80x86 is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// s80x86 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with s80x86.  If not, see <http://www.gnu.org/licenses/>.

module Timer(input logic clk,
             input logic reset,
             input logic pit_clk,
             input logic cs,
             input logic [1:1] data_m_addr,
             input logic [15:0] data_m_data_in,
             output logic [15:0] data_m_data_out,
             input logic [1:0] data_m_bytesel,
             input logic data_m_wr_en,
             input logic data_m_access,
             output logic data_m_ack,
             output logic intr);

wire pit_clk_sync;
wire pit_clk_posedge = pit_clk_sync & ~last_pit_clk;
wire access_data = cs & data_m_access & ~data_m_addr[1] & data_m_bytesel[0];
wire access_ctrl = cs & data_m_access & data_m_addr[1] & data_m_bytesel[1];
wire [7:0] ctrl_wr_val = data_m_data_in[15:8];
wire [1:0] channel = ctrl_wr_val[7:6];

reg last_pit_clk;

reg [15:0] count, reload, latched_count;
reg [1:0] rw;
reg [2:0] mode;
reg [1:0] latched;
reg access_low;
reg reloaded;

BitSync PITSync(.clk(clk),
                .d(pit_clk),
                .q(pit_clk_sync));

always_ff @(posedge clk)
    last_pit_clk <= pit_clk_sync;

always_ff @(posedge clk)
    if (access_data && !data_m_wr_en) begin
        if (|latched) begin
            data_m_data_out <= {8'b0, latched_count[7:0]};
        end else
            data_m_data_out <= {8'b0, rw[0] ? count[7:0] : count[15:8]};
    end else begin
        data_m_data_out <= 16'b0;
    end

always_ff @(posedge reset or posedge clk) begin
    if (reset) begin
        {rw, mode, access_low} <= 6'b0;
        latched_count <= 16'b0;
        latched <= 2'b00;
    end else if (access_ctrl && data_m_wr_en && channel == 2'b00) begin
        if (ctrl_wr_val[5:4] == 2'b00 && ~|latched) begin
            latched <= 2'b11;
            latched_count <= count;
        end else begin
            mode <= ctrl_wr_val[3:1];
            access_low <= ctrl_wr_val[4];
            rw <= ctrl_wr_val[5:4];
        end
    end else if (access_data && data_m_wr_en && rw == 2'b11)
        access_low <= ~access_low;
    else if (access_data && !data_m_wr_en) begin
        latched <= {1'b0, latched[1]};
        latched_count <= {8'b0, latched_count[15:8]};
    end
end

always_ff @(posedge reset or posedge clk) begin
    if (reset) begin
        reload <= 16'b0;
        reloaded <= 1'b0;
    end else begin
        reloaded <= 1'b0;

        if (access_data && data_m_wr_en) begin
            if (access_low)
                reload[7:0] <= data_m_data_in[7:0];
            else begin
                reload[15:8] <= data_m_data_in[7:0];
                reloaded <= 1'b1;
            end
        end
    end
end

always_ff @(posedge reset or posedge clk) begin
    if (reset) begin
        count <= 16'b0;
        intr <= 1'b0;
    end else begin
        if (reloaded)
            count <= reload - 1'b1;
        else if (pit_clk_posedge && mode[1:0] == 2'b10) begin
            count <= (count == 16'b0 ? reload : count) - 1'b1;
            if (count == 16'b1)
                intr <= 1'b0;
            else
                intr <= 1'b1;
        end
    end
end

always_ff @(posedge clk)
    data_m_ack <= cs & data_m_access;

endmodule

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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