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
|
`include "core/uarch.sv"
module core_control_data
(
input logic clk,
rst_n,
input insn_decode dec,
input word rd_value_a,
rd_value_b,
input logic mem_ready,
input word q_alu,
q_shifter,
input logic c_shifter,
input ctrl_cycle cycle,
next_cycle,
input ptr pc,
input word mem_offset,
input psr_flags flags,
output alu_op alu,
output word alu_a,
alu_b,
saved_base,
output shifter_control shifter,
output logic[7:0] shifter_shift,
output logic c_in,
trivial_shift,
data_snd_shift_by_reg
);
logic data_snd_is_imm;
logic[5:0] data_shift_imm;
logic[11:0] data_imm;
assign trivial_shift = shifter_shift == 0;
always_comb begin
unique case(cycle)
RD_INDIRECT_SHIFT: shifter_shift = rd_value_b[7:0];
default: shifter_shift = {2'b00, data_shift_imm};
endcase
unique case(cycle)
TRANSFER: alu_a = saved_base;
EXCEPTION: alu_a = {pc, 2'b00};
default: alu_a = rd_value_a;
endcase
unique case(cycle)
RD_INDIRECT_SHIFT, WITH_SHIFT:
alu_b = saved_base;
TRANSFER:
alu_b = mem_offset;
default:
if(data_snd_is_imm)
alu_b = {{20{1'b0}}, data_imm};
else
alu_b = rd_value_b;
endcase
end
always_ff @(posedge clk or negedge rst_n)
if(!rst_n) begin
alu <= {$bits(alu){1'b0}};
c_in <= 0;
shifter <= {$bits(shifter){1'b0}};
data_imm <= {$bits(data_imm){1'b0}};
saved_base <= 0;
data_shift_imm <= {$bits(data_shift_imm){1'b0}};
data_snd_is_imm <= 0;
data_snd_shift_by_reg <= 0;
end else unique case(next_cycle)
ISSUE: begin
alu <= dec.data.op;
c_in <= flags.c;
data_imm <= dec.snd.imm;
data_shift_imm <= dec.snd.shift_imm;
data_snd_is_imm <= dec.snd.is_imm;
data_snd_shift_by_reg <= dec.snd.shift_by_reg;
shifter.shr <= dec.snd.shr;
shifter.ror <= dec.snd.ror;
shifter.put_carry <= dec.snd.put_carry;
shifter.sign_extend <= dec.snd.sign_extend;
end
RD_INDIRECT_SHIFT: begin
saved_base <= rd_value_b;
data_snd_shift_by_reg <= 0;
end
WITH_SHIFT: begin
c_in <= c_shifter;
saved_base <= q_shifter;
end
TRANSFER:
if(cycle != TRANSFER || mem_ready)
saved_base <= q_alu;
EXCEPTION: begin
alu <= `ALU_ADD;
data_imm <= 12'd4;
data_snd_is_imm <= 1;
end
endcase
endmodule
|