% 6.111 Final Project - Fall 1996 - "PIC-Cam" %
% Kenneth B. Russell <kbrussel@mit.edu> %

INCLUDE "lpm_mux.inc";
INCLUDE "digictr.inc";
INCLUDE "jpegctr.inc";
INCLUDE "pc_const.inc";

CONSTANT FIRST_FREE_ADDRESS = (4 * ADDRS_PER_ROW * NUM_LINES * NUM_FIELDS);
% Last valid address is the last pixel on the PREVIOUS line %
CONSTANT LAST_ADDRESS = FIRST_FREE_ADDRESS - (4 * ADDRS_PER_ROW) + (4 * PIXELS_PER_ROW) - 1;

% Chip which contains 2 digitization counters and a JPEG-order %
% counter. Contains multiplexing circuitry to output an 11-bit %
% address which corresponds to a DRAM row or column address, %
% along with two bits which indicate which byte of those 32 %
% bits is currently being addressed (if applicable). %

SUBDESIGN ctrchip
(
	% Inputs %
	/clk			: INPUT;
	
	% Counter control inputs (from the main FSM) %
	% NOTE: Some of these inputs have been commented %
	% out and had the counters' inputs fixed to GND, %
	% because one of the counters only has to count %
	% by bytes, and the other one never has to count %
	% by bytes. %
	c1_aclr			: INPUT;
	c1_cnt_en		: INPUT;
%	c1_cnt2_en		: INPUT; %
%	c1_cnt4_en		: INPUT; %
	c1_sload		: INPUT;
	c2_aclr			: INPUT;
%	c2_cnt_en		: INPUT; %
	c2_cnt2_en		: INPUT;
	c2_cnt4_en		: INPUT;
	c2_sload		: INPUT;
	cj_aclr			: INPUT;
	cj_cnt_en		: INPUT;
%	cj_sload		: INPUT; %
	
	% Input for selecting a row or column address. %
	% ** NOTE ** that the output port is 13 bits wide. The lower two %
	% bits ALWAYS map to the low two bits of the appropriate counter, %
	% which are equivalent to a byte selector within that word. %
	% MAPPING: %
	%   S3  S2  S1  OUTPUT %
	%   0   0   0   Counter 1, ROW address (high bits) %
	%   0   0   1   Counter 1, COLUMN address (low bits) %
	%   0   1   0   Counter 2, ROW address %
	%   0   1   1   Counter 2, COLUMN address %
	%   1   0   0   JPEG Counter, ROW address (high bits) %
	%   1   0   1   JPEG Counter, COLUMN address (low bits) %
	%   1   1   X   Undefined %	
	select[3..1]	: INPUT;
	
	% Outputs %
	q[13..1]		: OUTPUT;	% Address information (described above) %
	c12_equal		: OUTPUT;	% Information to main FSM; counter 1 == counter 2 %
	cj_full			: OUTPUT;	% JPEG counter reached end of last image %
)
VARIABLE
	addr_mux		: lpm_mux WITH (
		LPM_WIDTH = 13,
		LPM_SIZE = 6,
		LPM_WIDTHS = 3
	);
	c1				: digictr;
	c2				: digictr;
	cj				: jpegctr;
BEGIN
	% Clocks %
	c1.clock = /clk;
	c2.clock = /clk;
	cj.clock = /clk;
	
	% Load inputs %
	c1.sload = c1_sload;
	c2.sload = c2_sload;
%	cj.sload = cj_sload; %
	
	% Clear inputs %
	c1.aclr = c1_aclr;
	c2.aclr = c2_aclr;
	cj.aclr = cj_aclr;
	
	% Count enable inputs %
	c1.cnt_en = c1_cnt_en;
	c1.cnt2_en = GND;
	c1.cnt4_en = GND;
%	c1.cnt2_en = c1_cnt2_en; %
%	c1.cnt4_en = c1_cnt4_en; %
	c2.cnt_en = GND;
%	c2.cnt_en = c2_cnt_en; %
	c2.cnt2_en = c2_cnt2_en;
	c2.cnt4_en = c2_cnt4_en;
	cj.cnt_en = cj_cnt_en;

	% Data inputs to the counters. %
	% NOTE that the address we load is the beginning of the %
	% next "line" after the last image line. That's where %
	% we'll begin to store the JPEG data. %
	c1.data[] = FIRST_FREE_ADDRESS;
	c2.data[] = FIRST_FREE_ADDRESS;
	% Debugging data input for the JPEG counter; comment out %
	% in the real system. Allows four counts before cj_full %
	% should go high. %
	% cj.data[] = H"707E6F"; %

	% Hook up the counters' outputs to the multiplexer %
	addr_mux.data[0][12..2] = c1.q[24..14];
	addr_mux.data[0][1..0]  = c1.q[2..1];
	addr_mux.data[1][12..2] = c1.q[13..3];
	addr_mux.data[1][1..0]  = c1.q[2..1];
	addr_mux.data[2][12..2] = c2.q[24..14];
	addr_mux.data[2][1..0]  = c2.q[2..1];
	addr_mux.data[3][12..2] = c2.q[13..3];
	addr_mux.data[3][1..0]  = c2.q[2..1];
	addr_mux.data[4][12]    = GND;
	addr_mux.data[4][11..2] = cj.q[23..14];
	addr_mux.data[4][1..0]  = cj.q[2..1];
	addr_mux.data[5][12..2] = cj.q[13..3];
	addr_mux.data[5][1..0]  = cj.q[2..1];
	% ...and the selection input %
	addr_mux.sel[] = select[];
	
	% The address output. The two low bits go to the main FSM. %
	% Lowest bit is the byte counter; next higher is the half %
	% word counter. %
	q[] = addr_mux.result[];
	% Information outputs to the main FSM %
	c12_equal = (c1.q[] == c2.q[]);
	cj_full = (cj.q[] == LAST_ADDRESS);
END;