Line data Source code
1 : // SPDX-License-Identifier: Apache-2.0
2 : // Copyright 2020 Western Digital Corporation or its affiliates.
3 : //
4 : // Licensed under the Apache License, Version 2.0 (the "License");
5 : // you may not use this file except in compliance with the License.
6 : // You may obtain a copy of the License at
7 : //
8 : // http://www.apache.org/licenses/LICENSE-2.0
9 : //
10 : // Unless required by applicable law or agreed to in writing, software
11 : // distributed under the License is distributed on an "AS IS" BASIS,
12 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : // See the License for the specific language governing permissions and
14 : // limitations under the License.
15 :
16 : module el2_dec_gpr_ctl
17 : import el2_pkg::*;
18 : #(
19 : `include "el2_param.vh"
20 : ) (
21 2495649 : input logic [4:0] raddr0, // logical read addresses
22 4215929 : input logic [4:0] raddr1,
23 :
24 5726991 : input logic wen0, // write enable
25 2808313 : input logic [4:0] waddr0, // write address
26 314101 : input logic [31:0] wd0, // write data
27 :
28 919868 : input logic wen1, // write enable
29 368806 : input logic [4:0] waddr1, // write address
30 71598 : input logic [31:0] wd1, // write data
31 :
32 156852 : input logic wen2, // write enable
33 21351 : input logic [4:0] waddr2, // write address
34 24784 : input logic [31:0] wd2, // write data
35 :
36 69840565 : input logic clk,
37 338 : input logic rst_l,
38 :
39 407934 : output logic [31:0] rd0, // read data
40 598866 : output logic [31:0] rd1,
41 :
42 : // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
43 : /*verilator coverage_off*/
44 : input logic scan_mode
45 : /*verilator coverage_on*/
46 : );
47 :
48 : logic [31:1] [31:0] gpr_out; // 31 x 32 bit GPRs
49 : logic [31:1] [31:0] gpr_in;
50 1324 : logic [31:1] w0v,w1v,w2v;
51 63540 : logic [31:1] gpr_wr_en;
52 :
53 : // GPR Write Enables
54 : assign gpr_wr_en[31:1] = (w0v[31:1] | w1v[31:1] | w2v[31:1]);
55 : for ( genvar j=1; j<32; j++ ) begin : gpr
56 : rvdffe #(32) gprff (.*, .en(gpr_wr_en[j]), .din(gpr_in[j][31:0]), .dout(gpr_out[j][31:0]));
57 : end : gpr
58 :
59 : // the read out
60 339 : always_comb begin
61 339 : rd0[31:0] = 32'b0;
62 339 : rd1[31:0] = 32'b0;
63 339 : w0v[31:1] = 31'b0;
64 339 : w1v[31:1] = 31'b0;
65 339 : w2v[31:1] = 31'b0;
66 339 : gpr_in[31:1] = '0;
67 :
68 : // GPR Read logic
69 339 : for (int j=1; j<32; j++ ) begin
70 10509 : rd0[31:0] |= ({32{(raddr0[4:0]== 5'(j))}} & gpr_out[j][31:0]);
71 10509 : rd1[31:0] |= ({32{(raddr1[4:0]== 5'(j))}} & gpr_out[j][31:0]);
72 : end
73 :
74 : // GPR Write logic
75 339 : for (int j=1; j<32; j++ ) begin
76 10509 : w0v[j] = wen0 & (waddr0[4:0]== 5'(j) );
77 10509 : w1v[j] = wen1 & (waddr1[4:0]== 5'(j) );
78 10509 : w2v[j] = wen2 & (waddr2[4:0]== 5'(j) );
79 10509 : gpr_in[j] = ({32{w0v[j]}} & wd0[31:0]) |
80 10509 : ({32{w1v[j]}} & wd1[31:0]) |
81 10509 : ({32{w2v[j]}} & wd2[31:0]);
82 : end
83 : end // always_comb begin
84 :
85 : `ifdef RV_ASSERT_ON
86 :
87 : logic write_collision_unused;
88 : assign write_collision_unused = ( (w0v[31:1] == w1v[31:1]) & wen0 & wen1 ) |
89 : ( (w0v[31:1] == w2v[31:1]) & wen0 & wen2 ) |
90 : ( (w1v[31:1] == w2v[31:1]) & wen1 & wen2 );
91 :
92 :
93 : // asserting that no 2 ports will write to the same gpr simultaneously
94 : assert_multiple_wen_to_same_gpr: assert #0 (~( write_collision_unused ) );
95 :
96 : `endif
97 :
98 : endmodule
|