1 |
121 |
ultro |
/* verilator lint_off UNUSED */
|
2 |
|
|
/* verilator lint_off CASEX */
|
3 |
|
|
/* verilator lint_off COMBDLY */
|
4 |
|
|
|
5 |
|
|
//
|
6 |
|
|
// address calculation Unit
|
7 |
|
|
//
|
8 |
|
|
|
9 |
|
|
module acu (clk, rstn, add_src , to_regf , from_regf, from_dec, db67 , seg_src );
|
10 |
|
|
|
11 |
|
|
input clk, rstn;
|
12 |
|
|
input [63:0] from_regf; // base&index register selected for address calculation
|
13 |
|
|
input [128+1+1+73+8-1:0] from_dec;
|
14 |
|
|
input db67;
|
15 |
|
|
|
16 |
|
|
output reg [2:0] seg_src;
|
17 |
|
|
output reg [31:0] add_src; // adress to read from
|
18 |
|
|
output [7:0] to_regf; // base&index select register for address calculation
|
19 |
|
|
|
20 |
|
|
wire [7:0] indrm; // Decoder intermediate input
|
21 |
|
|
wire [72:0] indic; // Decoder intermediate input
|
22 |
|
|
wire [127:0] in128; // Decoder intermediate input
|
23 |
|
|
wire sib_dec; // Decoder intermediate input
|
24 |
|
|
wire mod_dec; // Decoder intermediate input
|
25 |
|
|
wire [31:0] reg_base;
|
26 |
|
|
wire [31:0] reg_index;
|
27 |
|
|
wire [31:0] shf_index;
|
28 |
|
|
wire [7:0] modrm,modrmr;
|
29 |
|
|
wire [15:0] disp16;
|
30 |
|
|
wire [7:0] to_regf32,to_regf16;
|
31 |
|
|
reg ov;
|
32 |
|
|
|
33 |
|
|
// Split from_deco bus
|
34 |
|
|
//
|
35 |
|
|
assign {in128,mod_dec,sib_dec,indic,indrm}=from_dec;
|
36 |
|
|
|
37 |
|
|
// Select Base and index Register
|
38 |
|
|
//
|
39 |
|
|
assign modrm = in128[15:8];
|
40 |
|
|
assign to_regf = db67 ? to_regf32 : to_regf16;
|
41 |
|
|
assign to_regf32[3:0] = (&indrm[1:0]) ? {1'b0,in128[18:16]} : {1'b0,in128[10:8]};
|
42 |
|
|
assign to_regf32[7:4] = (&indrm[1:0]) ? {1'b0,in128[21:19]} : {4'b1111 };
|
43 |
|
|
|
44 |
|
|
assign disp16 = ({modrm[7:6],modrm[2:0]}==5'b00110) ? in128[31:16] :
|
45 |
|
|
({modrm[7:6]}==2'b10) ? in128[31:16] :
|
46 |
|
|
({modrm[7:6]}==2'b01) ? {{8{in128[23]}},in128[23:16]} :
|
47 |
|
|
16'b0;
|
48 |
|
|
|
49 |
|
|
assign to_regf16[3:0] = (modrm[2:1]==2'b11) ? {4'b1111} : {1'b0,2'b11,modrm[0]} ;
|
50 |
|
|
assign to_regf16[7:4] = ( modrm[2:1] == 2'b10 ) ? {4'b1111} :
|
51 |
|
|
({modrm[7:6],modrm[2:0]} == 5'b00110) ? {4'b1111} :
|
52 |
|
|
(modrm[2]==1'b0) ? {1'b0, modrm[1], ~modrm[1],1'b1} :
|
53 |
|
|
{1'b0, ~modrm[0], modrm[0],1'b1} ;
|
54 |
|
|
|
55 |
|
|
assign reg_base = from_regf[31: 0];
|
56 |
|
|
assign reg_index = ((in128[21:19]==4)&&(db67==1)) ? 0 : from_regf[63:32]; // ESP is illegal index
|
57 |
|
|
assign shf_index = (in128[23:22]==0) ? reg_index :
|
58 |
|
|
(in128[23:22]==1) ? {reg_index[30:0],1'b0} :
|
59 |
|
|
(in128[23:22]==2) ? {reg_index[29:0],2'b0} :
|
60 |
|
|
{reg_index[28:0],3'b0} ;
|
61 |
|
|
|
62 |
|
|
// Put in FFlops the address of memory location to be used for next operation
|
63 |
|
|
//
|
64 |
|
|
|
65 |
|
|
//always @(reg_base or reg_index or shf_index or in128 or mod_dec or indrm or disp16 or to_regf32 or to_regf or db67)
|
66 |
|
|
always @(posedge clk)
|
67 |
|
|
if (db67)
|
68 |
|
|
begin
|
69 |
|
|
seg_src <=0;
|
70 |
|
|
if (mod_dec)
|
71 |
|
|
casex(indrm[4:0])
|
72 |
|
|
5'b00110 : begin add_src <= in128[47:16] ; end // 32bit only displc
|
73 |
|
|
5'b10010 : begin {ov,add_src} <= reg_base + {{24{in128[23]}},in128[23:16]}; end // no sib - 8bit displc
|
74 |
|
|
5'b10011 : begin {ov,add_src} <= shf_index+ reg_base + {{24{in128[31]}},in128[31:24]}; end // sib - 8bit displc
|
75 |
|
|
5'b01010 : begin {ov,add_src} <= reg_base + in128[47:16] ; end // no sib - 32bit displc
|
76 |
|
|
5'b01011 : begin {ov,add_src} <= shf_index+ reg_base + in128[55:24] ; end // sib - 32bit displc
|
77 |
|
|
|
78 |
|
|
5'b00011 : if ((indrm[7]==1)&&(to_regf32[3:0]==4'b0101))
|
79 |
|
|
begin {ov,add_src} <= shf_index+ in128[55:24] ; end // sib - 32bit displc only
|
80 |
|
|
else begin {ov,add_src} <= shf_index+ reg_base ; end // sib - no displc displc
|
81 |
|
|
|
82 |
|
|
5'b00010 : begin add_src <= reg_base ; end // no sib - no displc - only base
|
83 |
|
|
default : begin add_src <= reg_base ; end
|
84 |
|
|
endcase
|
85 |
|
|
else begin add_src <=0; ov <=0; end
|
86 |
|
|
end
|
87 |
|
|
else
|
88 |
|
|
begin if ((mod_dec&indrm[6]) == 1) seg_src <= 3'b011;
|
89 |
|
|
else if ( mod_dec == 0 ) seg_src <= 3'b011;
|
90 |
|
|
else if (to_regf[7:4] == 4'b0101) seg_src <= 3'b010;
|
91 |
|
|
else if (to_regf[7:4] == 4'b0100) seg_src <= 3'b010;
|
92 |
|
|
else seg_src <= 3'b011;
|
93 |
|
|
ov <=0;
|
94 |
|
|
if (mod_dec)
|
95 |
|
|
begin
|
96 |
|
|
add_src[15:0] <= reg_base[15:0] + reg_index[15:0] + disp16;
|
97 |
|
|
add_src[31:16] <= 16'b0 ;
|
98 |
|
|
end
|
99 |
|
|
else add_src <=0;
|
100 |
|
|
end
|
101 |
|
|
|
102 |
|
|
endmodule
|