-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtop.sv
More file actions
1065 lines (978 loc) · 77 KB
/
top.sv
File metadata and controls
1065 lines (978 loc) · 77 KB
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
/******************************************************************************
* Engineer: Agner Fog
*
* Create date: 2020-05-03
* Last modified: 2022-01-01
* Module name: top
* Project name: ForwardCom soft core
* Tool versions: Vivado 2020.1
* License: CERN-OHL-W version 2 or later
* Description: Top level module of ForwardCom softcore
* Softcore version A1.01, ForwardCom standard version 1.12
*
* The pipeline stages are connected here:
* 1. fetch: Fetch code words from code memory
* 2. decoder Decode instruction code
* 3. register_read Read registers. The register file is included in this stage
* 4. addressgenerator Calculate address of any memory operand
* 5. dataread Wait for data being read from data RAM
* 6a. alu Execute the instruction and calculate the result
* 6b. in_out_ports Input and output instructions etc. go here instead of into alu
*
* Other modules connected here:
* clock_generator: Controls the clock frequency of the global clock
* code_memory: Code memory or cache
* data_memory: Data memory or cache
* call_stack: Call stack for function return addresses
* debug_display: Shows contents of each pipeline stage on LCD display
* debugger.vh: Displays values of any signals anywhere in system on LED displays
*
******************************************************************************/
`include "defines.vh"
/*
Signals have name prefixes indicating the modules that generate them.
Handshaking signals between pipeline stages:
valid_in: Preceding stage has valid data ready
valid_out: Valid data are ready for next stage
stall_in: Keep your data for the next clock cycle
stall_out: Unable to receive new data
stall_predict_out: Predict that the next stage in pipeline will stall in next clock cycle
There is currently no contention for result buses, but future implementation may need handshaking for this:
result_bus_require_out: Needs result bus in next clock cycle
result_bus_acknowledge_in: No unit with higher privilege is taking the result bus
result_bus_enable_out: A result is on the result bus
*/
module top (
input clock100, // board input clock 100 MHz
input switch0, // switches for debug modes
input switch1, // switches for debug modes
input switch2, // switches for debug modes
input switch3, // switches for debug modes
input switch4, // switches for debug modes
input switch5, // switches for debug modes
input switch6, // switches for debug modes
input switch7, // switches for debug modes
input switch8, // switches for debug modes
input switch15, // disables error stop
input step_button, // Single stepping (RIGHT BUTTON)
input run_button, // Stop single stepping and start free running (UP BUTTON)
input reset_button, // Reset to start of program (DOWN BUTTON)
input load_button, // Load program throung serial interfase (!CPU RESET BUTTON)
input step_button_x, // Single stepping (external button)
input run_button_x, // Stop single stepping and start free running (external button)
input reset_button_x, // Reset to start of program (external button)
input load_button_x, // Loader (external button)
input external_connected_x, // high if external debug interface is connected
input debug1_switch, // enable single-stepping, pipeline mode
input debug2_switch, // enable single-stepping, instruction mode
input uart_txd_in, // UART transmit from PC
//input uart_rts_in, // UART RTS from PC
output reg [7:0] segment7seg, // segment output, active low
output reg [7:0] digit7seg, // digit select output, active low
output reg [3:0] lcd_data, // data to LCD display
output reg lcd_rs, // control signal for LCD display
output reg [1:0] lcd_e, // enable signals for LCD displays
output uart_rxd_out, // UART receive to PC
output uart_cts_out, // UART CTS to PC
output led0, // use of led's: see below
output led1,
output led2,
output led3,
output led4,
output led5,
output led6,
output led7,
output led12,
output led13,
output led14,
output led15,
output led16R, // RGB led
output led16G,
output led16B
);
// generate clock (Xilinx specific. Generated by Clocking Wizard)
clock_generator clock_generator_inst (
.clk_in(clock100), // board input clock, 100 MHz
.clk_out(clock), // synthesized clock, frequency is `CLOCK_FREQUENCY
.locked() // clock frequency has stabilized
);
// control single stepping
reg single_step_mode;
reg step_button_debounced;
reg run_button_debounced;
reg reset_button_debounced;
reg load_button_debounced;
reg step_button_pulse;
reg run_button_pulse;
reg reset_button_pulse;
reg load_button_pulse;
reg [2:0] reset_step = 3'b111; // shift register for system reset clock cycles
reg clock_enable = 0;
reg system_reset = 1; // reset everything. load program
reg program_restart = 0; // restart loaded program
// pushbutton debouncers
// on-board buttons are always enabled, external buttons are enabled by external_connected_x
logic[3:0] input_buttons;
logic[3:0] debounced_buttons;
logic[3:0] button_pulse;
assign input_buttons[0] = step_button | (step_button_x & external_connected_x);
assign input_buttons[1] = run_button | (run_button_x & external_connected_x);
assign input_buttons[2] = reset_button | (reset_button_x & external_connected_x);
assign input_buttons[3] = (~load_button) | (load_button_x & external_connected_x);
assign debounced_buttons[0] = step_button_debounced;
assign debounced_buttons[1] = run_button_debounced;
assign debounced_buttons[2] = reset_button_debounced;
assign debounced_buttons[3] = load_button_debounced;
assign button_pulse[0] = step_button_pulse;
assign button_pulse[1] = run_button_pulse;
assign button_pulse[2] = reset_button_pulse;
assign button_pulse[3] = load_button_pulse;
debounce #(.num(4) ) debounce_inst
(.clock(clock),
.buttons_in (input_buttons),
.buttons_out(debounced_buttons),
.pulse_out(button_pulse));
/***************************************************
Signals connecting the stages
***************************************************/
// code memory
logic [`CODE_DATA_WIDTH-1:0] code_memory_data; // Data out
logic [31:0] code_memory_debug;
// data memory
logic [`RB1:0] data_memory_data;
// call stack
logic [`CODE_ADDR_WIDTH-1:0] call_stack_pop_data; // return address popped from call stack
logic call_stack_overflow; // call stack overflow or underflow or error
// register file input
logic [5:0] debug_reada; // read port for debugger
// signals from each pipeline stage
// fetch stage
logic fetch_valid;
logic fetch_jump; // jump instruction bypassing pipeline
logic fetch_call_e; // executing call instruction
logic fetch_return_e; // executing return instruction
logic [95:0] fetch_instruction;
logic [`CODE_ADDR_WIDTH-1:0] fetch_instruction_pointer; // point to current instruction
logic fetch_read_enable;
logic [`CODE_ADDR_WIDTH-2:0] fetch_read_addr; // Address for reading from code ram
logic [`CODE_ADDR_WIDTH-1:0] fetch_call_push_data; // return address pushed to call stack
logic [31:0] fetch_debug1; // temporary debug output
// decoder
logic [`TAG_WIDTH-1:0] decoder_tag_val; // instruction tag value
logic decoder_tag_write; // tag write enable
logic decoder_read; // read register enable
logic decoder_valid; // An instruction is ready for output to next stage
logic [`CODE_ADDR_WIDTH-1:0] decoder_instruction_pointer; // address of current instruction
logic [95:0] decoder_instruction; // first word of instruction
logic decoder_stall_predict; // Not ready to receive next instruction
logic [5:0] decoder_tag_a; // register number for instruction tag
logic decoder_vector; // this is a vector instruction
logic [1:0] decoder_category; // 00: multiformat, 01: single format, 10: jump
logic [1:0] decoder_format; // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
logic [2:0] decoder_rs_status; // use of RS
logic [2:0] decoder_rt_status; // use of RT
logic [1:0] decoder_ru_status; // 1: RU is used
logic [1:0] decoder_rd_status; // 1: RD is used as input
logic [1:0] decoder_mask_status; // what the mask register is used for
logic decoder_mask_options; // 1: mask register may contain options
logic decoder_mask_alternative; // mask register and fallback register used for alternative purposes
logic [2:0] decoder_fallback_use; // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
logic [1:0] decoder_num_operands; // number of source operands
logic [1:0] decoder_result_type; // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
logic [1:0] decoder_offset_field; // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
logic [1:0] decoder_immediate_field; // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
logic [1:0] decoder_scale_factor; // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
logic decoder_index_limit; // index has a limit
logic decoder_multi_finish; // Decoding multiple micro-op instruction is finishing
logic decoder_error; // wrong format or parameter detected in decoder
logic [31:0] decoder_debug1; // temporary debug output
// register read stage
logic registerread_valid; // An instruction is ready for output to next stage
logic [`CODE_ADDR_WIDTH-1:0] registerread_instruction_pointer; // address of current instruction
logic [95:0] registerread_instruction; // first word of instruction
logic registerread_stall_predict; // predict next stage will stall
logic [`TAG_WIDTH-1:0] registerread_tag_val; // instruction tag value
logic registerread_vector; // this is a vector instruction
logic [1:0] registerread_category; // 00: multiformat, 01: single format, 10: jump
logic [1:0] registerread_format; // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
logic [1:0] registerread_num_operands; // number of source operands
logic [1:0] registerread_result_type; // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
logic [1:0] registerread_offset_field; // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
logic [1:0] registerread_immediate_field; // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
logic [1:0] registerread_scale_factor; // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
logic registerread_index_limit; // The field indicated by offset_field contains a limit to the index
logic [`RB:0] registerread_rd_val; // value of register operand RD, bit `RB indicates missing
logic [`RB:0] registerread_rs_val; // value of register operand RS, bit `RB indicates missing
logic [`RB:0] registerread_rt_val; // value of register operand RT, bit `RB indicates missing
logic [`RB:0] registerread_ru_val; // value of register operand RU, bit `RB indicates missing
logic [`MASKSZ:0] registerread_mask_val; // value of mask register, bit 32 indicates missing
logic [1:0] registerread_rd_status; // RD is used as input
logic [2:0] registerread_rs_status; // use of RS
logic [2:0] registerread_rt_status; // use of RT
logic [1:0] registerread_ru_status; // RU is used
logic [1:0] registerread_mask_status; // mask register is used
logic registerread_mask_alternative; // mask register and fallback register used for alternative purposes
logic [2:0] registerread_fallback_use; // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
logic [32:0] registerread_debugport; // register read by debugger
// address generator
logic [`COMMON_ADDR_WIDTH-1:0] addrgen_read_write_address; // address of memory operand
logic addrgen_read_enable; // read from data memory
logic [1:0] addrgen_read_data_size;
logic [7:0] addrgen_write_enable;
logic [63:0] addrgen_write_data; // Any part of the 64 bits write bus can be used when the operand size is less than 64 bits
logic addrgen_valid; // An instruction is ready for output to next stage
logic [`CODE_ADDR_WIDTH-1:0] addrgen_instruction_pointer; // address of current instruction
logic [63:0] addrgen_instruction; // first word of instruction
logic addrgen_stall_next; // address generator waiting for an operand
logic addrgen_div_predict; // a division instruction is underway
logic [`TAG_WIDTH-1:0] addrgen_tag_val; // instruction tag value
logic [`RB:0] addrgen_operand1; // value of first register operand
logic [`RB:0] addrgen_operand2; // value of second register operand
logic [`RB:0] addrgen_operand3; // value of last operand
logic [`MASKSZ:0] addrgen_mask_val; // value of mask register, bit 32 indicates valid
logic addrgen_vector; // this is a vector instruction
logic [1:0] addrgen_category; // instruction category: multiformat, single format, jump
logic [1:0] addrgen_format; // instruction format: A, E, B, D
logic addrgen_mask_status; // mask register is used
logic addrgen_mask_alternative; // mask register and fallback register used for alternative purposes
logic [2:0] addrgen_fallback_use; // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
logic [1:0] addrgen_num_operands; // number of source operands
logic [1:0] addrgen_result_type; // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
logic [1:0] addrgen_offset_field; // unused
logic [1:0] addrgen_immediate_field; // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
logic [1:0] addrgen_scale_factor; // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
logic addrgen_memory_operand; // The instruction has a memory operand
logic addrgen_array_error; // Array index exceeds limit
logic [31:0] addrgen_debug1; // temporary debug output
logic [31:0] addrgen_debug2; // temporary debug output
logic [31:0] addrgen_debug3; // temporary debug output
// data read stage
logic dataread_valid; // An instruction is ready for output to next stage
logic [`CODE_ADDR_WIDTH-1:0] dataread_instruction_pointer; // address of current instruction
logic [31:0] dataread_instruction; // first word of instruction
logic dataread_stall_predict; // predict next stage will stall
logic [`TAG_WIDTH-1:0] dataread_tag_val; // instruction tag value
logic [`RB:0] dataread_operand1; // value of first operand
logic [`RB:0] dataread_operand2; // value of second operand
logic [`RB:0] dataread_operand3; // value of last operand
logic [`MASKSZ:0] dataread_mask_val; // value of mask, bit 32 is 0 if valid
logic dataread_opr2_from_ram; // value of operand 2 comes from data memory
logic dataread_opr3_from_ram; // value of last operand comes from data memory
logic dataread_vector; // this is a vector instruction
logic [1:0] dataread_category; // 00: multiformat, 01: single format, 10: jump
logic [1:0] dataread_format; // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
logic [1:0] dataread_num_operands; // number of source operands
logic dataread_opr1_used; // opr1_val_out is needed
logic dataread_opr2_used; // opr2_val_out is needed
logic dataread_opr3_used; // opr3_val_out is needed
logic dataread_mask_used; // mask_val_out is needed
logic dataread_mask_alternative; // mask register and fallback register used for alternative purposes
logic [1:0] dataread_result_type; // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
logic [3:0] dataread_exe_unit; // each bit enables a particular execution unit
// 1: ALU, 10: MUL, 100: DIV, 1000: IN/OUT
logic [6:0] dataread_opx; // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
logic [5:0] dataread_opj; // operation ID for conditional jump instructions
logic [2:0] dataread_ot; // operand type
logic [5:0] dataread_option_bits; // option bits from IM5 or mask
logic [15:0] dataread_im4_bits; // constant bits from IM4 as extra operand
logic dataread_trap; // trap instruction detected. enable single step mode
logic dataread_array_error; // array index out of bounds
logic dataread_read_address_error; // invalid read memory address
logic dataread_write_address_error; // invalid write memory address
logic dataread_misaligned_address_error; // misaligned read/write memory address
logic [31:0] dataread_debug; // output for debugging
// alu stage
logic alu_valid; // for debug display: alu is active
logic alu_write_en; // write value to register file
logic [5:0] alu_register_a; // register to write
logic [`RB1:0] alu_result; // result to write
logic [`TAG_WIDTH-1:0] alu_tag; // instruction tag value
logic alu_jump; // jump instruction: jump taken
logic alu_nojump; // jump instruction: jump not taken
logic [`CODE_ADDR_WIDTH-1:0] alu_jump_pointer; // jump target to fetch unit
logic alu_stall;
logic alu_stall_next;
logic alu_error; // unknown instruction
logic alu_error_parm; // wrong parameter for instruction
logic [31:0] alu_debug1; // output for debugger
logic [31:0] alu_debug2; // output for debugger
// mul/div alu
logic muldiv_valid; // for debug display: alu is active
logic muldiv_write_en; // write value to register file
logic [4:0] muldiv_register_a; // register to write
logic [`RB1:0] muldiv_result; // result to write
logic [`TAG_WIDTH-1:0] muldiv_tag; // instruction tag value
logic muldiv_divout; // muldiv output is division result
logic muldiv_stall; // division stall
logic muldiv_stall_next; // division stall predicted next
logic muldiv_error; // unknown instruction
logic muldiv_error_parm; // wrong parameter for instruction
logic [31:0] muldiv_debug1; // output for debugger
logic [31:0] muldiv_debug2; // output for debugger
logic [31:0] muldiv_debug3; // output for debugger
// in_out_ports
logic inout_valid; // for debug display: in_out is active
logic inout_write_en; // write value to register file
logic [5:0] inout_register_a; // register to write
logic [`RB1:0] inout_result; // result to write
logic [`TAG_WIDTH-1:0] inout_tag; // instruction tag value
logic inout_nojump; // serializing instruction read_perf gives jump not taken signal to resume pipeline
logic inout_stall;
logic inout_stall_next;
logic inout_error; // unknown instruction
logic inout_error_parm; // wrong parameter for instruction
logic [`N_ERROR_TYPES-1:0] inout_capab_disable_errors; // capab2 register: disable errors
logic [3:0] inout_first_error; // error type for first error, stored in inout module
logic [`CODE_ADDR_WIDTH-1:0] inout_first_error_address; // code address of first error
logic [31:0] inout_debug; // output for debugger
// error handling
logic [`N_ERROR_TYPES-1:0] errors_detect; // one bit for each type of error detected
logic clear_error; // clear error on debug display
reg show_error; // show error on debug display
/***************************************************
Top level logic signals
***************************************************/
// result bus 1
logic bus1_write_en; // write value to register file
logic [5:0] bus1_register_a; // register to write (includes system registers)
logic [`RB1:0] bus1_value; // value to write
logic [`TAG_WIDTH-1:0] bus1_tag; // result tag for value on bus 1
// result bus 2
logic bus2_write_en; // write value to register file
logic [4:0] bus2_register_a; // register to write
logic [`RB1:0] bus2_value; // value to write
logic [`TAG_WIDTH-1:0] bus2_tag; // result tag for value on bus 2
// signals for predicting when a result will be available
logic [`TAG_WIDTH-1:0] predict_tag1; // result tag value on bus 1 in next clock cycle
logic [`TAG_WIDTH-1:0] predict_tag2; // result tag value on bus 2 in next clock cycle
logic [`CODE_ADDR_WIDTH-2:0] code_read_addr; // Address for reading from ram
reg [2:0] color_led16; // RGB led
always_comb begin
// result bus 1
// There are no tri-state buffers inside the FPGA so we have to simulate the buses by OR'ing results:
bus1_write_en = alu_write_en | inout_write_en; // write value to register file
bus1_register_a = alu_register_a | inout_register_a; // register to write
bus1_value = alu_result | inout_result; // value to write
bus1_tag = alu_tag | inout_tag; // tag for result on bus 1
// result bus 2 not yet used
bus2_write_en = muldiv_write_en; // write value to register file
bus2_register_a = muldiv_register_a; // register to write
bus2_value = muldiv_result; // value to write
bus2_tag = muldiv_tag; // tag for result on bus 2
// read address for code memory. comes from fetch unit, except for taken conditional or indirect jumps/calls
code_read_addr = alu_jump ? (alu_jump_pointer >> 1) : fetch_read_addr;
// predict next tag on bus 1
predict_tag1 = (dataread_exe_unit[0] | dataread_exe_unit[3]) ? dataread_tag_val : 0;
// error detection
errors_detect[0] = alu_error | muldiv_error | inout_error; // unknown instruction
errors_detect[1] = decoder_error | alu_error_parm | muldiv_error_parm | inout_error_parm | call_stack_overflow; // wrong parameter for instruction
errors_detect[2] = dataread_array_error; // array index out of bounds
errors_detect[3] = dataread_read_address_error; // read address violation
errors_detect[4] = dataread_write_address_error; // write address violation
errors_detect[5] = dataread_misaligned_address_error; // misaligned memory address
clear_error = reset_button_debounced | step_button_pulse | run_button_pulse | load_button_debounced; // clear error on debug display
end
// single step and reset control
always_ff @(posedge clock) begin
reset_step[2:0] <= {reset_step[1:0],(reset_button_debounced|load_button_debounced)}; // shift register delaying reset button
if (reset_button_debounced) begin
clock_enable <= 1; // enable clock while resetting
system_reset <= 1; // reset everything for 3 clock cycles
program_restart <= 1;
single_step_mode <= 0;
end else if (load_button_debounced) begin
clock_enable <= 1; // enable clock while resetting
system_reset <= 1; // reset everything for 3 clock cycles
program_restart <= 0;
single_step_mode <= 0;
end else if (reset_step != 0) begin
clock_enable <= 1; // enable clock while resetting
system_reset <= 1; // reset everything for 3 clock cycles
single_step_mode <= 0; // start in single step mode
end else if (single_step_mode) begin // single-stepping for debugging
clock_enable <= step_button_pulse; // enable for one clock cycle
system_reset <= 0;
program_restart <= 0;
end else begin // not single_step_mode
clock_enable <= 1;
system_reset <= 0;
program_restart <= 0;
end
// set or clear single step mode
if (run_button_pulse) single_step_mode <= 0;
if (step_button_pulse) single_step_mode <= 1;
if (dataread_trap) single_step_mode <= 1; // breakpoint sets single step mode
if (|(errors_detect & ~inout_capab_disable_errors) & !switch15) single_step_mode <= 1; // error detected
if (clear_error) show_error <= 0;
if (|(errors_detect & ~inout_capab_disable_errors)) show_error <= 1;
end
/***************************************************
Memory modules
***************************************************/
// code memory
code_memory code_memory_inst(
.clock(clock), // clock
.clock_enable(clock_enable),
.read_enable(fetch_read_enable | alu_jump), // read enable
.write_enable(addrgen_write_enable),
.write_addr_in(addrgen_read_write_address),
.write_data_in(addrgen_write_data), // Data in
.read_addr_in(code_read_addr), // Address for reading from code ram
.data_out(code_memory_data), // Data out
.debug_out(code_memory_debug)
);
// read/write data memory
data_memory data_memory_inst (
.clock(clock), // clock
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.read_write_addr(addrgen_read_write_address), // Address for reading from ram
.read_enable(addrgen_read_enable), // read enable
.read_data_size(addrgen_read_data_size),
.write_enable(addrgen_write_enable), // write enable for each byte separately
.write_data_in(addrgen_write_data),
.read_data_out(data_memory_data) // Data out
);
// call stack
call_stack call_stack_instance(
.clock(clock), // clock
.clock_enable(clock_enable), // clock enable
.reset(system_reset), // reset
.call_e(fetch_call_e), // Executing call instruction
.return_e(fetch_return_e), // Executing return instruction
.push_data(fetch_call_push_data), // Return address pushed at call instruction
.pop_data(call_stack_pop_data), // Return address popped at return instruction
.overflow(call_stack_overflow)); // stack overflow or underflow or error
/***************************************************
Pipeline stages
***************************************************/
// code fetch module
fetch fetch_inst(
.clock(clock), // system clock (100 MHz)
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.reset(system_reset), // system reset.
.restart(program_restart), // restart loaded program
.valid_in(1), // data from code memory ready
.stall_in(decoder_stall_predict | registerread_stall_predict | addrgen_stall_next | dataread_stall_predict | alu_stall_next | muldiv_stall_next | inout_stall_next), // pipeline is stalled
.jump_in(alu_jump), // a jump target is coming from the ALU.
.nojump_in(alu_nojump | inout_nojump | decoder_multi_finish), // jump target is next instruction
.jump_pointer(alu_jump_pointer), // jump target from ALU. jump_pointer is also sent to the code memory
.read_data(code_memory_data), // data from code memory
.return_pop_data(call_stack_pop_data), // Return address popped here at return instruction
.read_addr_out(fetch_read_addr), // code read address relative to code memory start
.read_enable_out(fetch_read_enable), // code memory read enable
.valid_out(fetch_valid), // An instruction is ready for output to decoder
.jump_out(fetch_jump), // Jump instruction bypassing pipeline
.instruction_pointer_out(fetch_instruction_pointer), // address of current instruction
.instruction_out(fetch_instruction), // current instruction, up to 3 32-bit words long
.call_e_out(fetch_call_e), // Executing call instruction. push_data contains return address
.return_e_out(fetch_return_e), // Executing return instruction. return address is available in advance on pop_data
.stall_predict_out(), // predict stall in decoder
.call_push_data_out(fetch_call_push_data) , // Return address pushed here at call instruction
.debug1_out(fetch_debug1) // temporary debug output
);
decoder decoder_inst (
.clock(clock), // system clock (100 MHz)
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.reset(system_reset), // system reset.
.valid_in(fetch_valid), // data from fetch module ready
.stall_in(decoder_stall_predict | registerread_stall_predict | addrgen_stall_next | dataread_stall_predict | alu_stall_next | muldiv_stall_next | inout_stall_next), // pipeline is stalled
.instruction_pointer_in(fetch_inst.instruction_pointer_out), // address of current instruction
.instruction_in(fetch_instruction), // current instruction, up to 3 words long
.write_en1(bus1_write_en), // a result is written to bus 1
.write_tag1(bus1_tag), // tag of result in bus 1
.write_en2(bus2_write_en), // a result is written to bus 2
.write_tag2(bus2_tag), // tag of result in bus 2
.valid_out(decoder_valid), // An instruction is ready for output to next stage
.instruction_pointer_out(decoder_instruction_pointer), // address of current instruction
.instruction_out(decoder_instruction), // first word of instruction
.stall_predict_out(decoder_stall_predict), // Not ready to receive next instruction
.tag_a_out(decoder_tag_a), // register number for instruction tag
.tag_val_out(decoder_tag_val), // instruction tag value
.tag_write_out(decoder_tag_write), // instruction tag write enable
.vector_out(decoder_vector), // this is a vector instruction
.category_out(decoder_category), // 00: multiformat, 01: single format, 10: jump
.format_out(decoder_format), // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
.rs_status_out(decoder_rs_status), // use of RS
.rt_status_out(decoder_rt_status), // use of RT
.ru_status_out(decoder_ru_status), // 1: RU is used
.rd_status_out(decoder_rd_status), // 1: RD is used as input
.mask_status_out(decoder_mask_status), // What the mask register is used for
.mask_options_out(decoder_mask_options), // 1: mask register may contain options
.mask_alternative_out(decoder_mask_alternative), // mask register and fallback register used for alternative purposes
.fallback_use_out(decoder_fallback_use), // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
.num_operands_out(decoder_num_operands), // number of source operands
.result_type_out(decoder_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
.offset_field_out(decoder_offset_field), // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
.immediate_field_out(decoder_immediate_field), // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
.scale_factor_out(decoder_scale_factor), // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
.index_limit_out(decoder_index_limit), // The field indicated by offset_field contains a limit to the index
.multi_finish_out(decoder_multi_finish), // Decoding multiple micro-op instruction is finishing
.error_out(decoder_error), // wrong format or parameter detected in decoder
.debug1_out(decoder_debug1) // temporary debug output
);
register_read register_read_inst (
.clock(clock), // system clock
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.reset(system_reset), // system reset.
.valid_in(decoder_valid), // data from fetch module ready
.stall_in(decoder_stall_predict | registerread_stall_predict | addrgen_stall_next | dataread_stall_predict | alu_stall_next | muldiv_stall_next | inout_stall_next), // pipeline is stalled
.instruction_pointer_in(decoder_instruction_pointer), // address of current instruction
.instruction_in(decoder_instruction), // current instruction, up to 3 words long
.tag_write_in(decoder_tag_write), // write tag
.tag_val_in(decoder_tag_val), // instruction tag value
.vector_in(decoder_vector), // this is a vector instruction
.category_in(decoder_category), // 00: multiformat, 01: single format, 10: jump
.format_in(decoder_format), // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
.rs_status_in(decoder_rs_status), // 1: RS is register operand
.rt_status_in(decoder_rt_status), // 1: RT is register operand
.ru_status_in(decoder_ru_status), // 1: RU is used
.rd_status_in(decoder_rd_status), // 1: RD is used as input
.mask_status_in(decoder_mask_status), // use of mask
.mask_options_in(decoder_mask_options), // 1: mask register may contain options
.mask_alternative_in(decoder_mask_alternative), // mask register and fallback register used for alternative purposes
.fallback_use_in(decoder_fallback_use), // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
.num_operands_in(decoder_num_operands), // number of source operands
.result_type_in(decoder_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
.offset_field_in(decoder_offset_field), // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
.immediate_field_in(decoder_immediate_field), // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
.scale_factor_in(decoder_scale_factor), // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
.index_limit_in(decoder_index_limit), // The field indicated by offset_field contains a limit to the index
.writeport1(bus1_value), // result bus 1
.writea1(bus1_register_a), // address input for bus 1
.write_en1(bus1_write_en), // a result is written to bus 1
.write_tag1(bus1_tag), // tag of result in bus 1
.writeport2(bus2_value), // result bus 2
.writea2(bus2_register_a), // address input for bus 2
.write_en2(bus2_write_en), // a result is written to bus 2
.write_tag2(bus2_tag), // tag of result in bus 2
.debug_reada(debug_reada), // register read port for debugger
.predict_tag1_in(predict_tag1), // tag on result bus 1 in next clock cycle
.predict_tag2_in(predict_tag2), // tag on result bus 2 in next clock cycle
.valid_out(registerread_valid), // An instruction is ready for output to next stage
.instruction_pointer_out(registerread_instruction_pointer), // address of current instruction
.instruction_out(registerread_instruction), // first word of instruction
.stall_predict_out(registerread_stall_predict), // predict next stage will stall
.tag_val_out(registerread_tag_val), // instruction tag value
.vector_out(registerread_vector), // this is a vector instruction
.category_out(registerread_category), // 00: multiformat, 01: single format, 10: jump
.format_out(registerread_format), // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
.num_operands_out(registerread_num_operands), // number of source operands
.result_type_out(registerread_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
.offset_field_out(registerread_offset_field), // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
.immediate_field_out(registerread_immediate_field), // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
.scale_factor_out(registerread_scale_factor), // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
.index_limit_out(registerread_index_limit), // The field indicated by offset_field contains a limit to the index
.rd_val_out(registerread_rd_val), // value of register operand RD, bit `RB indicates missing
.rs_val_out(registerread_rs_val), // value of register operand RS, bit `RB indicates missing
.rt_val_out(registerread_rt_val), // value of register operand RT, bit `RB indicates missing
.ru_val_out(registerread_ru_val), // value of register operand RU, bit `RB indicates missing
.mask_val_out(registerread_mask_val), // value of mask register, bit 32 indicates missing
.rd_status_out(registerread_rd_status), // 1: RD is used as input
.rs_status_out(registerread_rs_status), // use of RS
.rt_status_out(registerread_rt_status), // use of RT
.ru_status_out(registerread_ru_status), // 1: RU is used
.mask_status_out(registerread_mask_status), // 1: mask register is used
.mask_alternative_out(registerread_mask_alternative), // mask register and fallback register used for alternative purposes
.fallback_use_out(registerread_fallback_use), // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
.debugport_out(registerread_debugport) // read for debugging purpose
);
addressgenerator addressgenerator_inst (
.clock(clock), // system clock (100 MHz)
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.reset(system_reset), // system reset.
.valid_in(registerread_valid), // data from fetch module ready
.stall_in(dataread_stall_predict | alu_stall_next | muldiv_stall_next | inout_stall_next), // pipeline is stalled
.instruction_pointer_in(registerread_instruction_pointer), // address of current instruction
.instruction_in(registerread_instruction), // current instruction, up to 3 words long
.tag_val_in(registerread_tag_val), // instruction tag value
.vector_in(registerread_vector), // this is a vector instruction
.category_in(registerread_category), // 00: multiformat, 01: single format, 10: jump
.format_in(registerread_format), // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
.rs_status_in(registerread_rs_status), // use of RS
.rt_status_in(registerread_rt_status), // use of RT
.ru_status_in(registerread_ru_status), // RU is used
.rd_status_in(registerread_rd_status), // RD is used as input
.mask_status_in(registerread_mask_status), // mask register used
.mask_alternative_in(registerread_mask_alternative), // mask register and fallback register used for alternative purposes
.fallback_use_in(registerread_fallback_use), // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
.num_operands_in(registerread_num_operands), // number of source operands
.result_type_in(registerread_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
.offset_field_in(registerread_offset_field), // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
.immediate_field_in(registerread_immediate_field), // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
.scale_factor_in(registerread_scale_factor), // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
.index_limit_in(registerread_index_limit), // The field indicated by offset_field contains a limit to the index
.rd_val_in(registerread_rd_val), // value of register operand RD, bit `RB indicates missing
.rs_val_in(registerread_rs_val), // value of register operand RS, bit `RB indicates missing
.rt_val_in(registerread_rt_val), // value of register operand RT, bit `RB indicates missing
.ru_val_in(registerread_ru_val), // value of register operand RU, bit `RB indicates missing
.mask_val_in(registerread_mask_val), // mask register
.write_en1(bus1_write_en), // a result is written to bus 1
.write_tag1_in(bus1_tag), // tag of result in bus 1
.writeport1_in(bus1_value), // result bus 1
.write_en2(bus2_write_en), // a result is written to bus 2
.write_tag2_in(bus2_tag), // tag of result in bus 2
.writeport2_in(bus2_value), // result bus 2
.predict_tag1_in(predict_tag1), // tag on result bus 1 in next clock cycle
.predict_tag2_in(predict_tag2), // tag on result bus 2 in next clock cycle
//.ram_data_in(data_memory_data), // memory operand from data memory
.read_write_address_out(addrgen_read_write_address), // address of read memory operand
.read_enable_out(addrgen_read_enable), // enable read from data memory
.read_data_size_out(addrgen_read_data_size), // data size for memory read
.write_enable_out(addrgen_write_enable), // write enable for each byte separately
.write_data_out(addrgen_write_data), // data to write
.valid_out(addrgen_valid), // An instruction is ready for output to next stage
.instruction_pointer_out(addrgen_instruction_pointer), // address of current instruction
.instruction_out(addrgen_instruction), // first word of instruction
.stall_predict_out(addrgen_stall_next), // will be waiting for an operand
.div_predict_out(addrgen_div_predict), // a division instruction is underway
.tag_val_out(addrgen_tag_val), // instruction tag value
.operand1_out(addrgen_operand1), // value of first operand, bit `RB indicates invalid
.operand2_out(addrgen_operand2), // value of second operand, bit `RB indicates invalid
.operand3_out(addrgen_operand3), // value of last, bit `RB indicates valid
.mask_val_out(addrgen_mask_val), // value of mask register, bit 32 indicates valid
.vector_out(addrgen_vector), // this is a vector instruction
.category_out(addrgen_category), // 00: multiformat, 01: single format, 10: jump
.format_out(addrgen_format), // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
.mask_status_out(addrgen_mask_status), // 1: mask register used
.mask_alternative_out(addrgen_mask_alternative), // mask register and fallback register used for alternative purposes
.fallback_use_out(addrgen_fallback_use), // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
.num_operands_out(addrgen_num_operands), // number of source operands
.result_type_out(addrgen_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
.offset_field_out(addrgen_offset_field), // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
.immediate_field_out(addrgen_immediate_field), // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
.scale_factor_out(addrgen_scale_factor), // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
.memory_operand_out(addrgen_memory_operand), // The instruction has a memory operand
.array_error_out(addrgen_array_error), // Array index exceeds limit
.options5_out(addrgen_options5), // IM5 containts option bits
.debug1_out(addrgen_debug1), // Temporary output for debugging purpose
.debug2_out(addrgen_debug2), // Temporary output for debugging purpose
.debug3_out(addrgen_debug3) // Temporary output for debugging purpose
);
dataread dataread_inst (
.clock(clock), // system clock
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.reset(system_reset), // system reset.
.valid_in(addrgen_valid), // data from fetch module ready
.stall_in(dataread_stall_predict | alu_stall_next | muldiv_stall_next | inout_stall_next), // pipeline is stalled
.instruction_pointer_in(addrgen_instruction_pointer), // address of current instruction
.instruction_in(addrgen_instruction), // current instruction, up to 3 words long
.tag_val_in(addrgen_tag_val), // instruction tag value
.vector_in(addrgen_vector), // this is a vector instruction
.category_in(addrgen_category), // 00: multiformat, 01: single format, 10: jump
.format_in(addrgen_format), // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
.mask_status_in(addrgen_mask_status), // 1: mask register used
.mask_alternative_in(addrgen_mask_alternative), // mask register and fallback register used for alternative purposes
.num_operands_in(addrgen_num_operands), // number of source operands
.result_type_in(addrgen_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
.immediate_field_in(addrgen_immediate_field), // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
.memory_operand_in(addrgen_memory_operand), // the instruction has a memory operand
.array_error_in(addrgen_array_error), // Array index exceeds limit
.options5_in(addrgen_options5), // IM5 containts option bits
//.div_busy_in(muldiv_busy), // divider is busy
.write_en1(bus1_write_en), // a result is written to bus 1
.write_tag1_in(bus1_tag), // tag of result in bus 1
.writeport1_in(bus1_value), // result bus 1
.write_en2(bus2_write_en), // a result is written to bus 2
.write_tag2_in(bus2_tag), // tag of result in bus 2
.writeport2_in(bus2_value), // result bus 2
.predict_tag1_in(predict_tag1), // result tag value on bus 1 in next clock cycle
.predict_tag2_in(predict_tag2), // result tag value on bus 2 in next clock cycle
.operand1_in(addrgen_operand1), // value of first operand
.operand2_in(addrgen_operand2), // value of second operand
.operand3_in(addrgen_operand3), // value of last operand
.mask_val_in(addrgen_mask_val), // mask register
.address_in(addrgen_read_write_address), // address of memory operand
.ram_data_in(data_memory_data), // memory operand from data memory
.valid_out(dataread_valid), // An instruction is ready for output to next stage
.instruction_pointer_out(dataread_instruction_pointer),// address of current instruction
.instruction_out(dataread_instruction), // first word of instruction
.stall_predict_out(dataread_stall_predict), // predict next stage will stall
.tag_val_out(dataread_tag_val), // instruction tag value
.operand1_out(dataread_operand1), // value of first operand for 3-op instructions, bit `RB is 0 if valid
.operand2_out(dataread_operand2), // value of second operand, bit `RB is 0 if valid
.operand3_out(dataread_operand3), // value of last operand, bit `RB is 0 if valid
.mask_val_out(dataread_mask_val), // value of mask, bit 32 is 0 if valid
.opr2_from_ram_out(dataread_opr2_from_ram), // value of operand 2 comes from data memory
.opr3_from_ram_out(dataread_opr3_from_ram), // value of last operand comes from data memory
.vector_out(dataread_vector), // this is a vector instruction
.category_out(dataread_category), // 00: multiformat, 01: single format, 10: jump
.format_out(dataread_format), // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
.num_operands_out(dataread_num_operands), // number of source operands
.result_type_out(dataread_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
.opr1_used_out(dataread_opr1_used), // operand1 is needed
.opr2_used_out(dataread_opr2_used), // operand2 is needed
.opr3_used_out(dataread_opr3_used), // operand3 is needed
.mask_used_out(dataread_mask_used), // mask_val_out is needed
.mask_alternative_out(dataread_mask_alternative), // mask register and fallback register used for alternative purposes
.exe_unit_out(dataread_exe_unit), // each bit enables a particular execution unit
.opx_out(dataread_opx), // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
.opj_out(dataread_opj), // operation ID for conditional jump instructions
.ot_out(dataread_ot), // operand type
.option_bits_out(dataread_option_bits), // instruction option bits
.im4_bits_out(dataread_im4_bits), // constant bits from IM4 as extra operand
.trap_out(dataread_trap), // trap instruction detected
.array_error_out(dataread_array_error), // array index out of bounds
.read_address_error_out(dataread_read_address_error), // invalid read memory address
.write_address_error_out(dataread_write_address_error),// invalid write memory address
.misaligned_address_error_out(dataread_misaligned_address_error), // misaligned read/write memory address
.debug_out(dataread_debug) // output for debugging
);
alu alu_inst (
.clock(clock), // system clock
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.reset(system_reset), // system reset.
.valid_in(dataread_valid & dataread_exe_unit[0]), // data from previous stage ready
.instruction_pointer_in(dataread_instruction_pointer), // address of current instruction
.instruction_in(dataread_instruction), // current instruction, first word only
.tag_val_in(dataread_tag_val), // instruction tag value
.category_in(dataread_category), // 00: multiformat, 01: single format, 10: jump
.mask_alternative_in(dataread_mask_alternative), // mask register and fallback register used for alternative purposes
.result_type_in(dataread_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
.vector_in(dataread_vector), // vector instruction
.opx_in(dataread_opx), // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
.opj_in(dataread_opj), // operation ID for conditional jump instructions
.ot_in(dataread_ot), // operand type
.option_bits_in(dataread_option_bits), // option bits from IM5
.im4_bits_in(dataread_im4_bits), // constant bits from IM4 as extra operand
// monitor result buses:
.write_en1(bus1_write_en), // a result is written to bus 1
.write_tag1_in(bus1_tag), // tag of result in bus 1
.writeport1_in(bus1_value), // result bus 1
.write_en2(bus2_write_en), // a result is written to bus 2
.write_tag2_in(bus2_tag), // tag of result in bus 2
.writeport2_in(bus2_value), // result bus 2
.predict_tag1_in(predict_tag1), // result tag value on bus 1 in next clock cycle
.predict_tag2_in(predict_tag2), // result tag value on bus 2 in next clock cycle
// Register values sampled from result bus in previous stages
.operand1_in(dataread_operand1), // first operand or fallback value
.operand2_in(dataread_operand2), // second operand value
.operand3_in(dataread_operand3), // last operand value
.mask_val_in(dataread_mask_val), // mask register
.ram_data_in(data_memory_data), // memory operand from data memory
.opr2_from_ram_in(dataread_opr2_from_ram), // value of operand 2 comes from data memory
.opr3_from_ram_in(dataread_opr3_from_ram), // value of last operand comes from data memory
.opr1_used_in(dataread_opr1_used), // opr1_val_in is needed
.opr2_used_in(dataread_opr2_used), // opr2_val_in is needed
.opr3_used_in(dataread_opr3_used), // opr3_val_in is needed
.mask_used_in(dataread_mask_used), // mask_val_in is needed
.valid_out(alu_valid), // alu is active
.register_write_out(alu_write_en), // write enable for bus 1
.register_a_out(alu_register_a), // register to write
.result_out(alu_result), //
.tag_val_out(alu_tag), // instruction tag value
.jump_out(alu_jump), // jump instruction: jump taken
.nojump_out(alu_nojump), // jump instruction: jump not taken
.jump_pointer_out(alu_jump_pointer), // jump target to fetch unit
.stall_out(alu_stall), // alu is waiting for an operand or not ready to receive a new instruction
.stall_next_out(alu_stall_next), // alu will be waiting in next clock cycle
.error_out(alu_error), // unknown instruction
.error_parm_out(alu_error_parm), // wrong parameter for instruction
.debug1_out(alu_debug1), // debug information
.debug2_out(alu_debug2) // debug information
);
mul_div muldiv_inst (
.clock(clock), // system clock
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.reset(system_reset), // system reset.
.valid_in(dataread_valid & (dataread_exe_unit[1] | dataread_exe_unit[2])), // data from previous stage ready
.instruction_in(dataread_instruction[31:0]), // current instruction, up to 3 words long
.tag_val_in(dataread_tag_val), // instruction tag value
//.category_in(dataread_category), // 00: multiformat, 01: single format, 10: jump
//.mask_alternative_in(dataread_mask_alternative), // mask register and fallback register used for alternative purposes
//.result_type_in(dataread_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
//.vector_in(dataread_vector), // vector instruction
.opx_in(dataread_opx), // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
.ot_in(dataread_ot), // operand type
.option_bits_in(dataread_option_bits), // option bits from IM4
.div_predict_in(addrgen_div_predict), // division instruction underway from address stage
// monitor result buses:
.write_en1(bus1_write_en), // a result is written to bus 1
.write_tag1_in(bus1_tag), // tag of result in bus 1
.writeport1_in(bus1_value), // result bus 1
.write_en2(bus2_write_en), // a result is written to bus 2
.write_tag2_in(bus2_tag), // tag of result in bus 2
.writeport2_in(bus2_value), // result bus 2
.predict_tag1_in(predict_tag1), // result tag value on bus 1 in next clock cycle
.predict_tag2_in(predict_tag2), // result tag value on bus 2 in next clock cycle
// Register values sampled from result bus in previous stages
.operand1_in(dataread_operand1), // first operand or fallback value
.operand2_in(dataread_operand2), // second operand value
.operand3_in(dataread_operand3), // last operand value
.mask_val_in(dataread_mask_val), // mask register
.ram_data_in(data_memory_data), // memory operand from data memory
.opr2_from_ram_in(dataread_opr2_from_ram), // value of operand 2 comes from data memory
.opr3_from_ram_in(dataread_opr3_from_ram), // value of last operand comes from data memory
.opr1_used_in(dataread_opr1_used), // opr1_val_in is needed
.opr2_used_in(dataread_opr2_used), // opr2_val_in is needed
.opr3_used_in(dataread_opr3_used), // opr3_val_in is needed
.mask_used_in(dataread_mask_used), // mask_val_in is needed
.valid_out(muldiv_valid), // alu is active
.register_write_out(muldiv_write_en), // write enable for bus 1
.register_a_out(muldiv_register_a), // register to write
.result_out(muldiv_result), //
.tag_val_out(muldiv_tag), // instruction tag value
.predict_tag2_out(predict_tag2), // predict tag for bus2_value in next clock cycle
//.div_busy_out(muldiv_busy), // division unit busy
.div_out(muldiv_divout), // division unit busy
.stall_out(muldiv_stall), // alu is waiting for an operand or not ready to receive a new instruction
.stall_next_out(muldiv_stall_next), // alu will be waiting in next clock cycle
.error_out(muldiv_error), // unknown instruction
.error_parm_out(muldiv_error_parm), // wrong parameter for instruction
.debug1_out(muldiv_debug1), // debug information
.debug2_out(muldiv_debug2) //, // debug information
//.debug3_out(muldiv_debug3) // debug information
);
/***************************************************
Input and output ports
***************************************************/
in_out_ports in_out_ports_inst (
.clock(clock), // system clock
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.reset(system_reset), // system reset
.valid_in(dataread_valid & dataread_exe_unit[3]), // data from previous stage ready
.stall_in(alu_stall_next | muldiv_stall_next | inout_stall_next),// pipeline is stalled
.instruction_in(dataread_instruction[31:0]), // current instruction, up to 3 words long
.tag_val_in(dataread_tag_val), // instruction tag value
.category_in(dataread_category), // 00: multiformat, 01: single format, 10: jump
.result_type_in(dataread_result_type), // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
.mask_alternative_in(dataread_mask_alternative), // mask register and fallback register used for alternative purposes
.vector_in(dataread_vector), // vector instruction
.opx_in(dataread_opx), // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
.opj_in(dataread_opj), // operation ID for conditional jump instructions
.ot_in(dataread_ot), // operand type
.mask_used_in(dataread_mask_used), // mask_val_in is needed
// connections to UART
.uart_bit_in(uart_txd_in), // serial input
//.uart_rts_in(uart_rts_in), // ready to send input. not used
// monitor result buses:
.write_en1(bus1_write_en), // a result is written to bus 1
.write_tag1_in(bus1_tag), // tag of result in bus 1
.writeport1_in(bus1_value), // result bus 1
.write_en2(bus2_write_en), // a result is written to bus 2
.write_tag2_in(bus2_tag), // tag of result in bus 2
.writeport2_in(bus2_value), // result bus 2
.predict_tag1_in(predict_tag1), // result tag value on bus 1 in next clock cycle
.predict_tag2_in(predict_tag2), // result tag value on bus 2 in next clock cycle
// Register values sampled from result bus in previous stages
.operand1_in(dataread_operand1), // first operand or fallback value
.operand2_in(dataread_operand2), // second operand
.operand3_in(dataread_operand3), // last operand
.mask_val_in(dataread_mask_val), // mask register
.opr1_used_in(dataread_opr1_used), // opr1_val_in is needed
// signals used for performance monitoring
.instruction_valid_in(dataread_valid), // instruction is valid but possibly going to a different exe unit
.fast_jump_in(fetch_jump), // a jump is bypassing the pipeline
.errors_detect_in(errors_detect), // one bit for each type of error detected
.fetch_instruction_pointer(fetch_instruction_pointer),
.dataread_instruction_pointer(dataread_instruction_pointer),
.dataread_valid(dataread_valid), // used when reconstructing alu_instruction_pointer
.call_stack_overflow(call_stack_overflow), // used for differentiating errors_detect_in[1]
.clear_error_in(clear_error), // debug clear error
// outputs
.valid_out(inout_valid), // in_out is active
.register_write_out(inout_write_en),
.register_a_out(inout_register_a), // register to write
.result_out(inout_result),
.tag_val_out(inout_tag), // instruction tag value
.nojump_out(inout_nojump), // serializing instruction finished
.stall_out(inout_stal), // alu is waiting for an operand or not ready to receive a new instruction
.stall_next_out(inout_stall_next), // alu will be waiting in next clock cycle
.error_out(inout_error), // unknown instruction
.error_parm_out(inout_error_parm), // wrong parameter for instruction
.uart_bit_out(uart_rxd_out), // serial output
.uart_cts_out(uart_cts_out), // clear to send output
.capab_disable_errors(inout_capab_disable_errors), // capab2 register: disable errors
.first_error(inout_first_error), // error type for first error
.first_error_address(inout_first_error_address), // code address of first error
.debug_out(inout_debug) // debug information
);
/***************************************************
Debugging signals
***************************************************/
// debug display
debug_display debug_display_inst (
.clock(clock), // system clock (50 - 100 MHz)
.clock_enable(clock_enable), // clock enable. Used when single-stepping
.reset_button_debounced(reset_button_debounced), // reset button
// from fetch stage
.fetch_instruction(fetch_instruction[63:0]), // first words of instruction
.fetch_instruction_pointer(fetch_instruction_pointer), // point to current instruction
.fetch_valid(fetch_valid), // output from fetch is ready
.fetch_jump(fetch_jump), // jump instruction bypassing pipeline
.fetch_call_e(fetch_call_e), // executing call instruction
.fetch_return_e(fetch_return_e), // executing return instruction
.decoder_stall_predict(decoder_stall_predict), // decoder stall next
.registerread_stall_predict(registerread_stall_predict),// address generation stalled next
.addrgen_stall_next(addrgen_stall_next),
.dataread_stall_predict(dataread_stall_predict), // alu stalled next
.alu_stall_next(alu_stall_next), // alu stalled next
.muldiv_stall_next(muldiv_stall_next), // muldiv stalled next
.inout_stall_next(inout_stall_next), // in_out_ports stalled next
// from decoder
.decoder_instruction(decoder_instruction[63:0]), // first words of instruction
.decoder_instruction_pointer(decoder_instruction_pointer), // address of current instruction
.decoder_valid(decoder_valid), // output from decoder is ready
// from register_read
.registerread_instruction(registerread_instruction[63:0]), // first words of instruction
.registerread_instruction_pointer(registerread_instruction_pointer), // address of current instruction
.registerread_valid(registerread_valid), // output from decode_wait is ready
// from address generator
.addrgen_instruction(addrgen_instruction[63:0]), // first words of instruction
.addrgen_instruction_pointer(addrgen_instruction_pointer), // address of current instruction
.addrgen_valid(addrgen_valid), // output from addrgen is ready
// from address_wait