URL
https://opencores.org/ocsvn/mcs-4/mcs-4/trunk
Subversion Repositories mcs-4
[/] [mcs-4/] [trunk/] [rtl/] [verilog/] [i4004/] [instruction_pointer.v] - Rev 5
Go to most recent revision | Compare with Previous | Blame | View Log
`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
Go to most recent revision | Compare with Previous | Blame | View Log