-
Notifications
You must be signed in to change notification settings - Fork 22
/
vm2_qbus.v
2294 lines (2078 loc) · 66.7 KB
/
vm2_qbus.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//
// Copyright (c) 2014-2019 by 1801BM1@gmail.com
//______________________________________________________________________________
//
// Version of 1801BM2 processor with Q-bus external interface
// All external signal transitions should be synchronzed with pin_clk
// The core does not contain any extra metastability eliminators itself
//
module vm2_qbus
#(parameter
//______________________________________________________________________________
//
// If VM2_CORE_FIX_PREFETCH is nonzero the PC2 prefetch bugfix is applied.
//
// Original 1801BM2 processor contains microcode bug at the following conditions:
// - two operands PDP-11 instruction is being executed
// - source has addressing method @PC (field value 17 octal)
// - destination does not involve PC (dst register field !=7)
// - no extra instruction words are used by destination (no E(Rn), @E(Rn))
// - Q-bus is slow and opcode prefetch is not completed before microcode
// starts source field processing and fetching the source data (slow RPLY/AR)
//
// At the source operand processing the source address is taken from PC and
// written back to the PC and Q-bus address register unchanged. This writing back
// also rewrites the PC2 register containing the modified prefetch address (PC+2/4).
// Then at the command completion microcode does not restart the prefetch with
// io_cmd code and prefetch continues with wrong address in PC2. The next
// instruction behaviour may become undefined.
//
// Fix just blocks the PC2 write in the affected instructions and prefetch
// address is no corrupted. If zero parameter is specified the model follows
// the original 1801BM2 behaviour (with prefetch bug).
//
VM2_CORE_FIX_PREFETCH = 0
)
(
input pin_clk, // processor clock
output pin_init, // peripheral reset output
input pin_dclo, // processor reset
input pin_aclo, // power fail notificaton
input pin_halt, // halt mode interrupt
input pin_evnt, // timer interrupt requests
input pin_virq, // vectored interrupt request
//
input pin_ar, // address ready
input pin_dmr, // bus grant request
input pin_sack, // bus grant acknowlegement
input pin_rply, // transaction acknowlegement
//
input pin_waki, // window grant request
output pin_wrq, // window grant acknowlegement
output pin_clko, // internal clock output
output pin_dmgo, // bus grant
output pin_sel, // halt mode access
output pin_iako, // interrupt vector input
//
input [15:0] pin_ad_in, // data bus input
output [15:0] pin_ad_out, // address/data bus output
output pin_ad_ena, // address/data bus enable
output pin_ctrl_ena, //
//
output pin_sync, // address strobe
output pin_wtbt, // write/byte status
output pin_dout, // data output strobe
output pin_din // data input strobe
);
//______________________________________________________________________________
//
reg f1, f2; // phase clock generator
reg virq, halt, evnt; // interrupt requests
reg dclo, aclo; // cold reset, power monitor
reg aclo_stb; //
//
reg ac0; // initial ACLO rising edge detected
reg dble_cnt0; // double QBUS timeout error counter
reg dble_cnt1; //
reg evnt_fall; // EVNT rising edge detector
reg aclo_fall; // ACLO falling edge detector
reg aclo_rise; // ACLO rising edge detector
//
wire [15:0] ad; // internal address/data bus
reg ad_oe; // external AD pins output enable
reg ct_oe; //
//
wire bus_free; //
wire bus_adr; // address on ad bus strobe
reg bus_dat; // data on ad bus strobe
reg bfree; //
//
wire sel, sel1, sel_alt; //
reg sel2; //
//
wire init; //
reg init_out; //
reg dmgo_out; //
wire dmgo; //
reg dmr; //
reg waki; //
wire ar; //
wire sack; //
wire win_req; //
reg wrq; //
wire iako; //
reg iako_out; //
reg vec_stb; //
wire wtbt_out; //
wire rplys; //
reg rply; //
reg rply0, rply1; //
reg rply2, rply3; //
reg din; //
reg dout, dout_s0; //
reg sync, sync_s0; //
reg ardy, ardy_s0; //
reg adr_req; //
reg drdy; //
reg sk, skp; //
wire sync_clw; //
wire sync_set; //
wire ua_rply; //
wire rdat; //
//
wire io_start; // start IO transaction
wire io_rdy; //
wire in_ua; //
wire io_in; //
wire io_wr; //
wire io_rd; //
wire io_sel; //
wire io_iak; //
wire io_alt; //
wire io_x001; //
wire io_rcd; //
wire io_rcd1; //
wire io_cmd; //
reg io_cmdr; //
reg io_rcdr; //
reg io_pswr; //
reg io_qto; // Q-bus timeout timer mode
//
reg iop_wr; //
reg iop_rd; //
reg iop_in; //
reg iop_rcd; //
reg iop_sel; // halt mode access
reg iop_iak; //
reg iop_una; // unaddressed access
reg iop_word; //
wire iop_stb; // IO opcode strobe
//
wire reset; //
wire abort; //
wire mc_res; //
wire mc_stb; // mc read phase strobe
wire mw_stb; // mc write phase strobe
wire pi_stb; // peri
wire all_rdy; //
reg all_rdy_t0; //
reg all_rdy_t1; //
reg alu_nrdy; // ALU not ready
reg sta_nrdy; // state not ready
reg cmd_nrdy; // instruction completion
wire pli_nrdy; // interrupt polling not ready
reg tim_nrdy0; //
reg tim_nrdy1; //
wire mc_rdy; //
reg sa1, sa2; //
reg br_iocmd; // instruction reading to breag in progress
reg br_ready; // breg contains valid read instruction
reg ir_stb; //
wire bir_stb; //
wire bra_req; //
wire tevent; //
wire mdfy; //
wire tena; //
wire tovf; //
wire thang; //
//
reg rta_fall; //
wire rta, creq; //
wire set_cend; //
reg clr_cend; //
wire wt_state; //
reg get_state, get_sta0; //
reg acmp_te, acmp_en; //
//
wire din_set, dout_set; //
reg din_clr, dout_clr; //
wire sync_clr; //
wire rcmd_set; // set command re-fetch request
//
reg [15:0] ireg; // primary instruction register
reg [15:0] breg; // prefetch instruction register
reg [5:0] ia; // microinstuction address register
reg [2:0] ri; // interrupt acknowlegement register
reg [2:0] ix; // auxiliary conditions register
//
reg [11:0] br; // branch processing matrix input register
reg [15:0] qr; // interrupt processing matrix input register
wire [9:0] pli; // interrupt priority encode matrix output
wire [11:0] pld; // preliminary instruction decoder matrix output
wire plb; // branch processing matrix output
//
reg na0r, na1w; //
reg [5:0] na; // microcode next address field
reg [30:0] plm; // main matrix result register (first stage)
reg [30:8] plm_wt; //
wire [30:8] plr; //
wire [36:0] pla; //
//
reg [4:0] plm_rn; //
wire [6:0] rn_wa; //
wire pc2_wa; //
wire pc2_was; //
wire [6:0] rn_ry; //
wire [6:0] rn_rx; //
wire [7:0] wa; //
wire [5:0] cn_rd; //
wire cn_ry0, cn_ry1; //
wire wa_gpr; //
wire wa_reg; //
wire wa_r1, wa_r2; //
wire rd_reg; //
wire ra_wa; // write address register from ax-bus
wire ra_wx; // write address register from x-bus
reg ra_fw; //
wire ra_fwn; //
wire ra_fr, ra_fr1; //
reg ra_fr2; //
wire rx_gpr, ry_gpr; //
wire rx_reg, ry_reg; //
wire pc1_rx, pc1_ry; //
wire pc2_rx, pc_ry; //
wire pc1_wr, pc_wax; //
wire pc_wr; //
wire brd_rx, brd_ry; //
wire acc_rx, acc_ry; //
wire rs_wa, acc_wa; //
wire rs_rx, rs_ry; //
wire ra_ry; //
wire bir_ry; //
wire cpsw_wa, cpsw_ry; //
wire cpsw_stb; //
wire ea1_wa, ea2_wa; //
wire ea1_rx, ea1_ry; //
wire ea2_rx, ea2_ry; //
wire ea_ctld; //
wire pswt_wa; //
wire psw_wa, psw8_wa; //
wire psw_rx, psw_ry; //
wire psw_stb, pswc_stb; //
wire wr_psw; //
wire brd_rql, brd_rqh; //
wire qd_swap; //
wire qswp, rd2h; //
reg qa0; //
reg wr7; //
//
wire [15:0] const0[5:0]; //
wire [15:0] const1[5:0]; //
//
reg [15:0] ea22; // extended arithmetics register
reg [15:0] ear1; // extended arithmetics register
reg [15:0] ear2; // extended arithmetics register
reg [15:0] acc; // accumulator
reg [15:0] sreg; // source register
reg [15:0] r[6:0]; // general purpose register files
reg [15:0] pc2; //
reg [15:0] pc1; //
reg [15:0] pc; //
reg [8:0] psw; //
reg [8:0] cpsw; // PSW copy
reg [15:0] qreg; // ALU Q register (Q-bus data)
reg [15:0] areg; // ALU A register (Q-bus address)
//
wire [15:0] alu_inx; // ALU X operand selector
wire [15:0] alu_iny; // ALU Y operand selector
wire [15:0] alu_an; // ALU operands 'and'
wire [15:0] alu_or; // ALU operands 'or'
wire [15:0] alu_cf; // ALU carry
wire [15:0] alu_cp; //
wire [15:0] alu_af; // ALU function
wire [15:0] alu_sh; //
reg [15:0] alu_fr; // ALU function register
reg [15:0] alu_cr; // ALU carry register
reg [15:0] xb; // ALU result register
wire [15:0] xbo; //
wire [15:0] x, ax; // ALU X (input) and X* (output) bus
wire [15:0] y, ay; // ALU Y (input) and Y* (output) bus
//
wire alu_cin; //
wire alu_a, alu_b; // ALU function controls
wire alu_c, alu_d; //
wire alu_e, alu_f; //
wire alu_g, alu_h; //
wire rshift, lshift, nshift; // ALU shifter controls
wire sh_ci1, sh_ci2, sh_ci3; //
wire alu_xb; //
//
wire sf_sum; //
reg sf_inv, sf_dir; //
reg sf_lr, sf_rr; //
reg sf_sub; //
reg sf_byte; //
reg sf_xchg; //
reg sxt_y; //
wire sxt_rxy; //
wire axy_wh; //
wire adr_eq; //
//
wire zl, zh, eq1; //
wire ea_22z; //
reg ea_20r; //
//
wire cond_c0; //
wire cond_c1; //
wire cond_c2; //
//
wire cond_c; //
wire cond_v; //
wire cond_z; //
wire cond_n; //
//
wire plm1m; //
wire plm13m; //
wire plm14m; //
wire plm18m; //
wire plm19m; //
wire plm20m; //
//
wire en_alu; //
wire en_rd; //
wire mc_drdy; //
reg mc_drdy0, mc_drdy1; //
reg [5:0] alu_st; // ALU state machine
reg [5:0] iocmd_st; //
reg [1:0] iopc_st; //
reg [5:0] io_st; //
reg buf_res; //
reg pc2_res; // ignore pc2 write
wire wr1, wr2; //
wire rd1, rd2; //
wire salu; //
wire rd_end; //
wire ad_rd; // external AD pins read enable
wire alu_wr; // ALU write result
wire brd_wq; // buffer data register write from Q-bus
wire brd_wa; // buffer data register write from ALU
wire to_clr; // not assert internal to_rply
//
wire pli_req; // interrupt module query
wire pli_ack; // interrupt module ack
wire pli_rclr; //
wire sd_word; //
reg word27; //
reg sm0, sm1, sm2, sm3; // interrupt module strobes
reg pli6r; //
reg pli8r; //
wire evnt_ack; //
wire aclo_ack; //
wire tovf_ack; //
wire [5:0] vsel; //
reg [3:0] vec; //
reg wcpu; //
reg tbit; //
wire tbit_req; //
wire rt_req; //
//
reg dc_b7; //
wire dc_f2; //
wire dc_f8; //
wire dc_i7; //
wire dc_j7; //
wire dc_bi; //
wire dc_fl; //
wire dc_aux; //
reg dc_i9; //
reg dc_i10; //
reg dc_fb; //
reg dc_rtt; //
reg dc_mop0; //
reg dc_mop1; //
wire alt_cnst; //
//
wire ea_nrdy; //
wire ea_shr; //
wire ea_vdiv; //
wire ea_mxin; //
reg ea_mxinr; //
wire ea_muls; //
wire sh_cin; //
wire [15:0] ea_mux; //
wire [4:1] ea_px; //
reg [4:0] ea_ct; //
reg [4:0] ea_cb; //
wire [4:0] ea_cts; //
reg ea_1t; //
reg ea_1tm; //
wire ea_sh2; //
wire ea_shl; //
wire ea_shr2; //
wire ea_div; //
wire ea_mul; //
wire ea_mop0, ea_mop1; //
wire ea_rdy; //
reg ea_trdy0, ea_trdy1; //
wire ea_trdy0_set; //
wire ea_trdy0_clr; //
wire ea_trdy1_clr; //
//
reg tlz; //
reg wait_vdiv; //
reg wait_div; //
reg zero_div; //
//
wire [20:0] ea_f; //
reg ea_f0r, ea_f4r; //
reg ea_fn23r; //
wire ea_fn12; //
wire ea_f218; //
wire ea_enact, ea_ctse; //
//
wire eas_dir; //
wire eas_left; //
wire eas_right; //
//
wire [7:0] rx; //
wire [7:0] ry; //
//
reg bra; //
reg sb0, sb1; //
wire clr_wsta; //
wire ws_cend, ws_wait; //
//
reg [8:0] qct_ta; //
reg [8:0] qct_tb; //
wire [8:0] qct_ck; //
wire tinit; //
wire tout; //
//
//______________________________________________________________________________
//
reg br_cmdrq; // breg read cmd request
wire to_block; // block timeout false reply
wire wra;
wire wtbt, to_rply;
//______________________________________________________________________________
//
// Removed aliases (inherited from schematics)
//
// reg sd1;
// wire nrs;
// wire ea_nin;
// wire ea_cin;
//
// assign nrs = acc[15];
// assign ea_cin = alu_cr[15];
// assign ea_nin = alu_fr[15];
//
// always @(*)
// begin
// if (~bra_req & ~ir_stb)
// sd1 <= 1'b0;
// else
// if (~f2 & bra_req)
// sd1 <= 1'b1;
// end
//
//______________________________________________________________________________
//
assign pin_ad_out = ad;
assign pin_ad_ena = ad_oe;
assign pin_init = init;
assign pin_dmgo = dmgo_out;
assign pin_wrq = wrq;
assign pin_sel = sel;
assign pin_iako = iako;
assign pin_ctrl_ena = ct_oe;
assign pin_sync = sync;
assign pin_wtbt = wtbt_out;
assign pin_dout = dout;
assign pin_din = din;
//______________________________________________________________________________
//
// Reset and phase clock generator
//
assign pin_clko = ~f1;
always @(negedge pin_clk)
begin
dclo <= pin_dclo;
f1 <= ~f2;
end
always @(posedge pin_clk)
begin
if (dclo) // this code provides
f2 <= 1'b0; // correct phase relation
else // f2 starts after f1
f2 <= f1;
end
assign init = init_out | dclo;
always @(*)
begin
if (reset | tout)
init_out <= 1'b0;
else
if (pi_stb & plm[13])
init_out <= 1'b1;
end
always @(*)
begin
if (f1) aclo <= pin_aclo;
if (reset)
ac0 <= 1'b0;
else
if (sm2)
ac0 <= pli[3];
end
assign reset = dclo | (~ac0 & aclo_stb);
assign mc_res = abort | reset;
//______________________________________________________________________________
//
// Interrupt inputs
//
always @(*)
begin
//
// This is strange behaviour:
// INIT does not reset EVNT if latch is active
//
if (~pli_req)
evnt <= pin_evnt;
else
if (init) evnt <= 1'b0;
if (~pli_req) halt <= pin_halt;
if (~pli_req) virq <= pin_virq;
if (~((ac0 & pli_req) | (~ac0 & f1))) aclo_stb <= aclo;
end
//______________________________________________________________________________
//
always @(negedge f1) dmr <= pin_dmr;
always @(*) if (f1) waki <= pin_waki;
always @(*) if (f1) dmgo_out <= dmgo;
assign sel_alt = psw[8] ^ io_alt;
assign sel = (sel2 & bus_adr) | sel1;
assign sel1 = iop_sel & din;
always @(*)
begin
if (wra)
sel2 <= sel_alt;
else
if (mc_res)
sel2 <= 1'b1;
end
//
// Window access request 160000..163777
//
assign win_req = wra & (~ax[11] | (~rd2 & ~x[11]))
& (~ax[12] | (~rd2 & ~x[12]))
& ( ay[13] | (~rd2 & x[13]))
& ( ay[14] | (~rd2 & x[14]))
& ( ay[15] | (~rd2 & x[15]));
always @(*)
begin
if (mc_res)
wrq <= 1'b0;
else
if (~f1 & waki)
wrq <= 1'b0;
else
if (win_req & ~waki)
wrq <= 1'b1;
end
//______________________________________________________________________________
//
// Internal multiplexed address/data bus
//
assign ad = (ad_rd ? pin_ad_in : 16'o000000)
| (bus_adr ? areg : 16'o000000)
| (brd_rql ? {8'o000, qreg[7:0]} : 16'o000000)
| (brd_rqh ? {qreg[15:8], 8'o000} : 16'o000000);
always @(*)
begin
if (din | sack)
ad_oe <= 1'b0;
else
if (~din & ~sack & ~f1)
ad_oe <= 1'b1;
end
always @(*)
begin
if (sack)
ct_oe <= 1'b0;
else
if (~f1 & ~sack & bfree)
ct_oe <= 1'b1;
end
//______________________________________________________________________________
//
// QBus state machine
//
assign ar = pin_ar;
assign sack = pin_sack;
assign iako = iop_iak & din & iako_out;
always @(negedge f1) iako_out <= iop_iak & din;
always @(*)
begin
if (iako_out)
vec_stb <= 1'b1;
else
if (f1 & ~iako_out)
vec_stb <= 1'b0;
end
assign wtbt_out = (bus_adr & wtbt) | (bus_dat & ~iop_word);
always @(*)
begin
if (mc_res | din_clr | ~ct_oe)
din <= 1'b0;
else
if (din_set)
din <= 1'b1;
end
always @(*)
begin
if (mc_res)
dout_s0 <= 1'b0;
else
if (~f1 & dout_clr)
dout_s0 <= 1'b0;
else
if (~f1 & dout_set)
dout_s0 <= 1'b1;
if (~dout_s0)
dout <= 1'b0;
else
if (f1 & ~mc_res)
dout <= 1'b1;
end
assign rta = sync & ~ardy;
assign creq = sync_s0 | adr_req;
assign dmgo = dmr & ~ct_oe & ~sync_s0 & ~in_ua;
assign bus_free = bfree & ~dmr & ct_oe;
assign bus_adr = (~sync | ~ardy_s0) & (sync_s0 | sync_set);
assign brd_rqh = bus_dat & (iop_word | qa0);
assign brd_rql = bus_dat & (iop_word | ~qa0);
assign qd_swap = qa0;
always @(*)
begin
if (rta | mc_res)
rta_fall <= 1'b0;
else
if (wra)
rta_fall <= 1'b1;
end
always @(*)
begin
if (sync_clr)
qa0 <= 1'b0;
else
if (bus_adr)
qa0 <= ad[0] & ~iop_word;
end
always @(*)
begin
if (mc_res)
bus_dat <= 1'b0;
else
if (f1 & dout_clr)
bus_dat <= 1'b0;
else
if (f1 & (~rply & ardy & drdy & (wtbt | dout_clr)))
bus_dat <= 1'b1;
end
assign sync_set = bus_free & adr_req & ~wrq;
assign sync_clw = (wtbt | dout_clr) & sync_clr;
assign sync_clr = mc_res | (~iop_wr & ~rply3 & rply2);
always @(*)
begin
if (~ct_oe | sync_clr)
sync_s0 <= 1'b0;
else
if (f1 & sync_set)
sync_s0 <= 1'b1;
if (~f1)
sync <= sync_s0;
end
always @(*)
begin
if (f1 & ~sync)
ardy_s0 <= 1'b0;
else
if (f1 & sync & ar)
ardy_s0 <= 1'b1;
if (~f1)
ardy <= ardy_s0;
end
always @(*)
begin
if (mc_res | to_block | (sync & ~ardy_s0))
adr_req <= 1'b0;
else
if (wra)
adr_req <= 1'b1;
end
assign to_rply = ~to_clr & ~word27 & tevent & io_qto;
assign ua_rply = (din | dout) & sel1;
always @(*)
begin
if (~f1)
rply <= pin_rply | to_rply | ua_rply;
if (~f1)
bfree <= ~sync & ~ar & (ardy | ~rply);
end
assign rdat = iop_rd & rply0 & ~rply2;
assign rplys = ~in_ua & (~sync_s0 | ~ardy_s0);
assign in_ua = (iop_sel | iop_iak) & (din | (~adr_req & bus_free));
assign io_iak = plr[24] & plr[23] & plr[22] & plr[21];
assign io_sel = plr[24] & ~io_iak & ~io_x001 & plr[21];
assign io_alt = ~plr[24] & ~io_rcd & ~io_x001 & plr[21];
assign io_wr = (io_x001 & ~dc_mop1) | (~io_rcd & ~io_iak & plr[23]);
assign io_rd = (io_x001 & ~dc_mop0) | plr[22];
assign io_in = io_rcd | (io_rd & ~io_cmd);
assign io_cmd = ~plr[24] & & plr[22] & ~plr[21];
assign io_rcd = ~plr[24] & plr[23] & plr[22] & plr[21];
assign io_rcd1 = ra_fr2 & na1w;
assign io_x001 = ~plr[23] & ~plr[22] & plr[21];
assign dout_set = ~dout_clr & bus_dat;
assign din_set = ~din_clr & iop_rd & ~rplys & ~rply3;
assign wtbt = ~din_clr & ~iop_rd & iop_wr;
always @(*)
begin
if (dout_clr)
iop_wr <= 1'b0;
else
if (iop_stb)
iop_wr <= io_wr;
if (din_clr)
iop_rd <= 1'b0;
else
if (iop_stb)
iop_rd <= io_rd;
if (iop_stb)
iop_word <= ~dc_fb | ~plr[30];
if (mw_stb)
iop_una = io_iak | io_sel;
if (sync_clr)
begin
iop_iak <= 1'b0;
iop_sel <= 1'b0;
end
else
if (iop_stb)
begin
iop_iak <= io_iak;
iop_sel <= io_sel;
end
end
always @(*)
begin
if (rply3 | ~rply1)
dout_clr <= 1'b0;
else
if (wtbt)
dout_clr <= 1'b1;
if (rply3 | ~rply2 | rdat)
din_clr <= 1'b0;
else
if (iop_rd)
din_clr <= 1'b1;
end
always @(*)
begin
if (rply3)
rply0 <= 1'b0;
else
if (f1)
rply0 <= rply & ~rplys;
if (~f1) rply1 <= rply0;
if (~f1) rply3 <= rply2;
if (f1)
if (rply1)
rply2 <= 1'b1;
else
if (~rply & ~rply1)
rply2 <= 1'b0;
end
always @(*)
begin
if (sync_clr)
drdy <= 1'b0;
else
if (brd_wa)
drdy <= 1'b1;
end
//______________________________________________________________________________
//
// Q-bus timer, also involved in INIT command pulse timing
//
assign qct_ck[0] = tena & ~f1;
assign qct_ck[1] = tena & qct_ta[0];
assign qct_ck[2] = qct_ck[1] & qct_tb[1];
assign qct_ck[3] = qct_ck[2] & qct_tb[2];
assign qct_ck[4] = qct_ck[3] & qct_tb[3];
assign qct_ck[5] = qct_ck[4] & qct_tb[4];
assign qct_ck[6] = qct_ck[5] & qct_tb[5];
assign qct_ck[7] = qct_ck[6] & qct_tb[6];
assign qct_ck[8] = qct_ck[7] & qct_tb[7];
assign tout = qct_ta[0] & qct_tb[2] & qct_tb[4] & qct_tb[5];
assign tinit = qct_tb[8] & qct_ck[8];
always @(*)
begin
if (!tena)
begin
qct_ta <= 9'o000;
qct_tb <= 9'o000;
end
else
begin
if (qct_ck[0]) qct_ta[0] <= ~qct_tb[0];
if (qct_ck[1]) qct_ta[1] <= ~qct_tb[1];
if (qct_ck[2]) qct_ta[2] <= ~qct_tb[2];
if (qct_ck[3]) qct_ta[3] <= ~qct_tb[3];
if (qct_ck[4]) qct_ta[4] <= ~qct_tb[4];
if (qct_ck[5]) qct_ta[5] <= ~qct_tb[5];
if (qct_ck[6]) qct_ta[6] <= ~qct_tb[6];
if (qct_ck[7]) qct_ta[7] <= ~qct_tb[7];
if (qct_ck[8]) qct_ta[8] <= ~qct_tb[8];
if (~qct_ck[0]) qct_tb[0] <= qct_ta[0];
if (~qct_ck[1]) qct_tb[1] <= qct_ta[1];
if (~qct_ck[2]) qct_tb[2] <= qct_ta[2];
if (~qct_ck[3]) qct_tb[3] <= qct_ta[3];
if (~qct_ck[4]) qct_tb[4] <= qct_ta[4];
if (~qct_ck[5]) qct_tb[5] <= qct_ta[5];
if (~qct_ck[6]) qct_tb[6] <= qct_ta[6];
if (~qct_ck[7]) qct_tb[7] <= qct_ta[7];
if (~qct_ck[8]) qct_tb[8] <= qct_ta[8];
end
end
//______________________________________________________________________________
//
assign adr_eq = ~acmp_en | (pc1 == areg);
assign mdfy = acmp_en & ~acmp_te & adr_eq;
always @(*)
begin
if (alu_wr) io_rcdr <= io_rcd;
if (alu_wr) io_cmdr <= io_cmd;
if (reset)
acmp_te <= 1'b0;
else
if (~f1 & acmp_en)
acmp_te <= 1'b0;
else
if (~f1 & wra & io_wr)
acmp_te <= 1'b1;
if (f1) acmp_en <= acmp_te;
if (reset | sync_clw)
io_pswr <= 1'b0;
else
if (wra & io_wr & ~na0r)
io_pswr <= 1'b1;
end
//______________________________________________________________________________
//
// Instruction registers - primary and preliminary decoder
//
always @(*)
begin
if (bir_stb) breg <= ad;
if ( ir_stb) ireg <= breg;
end
vm2_pld pld_matrix(.rq(breg), .sp(pld));
assign dc_f2 = ir_stb
& (breg[11:9] != 3'b000)
& ((breg[8:6] == 3'b111) | (breg[11:10] == 2'b11));
assign dc_j7 = ir_stb
& (breg[8:6] == 3'b111)
& (breg[14:12] != 3'b000);
assign dc_i7 = ~ir_stb | (breg[2:0] == 3'b111);
assign dc_bi = pld[5];
assign dc_f8 = ir_stb & psw[8];
assign dc_fl = ~dc_fb & ((ir_stb & dc_bi) | (~dc_mop0 & dc_mop1));
assign dc_aux = dc_j7 | bra | br_cmdrq;
assign alt_cnst = (~dc_fb & plm[30]) | (dc_fb & plm[30] & plm[5] & plm[6]);
always @(*)
begin
if (ir_stb)
begin
dc_fb <= ~pld[10];
dc_mop0 <= ~pld[4];
dc_mop1 <= ~pld[3];
dc_rtt <= ~pld[2];
dc_i9 <= br[1];
dc_i10 <= br[2];
end
if (wr2) dc_b7 <= (ay[15:13] == 3'b111);
end
always @(*)
begin
if (io_cmdr)
br_cmdrq <= 1'b0;
else
if (rcmd_set)
br_cmdrq <= 1'b1;
end
//______________________________________________________________________________
//
// Main microcode state machine
//
assign mc_stb = all_rdy_t0 & all_rdy_t1;
assign pi_stb = ~plm[0] & ~all_rdy_t0 & all_rdy_t1;
assign all_rdy = ~mc_res & ~alu_nrdy & ~sta_nrdy & ~pli_nrdy & ~cmd_nrdy & ~all_rdy_t1;
always @(*)
begin
if (mc_res)
all_rdy_t0 <= 1'b0;
else
if (f1)
begin
if (all_rdy)
all_rdy_t0 <= 1'b1;
else
if (all_rdy_t1)
all_rdy_t0 <= 1'b0;
end
if (~f1)
all_rdy_t1 <= all_rdy_t0;
end
always @(*)
begin
if (mc_res | clr_wsta)
sta_nrdy <= 1'b0;
else
if (wt_state)
sta_nrdy <= 1'b1;
end