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
/mcs-4
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/trunk/rtl/verilog/scratchpad.v
0,0 → 1,164
`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 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)); |
|
|
// Manage the row data buffer |
always @(posedge sysclk) begin |
if (precharge) |
dram_temp <= 8'b0; |
|
if (row_read) |
dram_temp <= dram_array[row]; |
|
if (wrab0) |
dram_temp[ 3:0] <= ~din_n; |
if (wrab1) |
dram_temp[ 7:4] <= ~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[ 3:0]; |
rrab1: dout = dram_temp[ 7:4]; |
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 |
/trunk/rtl/verilog/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 |
/trunk/rtl/verilog/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 |
/trunk/rtl/verilog/i4004.v
0,0 → 1,286
`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 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), |
.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), |
.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 |
/trunk/rtl/verilog/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 |
/trunk/rtl/verilog/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 (m12) |
{n0873, n0872, n0871, n0870} <= 4'b1010; |
if (acc_ada) |
{n0873, n0872, n0871, n0870} <= acc; |
if (acc_adac) |
{n0873, n0872, n0871, n0870} <= ~acc; |
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 n0877 = ~((n0893 & n0559 & n0873) | (n0861 & (n0893 | n0873 | n0559))); |
wire n0878 = ~((n0877 & 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 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 |
/trunk/rtl/verilog/instruction_decode.v
0,0 → 1,254
`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 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 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; |
if (clk1) |
n0397 <= ~n0405; |
end |
assign cn_n = ~n0397; |
|
// The Single-Cycle Flip-Flop |
reg n0343; |
wire n0368 = ~((sc & (fin_fim | jcn_isz | jun_jms) & x32) | (n0343 & ~x32)); |
reg n0362; |
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 |
/trunk/doc/License.txt
0,0 → 1,45
License information for the OpenCores MCS-4 Project |
|
Unless otherwise noted, all project files and code are |
Copyright © 2012 by Reece Pollack <rrpollack@opencores.org> |
|
|
This work based on the following previous works: |
|
MCS-4 Simulator by Lagos Kintli (2009). |
|
Schematic capture and design verification by Fred Huettig, |
Brian Silverman and Barry Silverman (February 2, 2006). |
|
Re-drawn schematics based on Revision G of the original |
Intel 4004 schematics by Intel Corporation (August 6, 1976). |
|
Intel® is a registered trademark of the Intel Corporation. |
|
------------------------------------------------------------- |
|
These materials are provided under the Creative Commons |
"Attribution-NonCommercial-ShareAlike" Public License. They |
are NOT "public domain" and are protected by copyright. |
|
Under the terms of the CCPL, you are free to: |
* make derivative works |
* copy, distribute, display, and perform this work |
under the following conditions: |
* Attribution. You must attribute the work in the manner |
specified by the author or licensor. |
* Noncommercial. You may not use this work for commercial purposes. |
* Share Alike. If you alter, transform, or build upon this work, |
you may distribute the resulting work only under a license |
identical to this one. |
* For any reuse or distribution, you must make clear to others the |
license terms of this work. |
* Any of these conditions can be waived if you get |
permission from the copyright holders. |
* Your fair use and other rights are in no way affected by the |
above. |
|
The full text of the license is available at: |
http://www.intel.com/museum/4004ipnclicense.htm |
Or in this project file: |
doc/Intel_IPNC_License.pdf |
/trunk/doc/Intel_IPNC_License.pdf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
trunk/doc/Intel_IPNC_License.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property