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

Subversion Repositories mcs-4

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 4 to Rev 5
    Reverse comparison

Rev 4 → Rev 5

/mcs-4/trunk/rtl/verilog/common/counter.v
0,0 → 1,35
`timescale 1ns / 1ps
`default_nettype none
////////////////////////////////////////////////////////////////////////
//
// 4004 Counter sub-module
//
// This file is part of the MCS-4 project hosted at OpenCores:
// http://www.opencores.org/cores/mcs-4/
//
 
//
// 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 counter(
input wire sysclk,
input wire step_a,
input wire step_b,
output reg q = 1'b0
);
 
reg q_n = 1'b1;
always @(posedge sysclk) begin
if (step_a) q <= ~q_n;
if (step_b) q_n <= q;
end
 
endmodule
/mcs-4/trunk/rtl/verilog/i4004/alu.v
0,0 → 1,241
`timescale 1ns / 1ps
`default_nettype none
////////////////////////////////////////////////////////////////////////
//
// 4004 Arithmetic Logic Unit
//
// This file is part of the MCS-4 project hosted at OpenCores:
// http://www.opencores.org/cores/mcs-4/
//
 
//
// 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 alu(
input wire sysclk,
// Inputs from the Timing and I/O board
input wire a12,
input wire m12,
input wire x12,
input wire poc,
// Common 4-bit data bus
inout wire [3:0] data,
 
// Outputs to the Instruction Decode board
output wire acc_0,
output wire add_0,
output reg cy_1,
 
// Inputs from the Instruction Decode board
input wire cma,
input wire write_acc_1,
input wire write_carry_2,
input wire read_acc_3,
input wire add_group_4,
input wire inc_group_5,
input wire sub_group_6,
input wire ior,
input wire iow,
input wire ral,
input wire rar,
input wire ope_n,
input wire daa,
input wire dcl,
input wire inc_isz,
input wire kbp,
input wire o_ib,
input wire tcs,
input wire xch,
input wire n0342,
input wire x21_clk2,
input wire x31_clk2,
input wire com_n,
// Outputs to external pins
output wire cmram0,
output wire cmram1,
output wire cmram2,
output wire cmram3,
output wire cmrom
);
 
reg [3:0] acc;
reg cy;
 
// Decode logic
wire n0854 = ~(~x12);
wire n0351 = ~(x21_clk2 | ~dcl);
wire n0415 = ~(x21_clk2 | ope_n);
wire add_ib = ~(x31_clk2 | ~inc_isz);
wire cy_ib = ~(x31_clk2 | ~iow);
wire acb_ib = ~((x31_clk2 | ~xch) & (x21_clk2 | ~iow));
wire n0477 = ~((~x31_clk2 & ~ior) | (a12 & ior));
wire adc_cy = ~(write_carry_2 | n0477);
wire add_acc = ~(write_acc_1 | n0477);
wire adsr = ~(x31_clk2 | ~rar);
wire adsl = ~(x31_clk2 | ~ral);
wire acc_adac = ~(~cma | n0342);
wire acc_ada = ~(read_acc_3 | n0342);
wire cy_ada = ~(add_group_4 | n0342);
wire cy_adac = ~(sub_group_6 | n0342);
 
// Latch the incoming data bus
reg [3:0] tmp; // It's the name used in simulator!
always @(posedge sysclk) begin
if (~n0342)
tmp <= data;
if (m12)
tmp <= 4'b1111;
end
// Invert some of the incoming data
reg n0893, n0891, n0889, n0887; // D3, D2, D1, D0
always @(posedge sysclk) begin
if (sub_group_6) begin
n0887 <= tmp[0];
n0889 <= ~tmp[1];
n0891 <= tmp[2];
n0893 <= ~tmp[3];
end
if (~(sub_group_6 | m12)) begin
n0887 <= ~tmp[0];
n0889 <= tmp[1];
n0891 <= ~tmp[2];
n0893 <= tmp[3];
end
end
 
// Feedback from Accumulator
reg n0873, n0872, n0871, n0870;
always @(posedge sysclk) begin
if (acc_ada)
{n0873, n0872, n0871, n0870} <= acc ^ 4'b1010;
if (acc_adac)
{n0873, n0872, n0871, n0870} <= acc ^ 4'b0101;
if (m12)
{n0873, n0872, n0871, n0870} <= 4'b1010;
end
 
// Carry generator
wire n0546 = ~(inc_group_5 | n0342);
reg n0550;
always @(posedge sysclk) begin
if (m12) n0550 <= 1'b0;
if (n0546) n0550 <= 1'b1;
if (cy_adac) n0550 <= ~cy;
if (cy_ada) n0550 <= cy;
end
wire n0911 = ~(n0550 ? (n0887 | n0870) : (n0887 & n0870));
wire n0553 = n0911;
wire n0912 = ~(n0553 ? (n0889 | n0871) : (n0889 & n0871));
wire n0556 = n0912;
wire n0913 = ~(n0556 ? (n0891 | n0872) : (n0891 & n0872));
wire n0559 = n0913;
wire n0914 = ~(n0559 ? (n0893 | n0873) : (n0893 & n0873));
wire n0861 = n0914;
 
// Adder
wire n0878 = ~((n0887 & n0550 & n0870) | (n0553 & (n0887 | n0870 | n0550)));
wire n0875 = ~((n0889 & n0553 & n0871) | (n0556 & (n0889 | n0871 | n0553)));
wire n0879 = ~((n0891 & n0556 & n0872) | (n0559 & (n0891 | n0872 | n0556)));
wire n0877 = ~((n0893 & n0559 & n0873) | (n0861 & (n0893 | n0873 | n0559)));
wire n0846 = ~n0878;
wire n0847 = n0875;
wire n0848 = ~n0879;
wire n0514 = n0877;
 
// Shifter / Accumulator and Carry
reg [3:0] acc_out; // {n0356, n0348, n0347, n0346}
wire n0803 = ~((acc_out[3] & (acc_out[2] | acc_out[1])) | cy_1);
wire n0403 = ~(~daa | n0803);
wire [3:0] acc_in = {n0514, n0848, n0847, n0846};
always @(posedge sysclk) begin
if (adsr)
{acc, cy} <= {cy_1, acc_in};
if (add_acc)
acc <= acc_in;
if (adsl)
{cy, acc} <= {acc_in, cy_1};
if (adc_cy)
cy <= n0861;
if (n0403 & n0415)
cy <= 1'b1;
// Dynamic refresh would occur during M12
end
// Accumulator output latch
always @(posedge sysclk) begin
if (n0854) begin
cy_1 <= cy;
acc_out <= acc;
end
end
assign acc_0 = ~|acc_out;
assign add_0 = ~|acc_in;
 
// Keyboard Process logic
wire n0378 = ~((daa & n0803) | o_ib);
wire n0345 = kbp & (acc_out == 4'b1000);
wire n0354 = kbp & (acc_out == 4'b0100);
wire n0363 = kbp & (acc_out == 4'b0010);
wire n0370 = kbp & (acc_out == 4'b0001);
wire n0377 = (kbp & (acc_out == 4'b0000)) | ~n0378;
wire n0358 = ~(n0345 | n0354 | n0363 | n0370 | n0377 | n0403);
wire n0366 = ~( n0354 | n0363 | n0370 | n0377 | tcs );
wire n0359 = ~(n0345 | n0370 | n0377 | tcs );
wire n0357 = ~(n0345 | n0363 | n0377 | n0403);
 
// Data output mux
reg [3:0] dout;
always @(*) begin
dout = 4'bzzzz;
if (acb_ib)
dout = acc_out;
if (add_ib)
dout = acc_in;
if (cy_ib)
dout = {3'bxxx, cy_1};
if (n0415)
dout = {n0358, n0366, n0359, n0357};
end
assign data = dout;
// Generate CMROM / CMRAMn
// This may get moved to the Timing & I/O board
// Inputs: {n0355, n0364, n0371}, n0351, poc, com_n
wire n0355 = ~acc_out[2];
wire n0364 = ~acc_out[1];
wire n0371 = ~acc_out[0];
reg n0749, n0750, n0751;
always @(posedge sysclk) begin
if (poc) begin
n0749 <= 1'b1;
n0750 <= 1'b1;
n0751 <= 1'b1;
end
else begin
if (n0351) begin
n0749 <= n0355;
n0750 <= n0364;
n0751 <= n0371;
end
end
end
 
assign cmram3 = ~(com_n | n0749);
assign cmram2 = ~(com_n | n0750);
assign cmram1 = ~(com_n | n0751);
assign cmram0 = ~(com_n | ~n0749 | ~n0750 | ~n0751);
assign cmrom = ~(com_n | poc);
endmodule
/mcs-4/trunk/rtl/verilog/i4004/i4004.v
0,0 → 1,289
`timescale 1ns / 1ps
`default_nettype none
////////////////////////////////////////////////////////////////////////
//
// 4004 CPU Integration Module
//
// This file is part of the MCS-4 project hosted at OpenCores:
// http://www.opencores.org/cores/mcs-4/
//
 
//
// 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 i4004(
input wire sysclk,
input wire clk1_pad,
input wire clk2_pad,
input wire poc_pad,
input wire test_pad,
inout wire [3:0] data_pad,
output wire cmrom_pad,
output wire cmram0_pad,
output wire cmram1_pad,
output wire cmram2_pad,
output wire cmram3_pad,
output wire sync_pad
);
 
// Common BiDir data bus
wire [3:0] data;
 
// Timing and I/O Board Outputs
wire clk1;
wire clk2;
wire a12;
wire a22;
wire a32;
wire m12;
wire m22;
wire x12;
wire x22;
wire x32;
wire gate;
wire poc; // Clean POC_PAD
wire n0432; // Clean TEST_PAD
 
// Outputs from the Instruction Decode board
wire jcn_isz;
wire jin_fin;
wire jun_jms;
wire cn_n;
wire bbl;
wire jms;
wire sc;
wire dc;
wire n0636;
wire sc_m22_clk2;
wire fin_fim_src_jin;
wire inc_isz_add_sub_xch_ld;
wire inc_isz_xch;
wire opa0_n;
wire cma;
wire write_acc_1;
wire write_carry_2;
wire read_acc_3;
wire add_group_4;
wire inc_group_5;
wire sub_group_6;
wire ior;
wire iow;
wire ral;
wire rar;
wire ope_n;
wire daa;
wire dcl;
wire inc_isz;
wire kbp;
wire o_ib;
wire tcs;
wire xch;
wire n0342;
wire x21_clk2;
wire x31_clk2;
wire com_n;
 
// Outputs from the ALU board
wire acc_0;
wire add_0;
wire cy_1;
wire cmram0;
wire cmram1;
wire cmram2;
wire cmram3;
wire cmrom;
 
// Instantiate the Timing and I/O board
timing_io tio_board (
.sysclk(sysclk),
.clk1_pad(clk1_pad),
.clk2_pad(clk2_pad),
.poc_pad(poc_pad),
.ior(ior),
.clk1(clk1),
.clk2(clk2),
.a12(a12),
.a22(a22),
.a32(a32),
.m12(m12),
.m22(m22),
.x12(x12),
.x22(x22),
.x32(x32),
.gate(gate),
.poc(poc),
.data(data),
.data_pad(data_pad),
.test_pad(test_pad),
.n0432(n0432),
.sync_pad(sync_pad),
.cmrom(cmrom),
.cmrom_pad(cmrom_pad),
.cmram0(cmram0),
.cmram0_pad(cmram0_pad),
.cmram1(cmram1),
.cmram1_pad(cmram1_pad),
.cmram2(cmram2),
.cmram2_pad(cmram2_pad),
.cmram3(cmram3),
.cmram3_pad(cmram3_pad)
);
 
// Instantiate the Instruction Decode board
instruction_decode id_board (
.sysclk(sysclk),
.clk1(clk1),
.clk2(clk2),
.a22(a22),
.m12(m12),
.m22(m22),
.x12(x12),
.x22(x22),
.x32(x32),
.poc(poc),
.n0432(n0432),
.data(data),
.jcn_isz(jcn_isz),
.jin_fin(jin_fin),
.jun_jms(jun_jms),
.cn_n(cn_n),
.bbl(bbl),
.jms(jms),
.sc(sc),
.dc(dc),
.n0636(n0636),
.sc_m22_clk2(sc_m22_clk2),
.fin_fim_src_jin(fin_fim_src_jin),
.inc_isz_add_sub_xch_ld(inc_isz_add_sub_xch_ld),
.inc_isz_xch(inc_isz_xch),
.opa0_n(opa0_n),
.acc_0(acc_0),
.add_0(add_0),
.cy_1(cy_1),
.cma(cma),
.write_acc_1(write_acc_1),
.write_carry_2(write_carry_2),
.read_acc_3(read_acc_3),
.add_group_4(add_group_4),
.inc_group_5(inc_group_5),
.sub_group_6(sub_group_6),
.ior(ior),
.iow(iow),
.ral(ral),
.rar(rar),
.ope_n(ope_n),
.daa(daa),
.dcl(dcl),
.inc_isz(inc_isz),
.kbp(kbp),
.o_ib(o_ib),
.tcs(tcs),
.xch(xch),
.n0342(n0342),
.x21_clk2(x21_clk2),
.x31_clk2(x31_clk2),
.com_n(com_n)
);
 
// Instantiate the ALU board
alu alu_board (
.sysclk(sysclk),
.a12(a12),
.m12(m12),
.x12(x12),
.poc(poc),
.data(data),
.acc_0(acc_0),
.add_0(add_0),
.cy_1(cy_1),
.cma(cma),
.write_acc_1(write_acc_1),
.write_carry_2(write_carry_2),
.read_acc_3(read_acc_3),
.add_group_4(add_group_4),
.inc_group_5(inc_group_5),
.sub_group_6(sub_group_6),
.ior(ior),
.iow(iow),
.ral(ral),
.rar(rar),
.ope_n(ope_n),
.daa(daa),
.dcl(dcl),
.inc_isz(inc_isz),
.kbp(kbp),
.o_ib(o_ib),
.tcs(tcs),
.xch(xch),
.n0342(n0342),
.x21_clk2(x21_clk2),
.x31_clk2(x31_clk2),
.com_n(com_n),
.cmram0(cmram0),
.cmram1(cmram1),
.cmram2(cmram2),
.cmram3(cmram3),
.cmrom(cmrom)
);
 
// Instantiate the Instruction Pointer board
instruction_pointer ip_board (
.sysclk(sysclk),
.clk1(clk1),
.clk2(clk2),
.a12(a12),
.a22(a22),
.a32(a32),
.m12(m12),
.m22(m22),
.x12(x12),
.x22(x22),
.x32(x32),
.poc(poc),
.m12_m22_clk1_m11_m12(gate),
.data(data),
.jcn_isz(jcn_isz),
.jin_fin(jin_fin),
.jun_jms(jun_jms),
.cn_n(cn_n),
.bbl(bbl),
.jms(jms),
.sc(sc),
.dc(dc)
);
 
// Instantiate the Scratchpad board
scratchpad sp_board (
.sysclk(sysclk),
.clk1(clk1),
.clk2(clk2),
.a12(a12),
.a22(a22),
.a32(a32),
.m12(m12),
.m22(m22),
.x12(x12),
.x22(x22),
.x32(x32),
.poc(poc),
.m12_m22_clk1_m11_m12(gate),
.data(data),
.n0636(n0636),
.sc_m22_clk2(sc_m22_clk2),
.fin_fim_src_jin(fin_fim_src_jin),
.inc_isz_add_sub_xch_ld(inc_isz_add_sub_xch_ld),
.inc_isz_xch(inc_isz_xch),
.opa0_n(opa0_n),
.sc(sc),
.dc(dc)
);
 
endmodule
/mcs-4/trunk/rtl/verilog/i4004/instruction_decode.v
0,0 → 1,258
`timescale 1ns / 1ps
`default_nettype none
////////////////////////////////////////////////////////////////////////
//
// 4004 Instruction Decoder
//
// This file is part of the MCS-4 project hosted at OpenCores:
// http://www.opencores.org/cores/mcs-4/
//
 
//
// 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_decode(
input wire sysclk, // 50 MHz FPGA clock
// Inputs from the Timing and I/O board
input wire clk1,
input wire clk2,
input wire a22,
input wire m12,
input wire m22,
input wire x12,
input wire x22,
input wire x32,
input wire poc, // Power-On Clear (reset)
input wire n0432, // Conditioned TEST_PAD
 
// Common 4-bit data bus
inout wire [3:0] data,
 
// These drive the Instruction Pointer (IP) board
output wire jcn_isz, // JCN+ISZ
output wire jin_fin, // JIN+FIN
output wire jun_jms, // JUN+JMS
output wire cn_n, // ~CN
output wire bbl, // BBL
output wire jms, // JMS
// Outputs to both the IP and SP boards
output wire sc, // SC (Single Cycle)
output wire dc, // DC (Double Cycle, ~SC)
 
// Outputs to the Scratch Pad (SP) board
output wire n0636, // JIN+FIN
output wire sc_m22_clk2, // SC&M22&CLK2
output wire fin_fim_src_jin, // FIN+FIM+SRC+JIN
output wire inc_isz_add_sub_xch_ld, // INC+ISZ+ADD+SUB+XCH+LD
output wire inc_isz_xch, // INC+ISZ+XCH
output wire opa0_n, // ~OPA.0
 
// Inputs from the ALU board (condition bits)
input wire acc_0, // ACC_0
input wire add_0, // ADD_0
input wire cy_1, // CY_1
 
// Outputs to the Arithmetic Logic Unit (ALU) board
output wire cma,
output wire write_acc_1,
output wire write_carry_2,
output wire read_acc_3,
output wire add_group_4,
output wire inc_group_5,
output wire sub_group_6,
output wire ior,
output wire iow,
output wire ral,
output wire rar,
output wire ope_n,
output wire daa,
output wire dcl,
output wire inc_isz,
output wire kbp,
output wire o_ib,
output wire tcs,
output wire xch,
output wire n0342,
output wire x21_clk2,
output wire x31_clk2,
output wire com_n
);
wire sc_m12_clk2 = sc & m12 & clk2;
assign sc_m22_clk2 = sc & m22 & clk2;
 
// Latch the first 4 bits of the opcode
reg [3:0] opr = 4'b0000;
always @(posedge sysclk) begin
if (sc_m12_clk2)
opr <= data;
end
// Latch the second 4 bits of the opcode
reg [3:0] opa = 4'b0000;
always @(posedge sysclk) begin
if (sc_m22_clk2)
opa <= data;
end
assign opa0_n = ~opa[0];
// Full OPR Decoding
wire nop = (opr == 4'b0000);
wire jcn = (opr == 4'b0001);
wire fim_src = (opr == 4'b0010);
assign jin_fin = (opr == 4'b0011);
wire jun = (opr == 4'b0100);
assign jms = (opr == 4'b0101);
wire inc = (opr == 4'b0110);
wire isz = (opr == 4'b0111);
wire add = (opr == 4'b1000);
wire sub = (opr == 4'b1001);
wire ld = (opr == 4'b1010);
assign xch = (opr == 4'b1011);
assign bbl = (opr == 4'b1100);
wire ldm = (opr == 4'b1101);
wire io = (opr == 4'b1110);
wire ope = (opr == 4'b1111);
assign ope_n = ~ope;
assign n0636 = jin_fin;
assign jcn_isz = jcn | isz;
assign jun_jms = jun | jms;
wire ldm_bbl = ldm | bbl;
assign inc_isz = (inc | isz) & sc;
assign inc_isz_xch = inc | isz | xch;
assign inc_isz_add_sub_xch_ld = inc | isz | add | sub | xch | ld;
assign fin_fim_src_jin = fim_src | jin_fin;
// OPE: OPA Decoding
assign o_ib = ope & (opa[3] == 1'b0);
wire clb = ope & (opa == 4'b0000);
wire clc = ope & (opa == 4'b0001);
wire iac = ope & (opa == 4'b0010);
wire cmc = ope & (opa == 4'b0011);
assign cma = ope & (opa == 4'b0100);
assign ral = ope & (opa == 4'b0101);
assign rar = ope & (opa == 4'b0110);
wire tcc = ope & (opa == 4'b0111);
wire dac = ope & (opa == 4'b1000);
assign tcs = ope & (opa == 4'b1001);
wire stc = ope & (opa == 4'b1010);
assign daa = ope & (opa == 4'b1011);
assign kbp = ope & (opa == 4'b1100);
assign dcl = ope & (opa == 4'b1101);
 
// IO: OPA Decoding
assign iow = io & (opa[3] == 1'b0);
assign ior = io & (opa[3] == 1'b1);
wire adm = io & (opa == 4'b1011);
wire sbm = io & (opa == 4'b1000);
 
wire fin_fim = fin_fim_src_jin & ~opa[0];
wire src = fim_src & opa[0];
assign write_acc_1 = ~(kbp | tcs | daa | xch | poc | cma | tcc | dac | iac |
clb | ior | ld | sub | add | ldm_bbl);
assign write_carry_2 = ~(tcs | poc | tcc | stc | cmc | dac | iac |
clc | clb | sbm | adm | sub | add);
assign read_acc_3 = ~(daa | rar | ral | dac | iac | sbm | adm | sub | add);
assign add_group_4 = ~(tcs | tcc | adm | add);
assign inc_group_5 = ~(inc_isz | stc | iac);
assign sub_group_6 = ~(cmc | sbm | sub | m12);
 
// The Condition Flip-Flop
reg n0397;
wire n0486 = ~((opa[2] & acc_0) | (opa[1] & cy_1) | (opa[0] & n0432));
wire n0419 = ~((add_0 | ~isz) & (~jcn | ((n0486 | opa[3]) & (~n0486 | ~opa[3]))));
wire n0413 = ~((sc & n0419 & x32) | (~x32 & n0397));
reg n0405;
always @(posedge sysclk) begin
if (clk2)
n0405 <= n0413;
end
always @(posedge sysclk) begin
if (clk1)
n0397 <= ~n0405;
end
assign cn_n = ~n0397;
 
// The Single-Cycle Flip-Flop
reg n0343 = 1'b0;
wire n0368 = ~((sc & (fin_fim | jcn_isz | jun_jms) & x32) | (n0343 & ~x32));
reg n0362 = 1'b1;
always @(posedge sysclk) begin
if (clk2)
n0362 <= n0368;
if (clk1)
n0343 <= ~n0362;
end
assign sc = ~n0343;
assign dc = ~sc;
 
// Generate ~(X21&~CLK2)
reg n0360;
always @(posedge sysclk) begin
if (clk2)
n0360 <= ~x12;
end
wire n0337 = ~(n0360 | clk2);
assign x21_clk2 = ~n0337;
 
// Generate ~(X31&~CLK2)
reg n0380;
always @(posedge sysclk) begin
if (clk2)
n0380 <= ~x22;
end
wire n0375 = ~(n0380 | clk2);
assign x31_clk2 = ~n0375;
// Generate ~COM
wire n0329 = io;
 
reg n0414, n0797;
always @(posedge sysclk) begin
if (clk2)
n0414 <= a22;
else
n0797 <= n0414;
end
 
reg n0433, n0801;
always @(posedge sysclk) begin
if (clk2)
n0433 <= m12;
else
n0801 <= n0433;
end
reg n0425, n0805;
always @(posedge sysclk) begin
if (clk2)
n0425 <= x12;
else
n0805 <= n0425;
end
 
wire n0782 = ~((n0801 & n0329) | (src & n0805) | n0797);
assign com_n = n0782;
// Generate N0342
wire n0332 = ~(((n0329 | poc) & x22 & clk2) | (~(n0329 | poc) & n0337 & clk1));
assign n0342 = n0332;
 
// Output OPA onto the data bus
wire opa_ib = (ldm_bbl | jun_jms) & ~x21_clk2;
assign data = opa_ib ? opa : 4'bzzzz;
 
endmodule
/mcs-4/trunk/rtl/verilog/i4004/instruction_pointer.v
0,0 → 1,214
`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/
//
 
//
// 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
/mcs-4/trunk/rtl/verilog/i4004/scratchpad.v
0,0 → 1,168
`timescale 1ns / 1ps
`default_nettype none
////////////////////////////////////////////////////////////////////////
//
// 4004 Scratchpad Register Array
//
// This file is part of the MCS-4 project hosted at OpenCores:
// http://www.opencores.org/cores/mcs-4/
//
 
//
// 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 scratchpad (
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 n0636, // JIN+FIN
input wire sc_m22_clk2, // SC&M22&CLK2
input wire fin_fim_src_jin, // FIN+FIM+SRC+JIN
input wire inc_isz_add_sub_xch_ld, // INC+ISZ+ADD+SUB+XCH+LD
input wire inc_isz_xch, // INC+ISZ+XCH
input wire opa0_n, // ~OPA.0
input wire sc, // SC (Single Cycle)
input wire dc // DC (Double Cycle, ~SC)
);
 
reg [7:0] dram_array [0:7];
reg [7:0] dram_temp;
reg [3:0] din_n;
 
// Refresh counter stuff
wire [2:0] reg_rfsh; // Row Refresh counter
wire reg_rfsh_step; // SC&A12&CLK2
assign reg_rfsh_step = sc & a12 & clk2;
counter reg_rfsh_0 (
.sysclk(sysclk),
.step_a(clk1),
.step_b(reg_rfsh_step),
.q(reg_rfsh[0])
);
counter reg_rfsh_1 (
.sysclk(sysclk),
.step_a( reg_rfsh[0]),
.step_b(~reg_rfsh[0]),
.q(reg_rfsh[1])
);
counter reg_rfsh_2 (
.sysclk(sysclk),
.step_a( reg_rfsh[1]),
.step_b(~reg_rfsh[1]),
.q(reg_rfsh[2])
);
 
// Row selection mux
reg [2:0] row; // {N0646, N0617, N0582}
always @(posedge sysclk) begin
if (sc & a22)
row <= reg_rfsh;
if (sc_m22_clk2)
row <= data[3:1];
end
 
 
// Row Precharge/Read/Write stuff
wire precharge; // SC(A22+M22)CLK2
wire row_read; // (~POC)&CLK2&SC(A32+X12)
wire row_write; // CLK2&SC(A12+M12)
 
assign precharge = sc & (a22 | m22) & clk2;
assign row_read = ~(poc | ~(clk2 & sc & (a32 | x12)));
assign row_write = sc & (a12 | m12) & clk2;
 
 
// Column Read selection stuff
reg n0615;
always @(posedge sysclk) begin
if (clk2)
n0615 <= ~(x12 & (fin_fim_src_jin |
(opa0_n & inc_isz_add_sub_xch_ld)));
end
wire rrab0 = ~(dc | n0615 | clk2);
 
reg n0592;
always @(posedge sysclk) begin
if (clk2)
n0592 <= ~((x22 & fin_fim_src_jin) |
(~opa0_n & x12 & inc_isz_add_sub_xch_ld));
end
wire rrab1 = ~(dc | n0592 | clk2);
 
 
// Column Write selection stuff
wire n0564 = opa0_n & fin_fim_src_jin & dc;
wire n0568 = inc_isz_xch & x32 & sc;
wire wrab0 = clk2 & ((m12 & n0564) | ( opa0_n & n0568));
wire wrab1 = clk2 & ((m22 & n0564) | (~opa0_n & n0568));
 
 
// Force row 0 if FIN&X12
wire fin_x12 = (n0636 & opa0_n) & x12;
 
// Manage the row data buffer
always @(posedge sysclk) begin
if (precharge)
dram_temp <= 8'b0;
if (row_read)
dram_temp <= dram_array[fin_x12 ? 3'b000 : row];
if (wrab0)
dram_temp[ 7:4] <= ~din_n;
if (wrab1)
dram_temp[ 3:0] <= ~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)
rrab0: dout = dram_temp[ 7:4];
rrab1: dout = dram_temp[ 3:0];
default: dout = 4'bzzzz;
endcase
end
assign data = dout;
// Data In latch
always @(posedge sysclk) begin
if (m12_m22_clk1_m11_m12)
din_n <= ~data;
end
 
endmodule
/mcs-4/trunk/rtl/verilog/i4004/timing_io.v
0,0 → 1,159
`timescale 1ns / 1ps
`default_nettype none
////////////////////////////////////////////////////////////////////////
//
// 4004 Timing and I/O Interfaces
//
// This file is part of the MCS-4 project hosted at OpenCores:
// http://www.opencores.org/cores/mcs-4/
//
 
//
// 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 timing_io(
input wire sysclk,
input wire clk1_pad,
input wire clk2_pad,
input wire poc_pad,
input wire ior,
// Timing and I/O Board Outputs
output wire clk1,
output wire clk2,
output wire a12,
output wire a22,
output wire a32,
output wire m12,
output wire m22,
output wire x12,
output wire x22,
output wire x32,
output wire gate,
output reg poc,
// External I/O Pad conditioning
inout wire [3:0] data,
inout wire [3:0] data_pad,
input wire test_pad,
output reg n0432,
output reg sync_pad,
input wire cmrom,
output wire cmrom_pad,
input wire cmram0,
output wire cmram0_pad,
input wire cmram1,
output wire cmram1_pad,
input wire cmram2,
output wire cmram2_pad,
input wire cmram3,
output wire cmram3_pad
);
 
// Simple pass-throughs
assign clk1 = clk1_pad;
assign clk2 = clk2_pad;
assign cmrom_pad = cmrom;
assign cmram0_pad = cmram0;
assign cmram1_pad = cmram1;
assign cmram2_pad = cmram2;
assign cmram3_pad = cmram3;
 
 
// Generate the 8 execution phase indicators
reg [0:7] master = 8'h00;
reg [0:7] slave = 8'h00;
always @(posedge sysclk) begin
if (clk2)
master <= {~|slave[0:6], slave[0:6]};
else
sync_pad <= master[7];
 
if (clk1)
slave <= master;
end
 
assign a12 = slave[0];
assign a22 = slave[1];
assign a32 = slave[2];
assign m12 = slave[3];
assign m22 = slave[4];
assign x12 = slave[5];
assign x22 = slave[6];
assign x32 = slave[7];
 
 
// Generate the DRAM Input Gate signal
// Properly called M12+M22+CLK1~(M11&M12)
wire n0279 = ~(a32 | m12);
reg n0278;
always @(posedge sysclk) begin
if (clk2)
n0278 <= n0279;
end
wire n0708 = ~((n0278 & clk1) | m12 | m22);
assign gate = ~n0708;
 
// Generate a clean POC signal
always @(posedge sysclk) begin
if (poc_pad) poc <= 1'b1;
else if (a12) poc <= 1'b0;
else poc <= poc;
end
// Generate a clean ~TEST signal (n0432)
always @(posedge sysclk) begin
n0432 <= ~test_pad;
end
 
// Manage the Data I/O pads
reg L;
always @(posedge sysclk) begin
if (clk2)
L <= a32 | m12 | (x12 & (ior | poc));
end
 
wire n0702 = ~clk2;
reg n0685;
reg n0699;
reg n0707;
always @(posedge sysclk) begin
if (clk1) begin
n0685 <= ~L;
n0707 <= L;
end
if (n0702)
n0699 <= ~L;
end
wire n0700 = n0707 | (L & n0702) | poc;
wire n0659 = (clk2 & n0685) | (clk1 & L);
wire n0676 = clk1 | n0685 | n0699;
// Incoming data from the external pads
reg [3:0] data_in;
always @* begin
if (n0659) data_in = 4'b1111;
else if (n0676) data_in = 4'bzzzz;
else if (poc) data_in = 4'b0000;
else data_in = data_pad;
end
assign data = data_in;
 
// Outgoing data to the external pads
reg [3:0] data_out;
always @(posedge sysclk) begin
if (n0702)
data_out <= data;
end
assign data_pad = poc ? 4'b0000 : (n0700 ? 4'bzzzz : data_out);
 
endmodule

powered by: WebSVN 2.1.0

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