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

Subversion Repositories mcs-4

[/] [mcs-4/] [trunk/] [rtl/] [verilog/] [i4004/] [instruction_decode.v] - Rev 5

Go to most recent revision | Compare with Previous | Blame | View Log

`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/
// 
// 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_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
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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