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

Subversion Repositories mcs-4

[/] [mcs-4/] [trunk/] [rtl/] [verilog/] [i4004/] [instruction_pointer.v] - Diff between revs 4 and 5

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 4 Rev 5
Line 1... Line 1...
 
`timescale 1ns / 1ps
 
`default_nettype none
 
////////////////////////////////////////////////////////////////////////
 
// 
 
// 4004 Instruction Pointer Array
 
// 
 
// This file is part of the MCS-4 project hosted at OpenCores:
 
//      http://www.opencores.org/cores/mcs-4/
 
// 
 
// Copyright © 2012, 2020 by Reece Pollack <rrpollack@opencores.org>
 
// 
 
// These materials are provided under the Creative Commons
 
// "Attribution-NonCommercial-ShareAlike" Public License. They
 
// are NOT "public domain" and are protected by copyright.
 
// 
 
// This work based on materials provided by Intel Corporation and
 
// others under the same license. See the file doc/License for
 
// details of this license.
 
//
 
////////////////////////////////////////////////////////////////////////
 
 
 
module instruction_pointer (
 
        input  wire                     sysclk,                                 // 50 MHz FPGA clock
 
 
 
        // Inputs from the Timing and I/O board
 
        input  wire                     clk1,
 
        input  wire                     clk2,
 
        input  wire                     a12,
 
        input  wire                     a22,
 
        input  wire                     a32,
 
        input  wire                     m12,
 
        input  wire                     m22,
 
        input  wire                     x12,
 
        input  wire                     x22,
 
        input  wire                     x32,
 
        input  wire                     poc,                                    // Power-On Clear (reset)
 
        input  wire                     m12_m22_clk1_m11_m12,   // M12+M22+CLK1~(M11+M12)
 
 
 
        // Common 4-bit data bus
 
        inout  wire     [3:0]    data,
 
 
 
        // Inputs from the Instruction Decode board
 
        input  wire                     jcn_isz,                                // JCN+ISZ
 
        input  wire                     jin_fin,                                // JIN+FIN
 
        input  wire                     jun_jms,                                // JUN+JMS
 
        input  wire                     cn_n,                                   // ~CN
 
        input  wire                     bbl,                                    // BBL
 
        input  wire                     jms,                                    // JMS
 
        input  wire                     sc,                                             // SC (Single Cycle)
 
        input  wire                     dc                                              // DC (Double Cycle, ~SC)
 
        );
 
 
 
        reg  [11:0]      dram_array [0:3];
 
        reg  [11:0]      dram_temp;
 
        wire  [3:0]      din_n;
 
 
 
        wire inh = (jin_fin & sc) | ((jun_jms | (jcn_isz & ~cn_n)) & dc);
 
 
 
        // Row Counter stuff
 
        wire [1:0]       addr_ptr;                               // Effective Address counter
 
        wire            addr_ptr_step;                  // CLK2(JMS&DC&M22+BBL(M22+X12+X22))
 
 
 
        assign addr_ptr_step = ~(~clk2 | ~(((m22 | x12 | x22) & bbl) |
 
                                                                           (m22 & dc & jms)));
 
        counter addr_ptr_0 (
 
                .sysclk(sysclk),
 
                .step_a(clk1),
 
                .step_b(addr_ptr_step),
 
                .q(addr_ptr[0])
 
        );
 
        counter addr_ptr_1 (
 
                .sysclk(sysclk),
 
                .step_a( addr_ptr[0]),
 
                .step_b(~addr_ptr[0]),
 
                .q(addr_ptr[1])
 
        );
 
 
 
        // Refresh counter stuff
 
        wire [1:0]       addr_rfsh;                              // Row Refresh counter
 
        wire            addr_rfsh_step;                 // (~INH)&X32&CLK2
 
 
 
        assign addr_rfsh_step = ~inh & x32 & clk2;
 
 
 
        counter addr_rfsh_0 (
 
                .sysclk(sysclk),
 
                .step_a(clk1),
 
                .step_b(addr_rfsh_step),
 
                .q(addr_rfsh[0])
 
        );
 
        counter addr_rfsh_1 (
 
                .sysclk(sysclk),
 
                .step_a( addr_rfsh[0]),
 
                .step_b(~addr_rfsh[0]),
 
                .q(addr_rfsh[1])
 
        );
 
 
 
        // Row selection mux
 
        reg  [1:0]       row;                                    // {N0409, N0420}
 
        always @(posedge sysclk) begin
 
                if (x12)
 
                        row <= addr_rfsh;
 
                if (x32)
 
                        row <= addr_ptr;
 
        end
 
 
 
 
 
        // Row Precharge/Read/Write stuff
 
        wire            precharge;                              // (~INH)(X11+X31)CLK1
 
        wire            row_read;                               // (~POC)CLK2(X12+X32)~INH
 
        wire            row_write;                              // ((~SC)(JIN+FIN))CLK1(M11+X21~INH)
 
 
 
        reg n0517;
 
        always @(posedge sysclk) begin
 
                if (clk2)
 
                        n0517 <= ~(m22 | x22);
 
        end
 
        assign precharge = ~(n0517 | inh | ~clk1);
 
 
 
        assign row_read = ~poc & clk2 & (x12 | x32) & ~inh;
 
 
 
        reg n0438;
 
        always @(posedge sysclk) begin
 
                if (clk2)
 
                        n0438 <= ~((x12 & ~inh) | a32);
 
        end
 
        assign row_write = ~(n0438 | (jin_fin & ~sc) | ~clk1);
 
 
 
 
 
        // Column Read selection stuff
 
        reg n0416;
 
        always @(posedge sysclk) begin
 
                if (clk2)
 
                        n0416 <= ~x32;
 
        end
 
        wire radb0 = ~(n0416 | clk2);
 
 
 
        reg n0384;
 
        always @(posedge sysclk) begin
 
                if (clk2)
 
                        n0384 <= ~a12;
 
        end
 
        wire radb1 = ~(n0384 | clk2);
 
 
 
        reg n0374;
 
        always @(posedge sysclk) begin
 
                if (clk2)
 
                        n0374 <= ~a22;
 
        end
 
        wire radb2 = ~(n0374 | clk2);
 
 
 
 
 
        // Column Write selection stuff
 
        wire n0322 = ~(sc | cn_n);
 
        wire wadb0 = ~(~clk2 | ~(a12 | (sc & jin_fin & x32) |
 
                                                (((jcn_isz & n0322) | (jun_jms & ~sc)) & m22)));
 
        wire wadb1 = ~(~clk2 | ~(a22 | (sc & jin_fin & x22) |
 
                                                (((jcn_isz & n0322) | (jun_jms & ~sc)) & m12)));
 
        wire wadb2 = ~(~clk2 | ~(a32 | (jun_jms & ~sc & x22)));
 
 
 
 
 
        // Manage the row data buffer
 
        always @(posedge sysclk) begin
 
                if (precharge)
 
                        dram_temp <= 12'b0;
 
 
 
                if (row_read)
 
                        dram_temp <= dram_array[row];
 
 
 
                if (wadb0)
 
                        dram_temp[ 3:0] <= ~din_n;
 
                if (wadb1)
 
                        dram_temp[ 7:4] <= ~din_n;
 
                if (wadb2)
 
                        dram_temp[11:8] <= ~din_n;
 
        end
 
 
 
        // Handle row writes
 
        always @(posedge sysclk) begin
 
                if (row_write)
 
                        dram_array[row] <= dram_temp;
 
        end
 
 
 
        // Manage the data output mux
 
        reg   [3:0]      dout;
 
        always @* begin
 
                (* PARALLEL_CASE *)
 
                case (1'b1)
 
                        radb0:          dout = dram_temp[ 3:0];
 
                        radb1:          dout = dram_temp[ 7:4];
 
                        radb2:          dout = dram_temp[11:8];
 
                        default:        dout = 4'bzzzz;
 
                endcase
 
        end
 
        assign data = dout;
 
 
 
        // Data In mux and incrementer
 
        reg [3:0] incr_in;
 
        always @(posedge sysclk) begin
 
                if (m12_m22_clk1_m11_m12)
 
                        incr_in <= data;
 
        end
 
 
 
        reg carry_out, carry_in;
 
        wire [4:0] incr_out = (a12 | ((a22 | a32) & carry_in)) ?
 
                        (incr_in + 4'b0001) : {1'b0, incr_in};
 
        always @(posedge sysclk) begin
 
                if (clk2)
 
                        carry_out <= incr_out[4];
 
                if (clk1)
 
                        carry_in <= carry_out;
 
        end
 
        assign din_n = ~incr_out[3:0];
 
 
 
endmodule
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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