blob: 5803717b76ba7377cdd4f29ea0a1d9714fd3576e [file] [log] [blame]
module StoreAGU (
clk,
rst,
en,
stall,
IN_mode,
IN_wmask,
IN_branch,
OUT_zcFwd,
IN_uop,
OUT_uop,
OUT_aguOp
);
input wire clk;
input wire rst;
input wire en;
input wire stall;
input wire [7:0] IN_mode;
input wire [63:0] IN_wmask;
input wire [75:0] IN_branch;
output wire [39:0] OUT_zcFwd;
input wire [198:0] IN_uop;
output reg [87:0] OUT_uop;
output reg [162:0] OUT_aguOp;
integer i;
wire [31:0] addrSum = IN_uop[198-:32] + {{20 {IN_uop[82]}}, IN_uop[82:71]};
wire [31:0] addr = (IN_uop[70-:6] >= 6'd7 ? IN_uop[198-:32] : addrSum);
reg except;
always @(*) begin
case (IN_uop[70-:6])
6'd7, 6'd0: except = addr == 0;
6'd8, 6'd1: except = (addr == 0) || addr[0];
6'd6, 6'd9, 6'd2: except = (addr == 0) || (addr[0] || addr[1]);
default: except = 0;
endcase
if ((addr[31:24] == 8'hff) && IN_mode[3'd4])
except = 1;
if (!IN_wmask[addr[31:26]] && IN_mode[3'd1])
except = 1;
end
always @(posedge clk) begin
OUT_uop[0] <= 0;
if (rst)
OUT_aguOp[0] <= 0;
else if (((!stall && en) && IN_uop[0]) && (!IN_branch[0] || ($signed(IN_uop[52-:7] - IN_branch[43-:7]) <= 0))) begin
OUT_aguOp[162-:32] <= addr;
OUT_aguOp[88-:32] <= IN_uop[134-:32];
OUT_aguOp[56-:7] <= IN_uop[64-:7];
OUT_aguOp[49-:5] <= IN_uop[57-:5];
OUT_aguOp[44-:7] <= IN_uop[52-:7];
OUT_aguOp[37-:7] <= IN_uop[15-:7];
OUT_aguOp[30-:7] <= IN_uop[8-:7];
OUT_aguOp[23-:5] <= IN_uop[45-:5];
OUT_aguOp[1] <= IN_uop[1];
OUT_aguOp[18-:16] <= IN_uop[31-:16];
OUT_aguOp[2] <= except;
OUT_aguOp[0] <= 1;
OUT_uop[55-:7] <= IN_uop[64-:7];
OUT_uop[48-:5] <= IN_uop[57-:5];
OUT_uop[43-:7] <= IN_uop[52-:7];
OUT_uop[36-:32] <= IN_uop[134-:32];
OUT_uop[4-:3] <= (except ? 3'd5 : 3'd0);
OUT_uop[1] <= IN_uop[1];
OUT_uop[87-:32] <= addrSum;
OUT_uop[0] <= 1;
case (IN_uop[70-:6])
6'd0, 6'd7: begin
OUT_aguOp[89] <= 0;
case (addr[1:0])
0: begin
OUT_aguOp[98-:4] <= 4'b0001;
OUT_aguOp[130-:32] <= IN_uop[166-:32];
end
1: begin
OUT_aguOp[98-:4] <= 4'b0010;
OUT_aguOp[130-:32] <= IN_uop[166-:32] << 8;
end
2: begin
OUT_aguOp[98-:4] <= 4'b0100;
OUT_aguOp[130-:32] <= IN_uop[166-:32] << 16;
end
3: begin
OUT_aguOp[98-:4] <= 4'b1000;
OUT_aguOp[130-:32] <= IN_uop[166-:32] << 24;
end
endcase
end
6'd1, 6'd8: begin
OUT_aguOp[89] <= 0;
case (addr[1])
0: begin
OUT_aguOp[98-:4] <= 4'b0011;
OUT_aguOp[130-:32] <= IN_uop[166-:32];
end
1: begin
OUT_aguOp[98-:4] <= 4'b1100;
OUT_aguOp[130-:32] <= IN_uop[166-:32] << 16;
end
endcase
end
6'd2, 6'd9: begin
OUT_aguOp[89] <= 0;
OUT_aguOp[98-:4] <= 4'b1111;
OUT_aguOp[130-:32] <= IN_uop[166-:32];
end
6'd3: begin
OUT_aguOp[89] <= 0;
OUT_aguOp[98-:4] <= 0;
OUT_aguOp[100:99] <= 0;
end
6'd4: begin
OUT_aguOp[89] <= 0;
OUT_aguOp[98-:4] <= 0;
OUT_aguOp[100:99] <= 1;
OUT_uop[4-:3] <= 3'd7;
end
6'd5: begin
OUT_aguOp[89] <= 0;
OUT_aguOp[98-:4] <= 0;
OUT_aguOp[100:99] <= 2;
OUT_uop[4-:3] <= 3'd7;
end
default:
;
endcase
end
else if (!stall || ((OUT_aguOp[0] && IN_branch[0]) && ($signed(OUT_aguOp[44-:7] - IN_branch[43-:7]) > 0)))
OUT_aguOp[0] <= 0;
end
endmodule