OpenCores
URL https://opencores.org/ocsvn/mcs-4/mcs-4/trunk

Subversion Repositories mcs-4

[/] [mcs-4/] [trunk/] [rtl/] [verilog/] [common/] [clockgen.v] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 rrpollack
`timescale 1ns / 1ps
2
`default_nettype none
3
////////////////////////////////////////////////////////////////////////
4
//
5
// MCS-4 common clock generator sub-module
6
//
7
// This module implements a two-phase clock generator suitable
8
// for use with the MCS-4 emulation.
9
//
10
// This file is part of the MCS-4 project hosted at OpenCores:
11
//      http://www.opencores.org/cores/mcs-4/
12
//
13
// Copyright © 2012, 2021 by Reece Pollack <rrpollack@opencores.org>
14
//
15
// These materials are provided under the Creative Commons
16
// "Attribution-NonCommercial-ShareAlike" (CC BY-NC-SA) Public License.
17
// They are NOT "public domain", and are protected by copyright.
18
//
19
// This work based on materials provided by Intel Corporation and
20
// others under the same license. See the file doc/License for
21
// details of this license.
22
//
23
////////////////////////////////////////////////////////////////////////
24
 
25
module clockgen #(
26
    parameter SYSCLK_TCY    = 20,   // System clock cycle time in nanoseconds
27
    parameter EXT_CLK_PROP  = 0     // External clock propagation delay in sysclk cycles
28
    ) (
29
    input  wire sysclk,
30
    output reg  clk1,
31
    output reg  clk2,
32
    output reg  clk1_ext,
33
    output reg  clk2_ext
34
    );
35
 
36
    //
37
    // Instruction phase timing in nanoseconds
38
    //
39
    // These are chosen to be nicely divisible by the clock
40
    // period from any of these three systems while giving
41
    // timing that would be compatible with a real i4004:
42
    //   * 50ns (20 MHz)  -- P170-DH replacement board
43
    //   * 20ns (50 MHz)  -- Digilent Spartan-3e Starter board
44
    //   * 10ns (100 MHz) -- Digilent Atlys Spartan-6 board
45
    //
46
    localparam  TPW = 400;      // Clock high pulse width
47
    localparam  TD1 = 400;      // Delay from clk1 to clk2
48
    localparam  TD2 = 200;      // Delay from clk2 to clk1
49
 
50
    // MCS-4 instruction phase cycle time
51
    localparam  TCY = TD1 + TPW + TD2 + TPW;
52
 
53
    // Calculate counter maximum value and width
54
    localparam  CMAX    = (TCY / SYSCLK_TCY) - 1;
55
    localparam  W       = clog2(CMAX);
56
 
57
    //
58
    // Instruction phase timing in sysclk cycles
59
    //
60
    localparam  SYSCLK_TPW  = TPW / SYSCLK_TCY;
61
    localparam  SYSCLK_TD1  = TD1 / SYSCLK_TCY;
62
    localparam  SYSCLK_TD2  = TD2 / SYSCLK_TCY;
63
 
64
    // Divide the system clock to produce basic machine cycle
65
    localparam  [W-1:0] CLOCKDIV_MAX    = CMAX;
66
    reg         [W-1:0] clockdiv        = 1'd0;
67
    always @(posedge sysclk) begin
68
        clockdiv <= (clockdiv == CLOCKDIV_MAX) ? 1'd0 : (clockdiv + 1'd1);
69
    end
70
 
71
    // Set the timing of the internal 2-phase clocks
72
    localparam  [W-1:0] CLK1_START  = SYSCLK_TD2 - 1,
73
                        CLK1_END    = CLK1_START + SYSCLK_TPW,
74
                        CLK2_START  = CLK1_END   + SYSCLK_TD1,
75
                        CLK2_END    = CLK2_START + SYSCLK_TPW;
76
 
77
    always @(posedge sysclk) begin
78
        case (clockdiv)
79
            CLK1_START: clk1 <= 1'b1;
80
            CLK1_END:   clk1 <= 1'b0;
81
        endcase
82
    end
83
 
84
    always @(posedge sysclk) begin
85
        case (clockdiv)
86
            CLK2_START: clk2 <= 1'b1;
87
            CLK2_END:   clk2 <= 1'b0;
88
        endcase
89
    end
90
 
91
    //
92
    // Set the timing of the external 2-phase clocks
93
    //
94
    // It takes ~70ns for the clocks to propagate from the FPGA through the
95
    // clock driver chip to the reconstructed i4004 CPU circuitry. To match
96
    // the timings, this module also provides advanced clock outputs.
97
    //
98
    localparam  [W-1:0] CLK1_EXT_START  = CLK1_START - EXT_CLK_PROP,
99
                        CLK1_EXT_END    = CLK1_END   - EXT_CLK_PROP,
100
                        CLK2_EXT_START  = CLK2_START - EXT_CLK_PROP,
101
                        CLK2_EXT_END    = CLK2_END   - EXT_CLK_PROP;
102
 
103
    always @(posedge sysclk) begin
104
        case (clockdiv)
105
            CLK1_EXT_START: clk1_ext <= 1'b1;
106
            CLK1_EXT_END:   clk1_ext <= 1'b0;
107
        endcase
108
    end
109
 
110
    always @(posedge sysclk) begin
111
        case (clockdiv)
112
            CLK2_EXT_START: clk2_ext <= 1'b1;
113
            CLK2_EXT_END:   clk2_ext <= 1'b0;
114
        endcase
115
    end
116
 
117
`include "functions.vh"
118
 
119
endmodule

powered by: WebSVN 2.1.0

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