`define SERIAL

//
// The pin-out is fixed in the project file, and must match the board
// as constructed.  Here we specify nice names for all the signals which
// match the names in the project's placement map.
//
module cpld (
  cf0,			// 1
  pulse_la,		// 2
  data08_l,		// 4
  f_set_l,		// 5
  md11_l,		// 6
  user_mode_l,		// 8
  md10_l,		// 9
  md09_l,		// 10
  d_l,			// 11
  md08_l,		// 12
  f_l,			// 15
  ir01_l,		// 16
  ir00_l,		// 17
  ind2_l,		// 18
  ind1_l,		// 20
  cpma_disable_l,	// 21
  skip_l,		// 22
  initialize,		// 24
  int_rqst_l,		// 25
  ts3_l,		// 27
  internal_io_l,	// 28
  ts1_l,		// 29
  tp4,			// 30
  tp3,			// 31
  c1_l,			// 33
  tp2,			// 34
  c0_l,			// 35
  io_pause_l,		// 36
  df_enable,		// 37
  power_ok,		// 39
  data07_l,		// 40
  run_l,		// 41
  data06_l,		// 44
  data05_l,		// 45
  data04_l,		// 46
  int_in_prog_l,	// 48
  md07_l,		// 49
  md06_l,		// 50
  md05_l,		// 51
  md04_l,		// 52
  load_cont_l,		// 54
  tp_bb1,		// 55
  tp_ba1,		// 56
  data03_l,		// 57
  data02_l,		// 58
  data01_l,		// 60
  data00_l,		// 61
  md03_l,		// 63
  md02_l,		// 64
  md01_l,		// 65
  md00_l,		// 67
  ema2_l,		// 68
  ema1_l,		// 69
  ema0_l,		// 70
  tp_ab1,		// 73
  tp_aa1,		// 74
  rxdttl,		// 75
  txdttl,		// 76
  data11_l,		// 77
  key_ctl_l,		// 79
  data10_l,		// 80
  data09_l,		// 81
  clk,			// 83
  cf1			// 84
);

input cf0;
input pulse_la;
inout data08_l;
input f_set_l;
input md11_l;
input user_mode_l;
input md10_l;
input md09_l;
input d_l;
input md08_l;
input f_l;
input ir01_l;
input ir00_l;
input ind2_l;
input ind1_l;
input cpma_disable_l;
output skip_l;
input initialize;
output int_rqst_l;
input ts3_l;
output internal_io_l;
input ts1_l;
input tp4;
input tp3;
output c1_l;
input tp2;
output c0_l;
input io_pause_l;
input df_enable;
input power_ok;
inout data07_l;
input run_l;
inout data06_l;
inout data05_l;
inout data04_l;
input int_in_prog_l;
input md07_l;
input md06_l;
input md05_l;
input md04_l;
input load_cont_l;
input tp_bb1;
input tp_ba1;
inout data03_l;
inout data02_l;
inout data01_l;
inout data00_l;
input md03_l;
input md02_l;
input md01_l;
input md00_l;
input ema2_l;
input ema1_l;
input ema0_l;
input tp_ab1;
input tp_aa1;
input rxdttl;
output txdttl;
inout data11_l;
input key_ctl_l;
inout data10_l;
inout data09_l;
input clk;
input cf1;

wire bd230400;
assign bd230400 = clk;

reg bd115200;
reg bd38400;
reg bd19200;
reg bd9600;
reg bd4800;
reg bd2400;
reg bd1200;
reg bd600;
reg bd300;
reg bd109;
wire n_t_3x;
wire n_t_6x;
reg n_t_1x;
reg n_t_2x;
reg n_t_4x;
reg n_t_5x;
wire sw1, sw2, sw3, sw4, sw5, sw6;
assign sw1 = cf0;
assign sw2 = cf1;
assign sw3 = tp_aa1;
assign sw4 = tp_ab1;
assign sw5 = tp_ba1;
assign sw6 = tp_bb1;

wire md03_set, md04_set, md05_set, md07_set;
wire md03_ok, md04_ok, md05_ok;
wire md06_in, md07_in, md08_in;
wire md06_out, md07_out, md08_out;
wire rx_sel_l;
wire tx_sel_l;
wire j23;
wire h12;
wire ratex2;

`ifdef VERILATOR
//
// Signal array added here to make the trace output easier to read.
//
int md;
assign md = {~md00_l, ~md01_l, ~md02_l, ~md03_l, ~md04_l, ~md05_l, ~md06_l, ~md07_l, ~md08_l, ~md09_l, ~md10_l, ~md11_l};
`endif

//
// Now, basically just instantiate the various modules.
//
// The modules are "dumbed down" to minimize warnings, and configured
// to match the limitations of the board, mostly imposed by the limited
// pin count.
//
// Ifdefs will get added later to configure for the various supported
// functions.
//

`ifdef SERIAL
// The DEC M8650 board model is instantiated here.
// The M8650 serial interface is modified during instantiation by replacing
// the baud rate generator and the level converters.  The board has no support
// for current loop, so we also set up here for 1 stop bit.
// Settings:
// sw[1:3]	Baud		sw[4:6]		Address
// 000		110		000		Disabled (0)
// 001		300		001		03/04
// 010		600		010		40/41
// 011		1200		011		42/43
// 100		9600		100		44/45
// 101		38400		101		46/47
// 110		115200		110		34/35
// 111		230400		111		11/12
// The six switches for settings are wired to
// [cf0,cf1,tp_aa1,tp_ab1,tp_ba1,tp_bb1].  (This precludes the use of
// the test points when serial I/O is chosen.)
/* verilator lint_off PINMISSING */
m8650d m8650d (
  .n3v3(1'b1),
//.n_t_128x(n_t_128x),	// RX20MA clamped to TTL(ish) (input)
  .n_t_152x(1'b1),	// 19.661 MHz Baud rate divider input (614.4 Kbaud)
  .n_t_50x(rx_sel_l),	// RX polarity for MD03
  .n_t_3x(rx_sel_l),	// RX polarity for MD04
  .n_t_165x(rx_sel_l),	// RX polarity for MD05
  .n_t_86x(rx_sel_l),	// RX polarity for MD06
  .n_t_90x(rx_sel_l),	// RX polarity for MD07
  .n_t_96x(rx_sel_l),	// RX polarity for MD08
  .n_t_32x(tx_sel_l),	// TX polarity for MD03
  .n_t_74x(tx_sel_l),	// TX polarity for MD04
  .n_t_1x(tx_sel_l),	// TX polarity for MD05
  .n_t_84x(tx_sel_l),	// TX polarity for MD06
  .n_t_58x(tx_sel_l),	// TX polarity for MD07
  .n_t_95x(tx_sel_l),	// TX polarity for MD08
  .stp_mark(j23),	// Stop bit jumpering
//.n_t_119x(j23),	// Use Two Stop Bits
  .n_t_146x(j23),	// Use One Stop Bit
  .tx_rate(h12),	// TX is 1X or 16
  .rx_rate(h12),	// TX Rate = RX Rate
//.n_t_162x(h12),	// TX Rate = RX Rate / 4
  .testp4(ratex2),	// Baud Rate Clock Input
//.bd2400(ratex2),	// Internally Generated Baud Rates
//.bd1200(ratex2),
//.bd600(ratex2),
//.bd300(ratex2),
//.bd150(ratex2),
  .c0_l(c0_l),
  .c1_l(c1_l),
  .data04_l(data04_l),
  .data05_l(data05_l),
  .data06_l(data06_l),
  .data07_l(data07_l),
  .data08_l(data08_l),
  .data09_l(data09_l),
  .data10_l(data10_l),
  .data11_l(data11_l),
  .initialize(initialize),
//.int_enab(cb1),	// Test point, not implemented
  .int_rqst_l(int_rqst_l),
  .internal_io_l(internal_io_l),
  .io_pause_l(io_pause_l),
  .line(txdttl),	// TTL Serial Output 
  .md03(md03_l),
  .md04(md04_l),
  .md05(md05_l),
  .md06(md06_l),
  .md07(md07_l),
  .md08(md08_l),
  .md09(md09_l),
  .md10(md10_l),
  .md11(md11_l),
//.n_t_83x(~rx_data),	// RX_DATA, inverted (input)
  .power_ok(power_ok),
//.r_run_l(r_run_l),	// Reader Run, not implemented
//.reader_run(db1),	// Test point, not implemented
//.rx20ma_data(rx20ma_data), // CL input data (TTL, output to H)
//.rx_active(ab1),	// Test point, not implemented
//.rx_data(rx_data),	// EIA input data (TTL, output to M)
  .serial_in(rxdttl),	// UART input (TTL, input pin E)
  .skip_l(skip_l),
  .tp3(tp3),
//.tx_active(ba1),	// Test point (not implemented)
//.tx_div_l(tx_div_l),	// Delay Line input
  .n_t_103x(1'b1),	// E25 pin 5, delay line output
//.n_t_103x(~tx_active_l), // E25 pin 5, delay line output
);
//
// The new baud rate generator.
// Our two highest speeds are 6X and 3X the next lower group.  We implent
// divide-by-two, then divide-by-3.
always @(bd230400, bd115200)
  if (~bd230400) begin
    bd115200 <= ~bd115200;
  end
// Divide-by-3.  We use n_t_3x to reset when the count reaches
// three.  This also means the duty cycle for 28,400 baud isn't
// 50%, which is hopefully not a problem.
always @(negedge bd115200, negedge n_t_3x)
  if (~n_t_3x) begin
    n_t_1x <= 1'b0;
  end else
  if (~bd115200) begin
    n_t_1x <= ~n_t_1x;
  end
always @(negedge n_t_1x, negedge n_t_3x)
  if (~n_t_3x) begin
    bd38400 <= 1'b0;
  end else
  if (~n_t_1x) begin
    bd38400 <= ~bd38400;
  end
assign n_t_3x = ~(n_t_1x & bd38400);
// 300, 600, 1200, 2400, 4800, 9600, 19200, 38400
// are all divide-by-2.
always @(bd38400, bd19200)
  if (~bd38400) begin
    bd19200 <= ~bd19200;
  end
always @(bd19200, bd9600)
  if (~bd19200) begin
    bd9600 <= ~bd9600;
  end
always @(bd9600, bd4800)
  if (~bd9600) begin
    bd4800 <= ~bd4800;
  end
always @(bd4800, bd2400)
  if (~bd4800) begin
    bd2400 <= ~bd2400;
  end
always @(bd2400, bd1200)
  if (~bd2400) begin
    bd1200 <= ~bd1200;
  end
always @(bd1200, bd600)
  if (~bd1200) begin
    bd600 <= ~bd600;
  end
always @(bd600, bd300)
  if (~bd600) begin
    bd300 <= ~bd300;
  end
// OK.  Now, we go back to 1200 baud.  Dividing that
// by 9 will give 109 baud.  Again without a 50% duty cycle.
always @(negedge bd1200, negedge n_t_6x)
  if (~n_t_6x) begin
    n_t_2x <= 1'b0;
  end else
  if (~bd1200) begin
    n_t_2x <= ~n_t_2x;
  end
always @(negedge n_t_2x, negedge n_t_6x)
  if (~n_t_6x) begin
    n_t_4x <= 1'b0;
  end else
  if (~n_t_2x) begin
    n_t_4x <= ~n_t_4x;
  end
always @(negedge n_t_4x, negedge n_t_6x)
  if (~n_t_6x) begin
    n_t_5x <= 1'b0;
  end else
  if (~n_t_4x) begin
    n_t_5x <= ~n_t_5x;
  end
always @(negedge n_t_5x, negedge n_t_6x)
  if (~n_t_6x) begin
    bd109 <= 1'b0;
  end else
  if (~n_t_5x) begin
    bd109 <= ~bd109;
  end
assign n_t_6x = ~(bd109 & n_t_4x & n_t_2x);
// Finally, assign the rate based on the config switches.
assign ratex2 = (~sw1 & ~sw2 & ~sw3) & bd109
              | (~sw1 & ~sw2 &  sw3) & bd300
              | (~sw1 &  sw2 & ~sw3) & bd600
              | (~sw1 &  sw2 &  sw3) & bd1200
              | ( sw1 & ~sw2 & ~sw3) & bd9600
              | ( sw1 & ~sw2 &  sw3) & bd38400
              | ( sw1 &  sw2 & ~sw3) & bd115200
              | ( sw1 &  sw2 &  sw3) & bd230400;
//
// Hook up address decoders.  The first digit of the I/O address
// is always the same for the input and output devices.
assign md03_set = (~sw4 &  sw5)
                | ( sw4 & ~sw5);
assign md04_set = ( sw4 &  sw5 & ~sw6);
assign md05_set = ( sw4 &  sw5);
assign md03_ok  = ( md03_set & ~md03_l)
                | (~md03_set &  md03_l);
assign md04_ok  = ( md04_set & ~md04_l)
                | (~md04_set &  md04_l);
assign md05_ok  = ( md05_set & ~md05_l)
                | (~md05_set &  md05_l);
assign md06_in  = ( sw4 & ~sw5)
                | ( sw4 &  sw5 & ~sw6);
assign md06_out = md06_in
                | ( sw4 &  sw5 &  sw6);
assign md07_set = (~sw4 &  sw5 &  sw6)
                | ( sw4 & ~sw5 &  sw6);
assign md07_in  = md07_set
                | (~sw4 & ~sw5 & ~sw6);
assign md07_out = md07_set
                | ( sw4 &  sw5 &  sw6);
assign md08_in  = (~sw4 & ~sw5 & ~sw6)
                | ( sw4 &  sw5 &  sw6);
assign md08_out = ~md08_in;
assign rx_sel_l = ~(md03_ok & md04_ok & md05_ok
                  & ((md06_in & ~md06_l) | (~md06_in & md06_l))
                  & ((md07_in & ~md07_l) | (~md07_in & md07_l))
                  & ((md08_in & ~md08_l) | (~md08_in & md08_l)));
assign tx_sel_l = ~(md03_ok & md04_ok & md05_ok
                  & ((md06_out & ~md06_l) | (~md06_out & md06_l))
                  & ((md07_out & ~md07_l) | (~md07_out & md07_l))
                  & ((md08_out & ~md08_l) | (~md08_out & md08_l)));
`endif

`ifdef VERILATOR
// Attempt to get weak pull-ups working.
pup pup(
   .c0_low(c0_l),
   .c1_low(c1_l),
   .data00_low(data00_l),
   .data01_low(data01_l),
   .data02_low(data02_l),
   .data03_low(data03_l),
   .data04_low(data04_l),
   .data05_low(data05_l),
   .data06_low(data06_l),
   .data07_low(data07_l),
   .data08_low(data08_l),
   .data09_low(data09_l),
   .data10_low(data10_l),
   .data11_low(data11_l),
   .internal_io_low(internal_io_l),
   .interrupt_low(int_rqst_l),
   .skip_low(skip_l)
);
`endif

`ifdef MONO
// We convert the monostables here to 74122 instances, as
// that seems to be the most general retriggerable monostable.

// 10K, 220pF == ?? us == 15 ticks
sn74122 e1a(
   .clk(clock),
   .a1(dly_done_low),
   .a2(1'b0),
   .b1(1'b1),
   .b2(1'b1),
   .clr_l(1'b1),
   .delay(15),
   .q(ddone)
);

// 10K, 220pF == ?? us == 15 ticks
sn74122 e1b(
   .clk(clock),
   .a1(erase_interval_low),
   .a2(1'b0),
   .b1(1'b1),
   .b2(1'b1),
   .clr_l(1'b1),
   .delay(15),
   .q(set_done)
);

// 24.3K, .25uF == ?? us == 15 ticks
sn74122 e2a(
   .clk(clock),
   .a1(color),
   .a2(color),
   .b1(1'b1),
   .b2(1'b1),
   .clr_l(1'b1),
   .delay(15),
   .q(grn_delay)
);

// 31.6K, .033uF == ?? us == 15 ticks
sn74122 e2b(
   .clk(clock),
   .a1(1'b0),
   .a2(1'b0),
   .b1(color),
   .b2(1'b1),
   .clr_l(1'b1),
   .delay(15),
   .q(red_delay)
);

// 31.6K, .033uF == ?? us == 15 ticks
sn74122 e4(
   .clk(clock),
   .a1(load_x_low),
   .a2(load_y_low),
   .b1(1'b1),
   .b2(1'b1),
   .clr_l(1'b1),
   .delay(15),
   .q_l(ld_del_low)
);

// 10k/39.2K, 220pF == ?? us == 15 ticks
sn74122 e15(
   .clk(clock),
   .a1(b_dixy_low),
   .a2(b_dixy_low),
   .b1(1'b1),
   .b2(1'b1),
   .clr_l(1'b1),
   .delay(15),
   .q(del_1),
   .q_l(del_1_low)
);
`endif

endmodule
