summaryrefslogtreecommitdiff
path: root/rtl/core/core_control_issue.sv
blob: 5bd03e15a78314e6d575e77773ba8b05816dc1b2 (plain)
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
`include "core/uarch.sv"

module core_control_issue
(
	input  logic       clk,
	                   rst_n,

	input  logic       halt,
	                   irq,

	input  insn_decode dec,
	input  ptr         insn_pc,
	input  logic       issue_abort,

	input  ctrl_cycle  next_cycle,
	input  logic       next_bubble,

`ifdef VERILATOR
	input  word        insn,
`endif

	output logic       issue,
	                   undefined,
	                   prefetch_abort,
	output ptr         pc,
	                   pc_visible,
	                   next_pc_visible
);

	logic valid;

`ifdef VERILATOR
	word bh0 /*verilator public*/,
	     bh1 /*verilator public*/,
	     bh2 /*verilator public*/,
	     bh3 /*verilator public*/;
`endif

	assign valid = !next_bubble && !halt;
	assign issue = next_cycle.issue && dec.ctrl.execute && valid;
	assign next_pc_visible = insn_pc + 2;

	always_ff @(posedge clk or negedge rst_n)
		if(!rst_n) begin
			pc <= 0;
			undefined <= 0;
			pc_visible <= 2;
			prefetch_abort <= 0;

`ifdef VERILATOR
			bh0 <= 0;
			bh1 <= 0;
			bh2 <= 0;
			bh3 <= 0;
`endif
		end else if(next_cycle.issue) begin
			if(valid) begin
				undefined <= dec.ctrl.undefined;
				prefetch_abort <= issue_abort;

`ifdef VERILATOR
				if(dec.ctrl.undefined && !issue_abort)
					$display("[core] undefined insn: [0x%08x] %08x", insn_pc << 2, insn);
`endif
			end

			pc <= insn_pc;
			pc_visible <= next_pc_visible;

`ifdef VERILATOR
			if(insn_pc != pc && insn_pc != pc + 1) begin
				bh0 <= {pc, 2'b00};
				bh1 <= bh0;
				bh2 <= bh1;
				bh3 <= bh2;
			end
`endif
		end

endmodule