//******************************************************************************** // SPDX-License-Identifier: Apache-2.0 // Copyright 2020 Western Digital Corporation or its affiliates. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //******************************************************************************** // purpose of this file is to convert 16b RISCV compressed instruction into 32b equivalent module el2_ifu_compress_ctl import el2_pkg::*; #( `include "el2_param.vh" ) ( input logic [15:0] din, // 16-bit compressed instruction output logic [31:0] dout // 32-bit uncompressed instruction ); logic legal; logic [15:0] i; logic [31:0] o,l1,l2,l3; assign i[15:0] = din[15:0]; logic [4:0] rs2d,rdd,rdpd,rs2pd; logic rdrd; logic rdrs1; logic rs2rs2; logic rdprd; logic rdprs1; logic rs2prs2; logic rs2prd; logic uimm9_2; logic ulwimm6_2; logic ulwspimm7_2; logic rdeq2; logic rdeq1; logic rs1eq2; logic sbroffset8_1; logic simm9_4; logic simm5_0; logic sjaloffset11_1; logic sluimm17_12; logic uimm5_0; logic uswimm6_2; logic uswspimm7_2; // form the opcodes // formats // // c.add rd 11:7 rs2 6:2 // c.and rdp 9:7 rs2p 4:2 // // add rs2 24:20 rs1 19:15 rd 11:7 assign rs2d[4:0] = i[6:2]; assign rdd[4:0] = i[11:7]; assign rdpd[4:0] = {2'b01, i[9:7]}; assign rs2pd[4:0] = {2'b01, i[4:2]}; // merge in rd, rs1, rs2 // rd assign l1[6:0] = o[6:0]; assign l1[11:7] = o[11:7] | ({5{rdrd}} & rdd[4:0]) | ({5{rdprd}} & rdpd[4:0]) | ({5{rs2prd}} & rs2pd[4:0]) | ({5{rdeq1}} & 5'd1) | ({5{rdeq2}} & 5'd2); // rs1 assign l1[14:12] = o[14:12]; assign l1[19:15] = o[19:15] | ({5{rdrs1}} & rdd[4:0]) | ({5{rdprs1}} & rdpd[4:0]) | ({5{rs1eq2}} & 5'd2); // rs2 assign l1[24:20] = o[24:20] | ({5{rs2rs2}} & rs2d[4:0]) | ({5{rs2prs2}} & rs2pd[4:0]); assign l1[31:25] = o[31:25]; logic [5:0] simm5d; logic [9:2] uimm9d; logic [9:4] simm9d; logic [6:2] ulwimm6d; logic [7:2] ulwspimm7d; logic [5:0] uimm5d; logic [20:1] sjald; logic [31:12] sluimmd; // merge in immediates + jal offset assign simm5d[5:0] = { i[12], i[6:2] }; assign uimm9d[9:2] = { i[10:7], i[12:11], i[5], i[6] }; assign simm9d[9:4] = { i[12], i[4:3], i[5], i[2], i[6] }; assign ulwimm6d[6:2] = { i[5], i[12:10], i[6] }; assign ulwspimm7d[7:2] = { i[3:2], i[12], i[6:4] }; assign uimm5d[5:0] = { i[12], i[6:2] }; assign sjald[11:1] = { i[12], i[8], i[10:9], i[6], i[7], i[2], i[11], i[5:4], i[3] }; assign sjald[20:12] = {9{i[12]}}; assign sluimmd[31:12] = { {15{i[12]}}, i[6:2] }; assign l2[31:20] = ( l1[31:20] ) | ( {12{simm5_0}} & {{7{simm5d[5]}},simm5d[4:0]} ) | ( {12{uimm9_2}} & {2'b0,uimm9d[9:2],2'b0} ) | ( {12{simm9_4}} & {{3{simm9d[9]}},simm9d[8:4],4'b0} ) | ( {12{ulwimm6_2}} & {5'b0,ulwimm6d[6:2],2'b0} ) | ( {12{ulwspimm7_2}} & {4'b0,ulwspimm7d[7:2],2'b0} ) | ( {12{uimm5_0}} & {6'b0,uimm5d[5:0]} ) | ( {12{sjaloffset11_1}} & {sjald[20],sjald[10:1],sjald[11]} ) | ( {12{sluimm17_12}} & sluimmd[31:20] ); assign l2[19:12] = ( l1[19:12] ) | ( {8{sjaloffset11_1}} & sjald[19:12] ) | ( {8{sluimm17_12}} & sluimmd[19:12] ); assign l2[11:0] = l1[11:0]; // merge in branch offset and store immediates logic [8:1] sbr8d; logic [6:2] uswimm6d; logic [7:2] uswspimm7d; assign sbr8d[8:1] = { i[12], i[6], i[5], i[2], i[11], i[10], i[4], i[3] }; assign uswimm6d[6:2] = { i[5], i[12:10], i[6] }; assign uswspimm7d[7:2] = { i[8:7], i[12:9] }; assign l3[31:25] = ( l2[31:25] ) | ( {7{sbroffset8_1}} & { {4{sbr8d[8]}},sbr8d[7:5] } ) | ( {7{uswimm6_2}} & { 5'b0, uswimm6d[6:5] } ) | ( {7{uswspimm7_2}} & { 4'b0, uswspimm7d[7:5] } ); assign l3[24:12] = l2[24:12]; assign l3[11:7] = ( l2[11:7] ) | ( {5{sbroffset8_1}} & { sbr8d[4:1], sbr8d[8] } ) | ( {5{uswimm6_2}} & { uswimm6d[4:2], 2'b0 } ) | ( {5{uswspimm7_2}} & { uswspimm7d[4:2], 2'b0 } ); assign l3[6:0] = l2[6:0]; assign dout[31:0] = l3[31:0] & {32{legal}}; // file "cdecode" is human readable file that has all of the compressed instruction decodes defined and is part of git repo // modify this file as needed // to generate all the equations below from "cdecode" except legal equation: // 1) coredecode -in cdecode > cdecode.e // 2) espresso -Dso -oeqntott cdecode.e | addassign > compress_equations // to generate the legal (16b compressed instruction is legal) equation below: // 1) coredecode -in cdecode -legal > clegal.e // 2) espresso -Dso -oeqntott clegal.e | addassign > clegal_equation // espresso decodes assign rdrd = (!i[14]&i[6]&i[1]) | (!i[15]&i[14]&i[11]&i[0]) | (!i[14]&i[5]&i[1]) | ( !i[15]&i[14]&i[10]&i[0]) | (!i[14]&i[4]&i[1]) | (!i[15]&i[14]&i[9] &i[0]) | (!i[14]&i[3]&i[1]) | (!i[15]&i[14]&!i[8]&i[0]) | (!i[14] &i[2]&i[1]) | (!i[15]&i[14]&i[7]&i[0]) | (!i[15]&i[1]) | (!i[15] &!i[13]&i[0]); assign rdrs1 = (!i[14]&i[12]&i[11]&i[1]) | (!i[14]&i[12]&i[10]&i[1]) | (!i[14] &i[12]&i[9]&i[1]) | (!i[14]&i[12]&i[8]&i[1]) | (!i[14]&i[12]&i[7] &i[1]) | (!i[14]&!i[12]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14] &i[12]&i[6]&i[1]) | (!i[14]&i[12]&i[5]&i[1]) | (!i[14]&i[12]&i[4] &i[1]) | (!i[14]&i[12]&i[3]&i[1]) | (!i[14]&i[12]&i[2]&i[1]) | ( !i[15]&!i[14]&!i[13]&i[0]) | (!i[15]&!i[14]&i[1]); assign rs2rs2 = (i[15]&i[6]&i[1]) | (i[15]&i[5]&i[1]) | (i[15]&i[4]&i[1]) | ( i[15]&i[3]&i[1]) | (i[15]&i[2]&i[1]) | (i[15]&i[14]&i[1]); assign rdprd = (i[15]&!i[14]&!i[13]&i[0]); assign rdprs1 = (i[15]&!i[13]&i[0]) | (i[15]&i[14]&i[0]) | (i[14]&!i[1]&!i[0]); assign rs2prs2 = (i[15]&!i[14]&!i[13]&i[11]&i[10]&i[0]) | (i[15]&!i[1]&!i[0]); assign rs2prd = (!i[15]&!i[1]&!i[0]); assign uimm9_2 = (!i[14]&!i[1]&!i[0]); assign ulwimm6_2 = (!i[15]&i[14]&!i[1]&!i[0]); assign ulwspimm7_2 = (!i[15]&i[14]&i[1]); assign rdeq2 = (!i[15]&i[14]&i[13]&!i[11]&!i[10]&!i[9]&i[8]&!i[7]); assign rdeq1 = (!i[14]&i[12]&i[11]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14] &i[12]&i[10]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]&i[12]&i[9] &!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]&i[12]&i[8]&!i[6]&!i[5] &!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]&i[12]&i[7]&!i[6]&!i[5]&!i[4]&!i[3] &!i[2]&i[1]) | (!i[15]&!i[14]&i[13]); assign rs1eq2 = (!i[15]&i[14]&i[13]&!i[11]&!i[10]&!i[9]&i[8]&!i[7]) | (i[14] &i[1]) | (!i[14]&!i[1]&!i[0]); assign sbroffset8_1 = (i[15]&i[14]&i[0]); assign simm9_4 = (!i[15]&i[14]&i[13]&!i[11]&!i[10]&!i[9]&i[8]&!i[7]); assign simm5_0 = (!i[14]&!i[13]&i[11]&!i[10]&i[0]) | (!i[15]&!i[13]&i[0]); assign sjaloffset11_1 = (!i[14]&i[13]); assign sluimm17_12 = (!i[15]&i[14]&i[13]&i[7]) | (!i[15]&i[14]&i[13]&!i[8]) | ( !i[15]&i[14]&i[13]&i[9]) | (!i[15]&i[14]&i[13]&i[10]) | (!i[15]&i[14] &i[13]&i[11]); assign uimm5_0 = (i[15]&!i[14]&!i[13]&!i[11]&i[0]) | (!i[15]&!i[14]&i[1]); assign uswimm6_2 = (i[15]&!i[1]&!i[0]); assign uswspimm7_2 = (i[15]&i[14]&i[1]); assign o[31] = 1'b0; assign o[30] = (i[15]&!i[14]&!i[13]&i[10]&!i[6]&!i[5]&i[0]) | (i[15]&!i[14] &!i[13]&!i[11]&i[10]&i[0]); assign o[29] = 1'b0; assign o[28] = 1'b0; assign o[27] = 1'b0; assign o[26] = 1'b0; assign o[25] = 1'b0; assign o[24] = 1'b0; assign o[23] = 1'b0; assign o[22] = 1'b0; assign o[21] = 1'b0; assign o[20] = (!i[14]&i[12]&!i[11]&!i[10]&!i[9]&!i[8]&!i[7]&!i[6]&!i[5]&!i[4] &!i[3]&!i[2]&i[1]); assign o[19] = 1'b0; assign o[18] = 1'b0; assign o[17] = 1'b0; assign o[16] = 1'b0; assign o[15] = 1'b0; assign o[14] = (i[15]&!i[14]&!i[13]&!i[11]&i[0]) | (i[15]&!i[14]&!i[13]&!i[10] &i[0]) | (i[15]&!i[14]&!i[13]&i[6]&i[0]) | (i[15]&!i[14]&!i[13]&i[5] &i[0]); assign o[13] = (i[15]&!i[14]&!i[13]&i[11]&!i[10]&i[0]) | (i[15]&!i[14]&!i[13] &i[11]&i[6]&i[0]) | (i[14]&!i[0]); assign o[12] = (i[15]&!i[14]&!i[13]&i[6]&i[5]&i[0]) | (i[15]&!i[14]&!i[13]&!i[11] &i[0]) | (i[15]&!i[14]&!i[13]&!i[10]&i[0]) | (!i[15]&!i[14]&i[1]) | ( i[15]&i[14]&i[13]); assign o[11] = 1'b0; assign o[10] = 1'b0; assign o[9] = 1'b0; assign o[8] = 1'b0; assign o[7] = 1'b0; assign o[6] = (i[15]&!i[14]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&!i[0]) | (!i[14]&i[13]) | ( i[15]&i[14]&i[0]); assign o[5] = (i[15]&!i[0]) | (i[15]&i[11]&i[10]) | (i[13]&!i[8]) | (i[13]&i[7]) | ( i[13]&i[9]) | (i[13]&i[10]) | (i[13]&i[11]) | (!i[14]&i[13]) | ( i[15]&i[14]); assign o[4] = (!i[14]&!i[11]&!i[10]&!i[9]&!i[8]&!i[7]&!i[0]) | (!i[15]&!i[14] &!i[0]) | (!i[14]&i[6]&!i[0]) | (!i[15]&i[14]&i[0]) | (!i[14]&i[5] &!i[0]) | (!i[14]&i[4]&!i[0]) | (!i[14]&!i[13]&i[0]) | (!i[14]&i[3] &!i[0]) | (!i[14]&i[2]&!i[0]); assign o[3] = (!i[14]&i[13]); assign o[2] = (!i[14]&i[12]&i[11]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14] &i[12]&i[10]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]&i[12]&i[9] &!i[6]&!i[5]&!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]&i[12]&i[8]&!i[6]&!i[5] &!i[4]&!i[3]&!i[2]&i[1]) | (!i[14]&i[12]&i[7]&!i[6]&!i[5]&!i[4]&!i[3] &!i[2]&i[1]) | (i[15]&!i[14]&!i[12]&!i[6]&!i[5]&!i[4]&!i[3]&!i[2] &!i[0]) | (!i[15]&i[13]&!i[8]) | (!i[15]&i[13]&i[7]) | (!i[15]&i[13] &i[9]) | (!i[15]&i[13]&i[10]) | (!i[15]&i[13]&i[11]) | (!i[14]&i[13]); // 32b instruction has lower two bits 2'b11 assign o[1] = 1'b1; assign o[0] = 1'b1; assign legal = (!i[13]&!i[12]&i[11]&i[1]&!i[0]) | (!i[13]&!i[12]&i[6]&i[1]&!i[0]) | ( !i[15]&!i[13]&i[11]&!i[1]) | (!i[13]&!i[12]&i[5]&i[1]&!i[0]) | ( !i[13]&!i[12]&i[10]&i[1]&!i[0]) | (!i[15]&!i[13]&i[6]&!i[1]) | ( i[15]&!i[12]&!i[1]&i[0]) | (!i[13]&!i[12]&i[9]&i[1]&!i[0]) | (!i[12] &i[6]&!i[1]&i[0]) | (!i[15]&!i[13]&i[5]&!i[1]) | (!i[13]&!i[12]&i[8] &i[1]&!i[0]) | (!i[12]&i[5]&!i[1]&i[0]) | (!i[15]&!i[13]&i[10]&!i[1]) | ( !i[13]&!i[12]&i[7]&i[1]&!i[0]) | (i[12]&i[11]&!i[10]&!i[1]&i[0]) | ( !i[15]&!i[13]&i[9]&!i[1]) | (!i[13]&!i[12]&i[4]&i[1]&!i[0]) | (i[13] &i[12]&!i[1]&i[0]) | (!i[15]&!i[13]&i[8]&!i[1]) | (!i[13]&!i[12]&i[3] &i[1]&!i[0]) | (i[13]&i[4]&!i[1]&i[0]) | (!i[13]&!i[12]&i[2]&i[1] &!i[0]) | (!i[15]&!i[13]&i[7]&!i[1]) | (i[13]&i[3]&!i[1]&i[0]) | ( i[13]&i[2]&!i[1]&i[0]) | (i[14]&!i[13]&!i[1]) | (!i[14]&!i[12]&!i[1] &i[0]) | (i[15]&!i[13]&i[12]&i[1]&!i[0]) | (!i[15]&!i[13]&!i[12]&i[1] &!i[0]) | (!i[15]&!i[13]&i[12]&!i[1]) | (i[14]&!i[13]&!i[0]); endmodule