OpenCores
URL https://opencores.org/ocsvn/yifive/yifive/trunk

Subversion Repositories yifive

[/] [yifive/] [trunk/] [caravel_yifive/] [verilog/] [rtl/] [syntacore/] [scr1/] [src/] [core/] [pipeline/] [scr1_pipe_mprf.sv] - Blame information for rev 21

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 11 dinesha
/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
2
/// @file       
3
/// @brief      Multi Port Register File (MPRF)
4
///
5
 
6
`include "scr1_arch_description.svh"
7
`include "scr1_arch_types.svh"
8
 
9
module scr1_pipe_mprf (
10
    // Common
11
`ifdef SCR1_MPRF_RST_EN
12
    input   logic                               rst_n,                      // MPRF reset
13
`endif // SCR1_MPRF_RST_EN
14
    input   logic                               clk,                        // MPRF clock
15
 
16
    // EXU <-> MPRF interface
17
    input   logic [`SCR1_MPRF_AWIDTH-1:0]       exu2mprf_rs1_addr_i,        // MPRF rs1 read address
18
    output  logic [`SCR1_XLEN-1:0]              mprf2exu_rs1_data_o,        // MPRF rs1 read data
19
    input   logic [`SCR1_MPRF_AWIDTH-1:0]       exu2mprf_rs2_addr_i,        // MPRF rs2 read address
20
    output  logic [`SCR1_XLEN-1:0]              mprf2exu_rs2_data_o,        // MPRF rs2 read data
21
    input   logic                               exu2mprf_w_req_i,           // MPRF write request
22
    input   logic [`SCR1_MPRF_AWIDTH-1:0]       exu2mprf_rd_addr_i,         // MPRF rd write address
23
    input   logic [`SCR1_XLEN-1:0]              exu2mprf_rd_data_i          // MPRF rd write data
24
);
25
 
26
//-------------------------------------------------------------------------------
27
// Local types declaration
28
//-------------------------------------------------------------------------------
29
 
30
logic                        wr_req_vd;
31
 
32
logic                        rs1_addr_vd;
33
logic                        rs2_addr_vd;
34
 
35
`ifdef  SCR1_MPRF_RAM
36
logic                        rs1_addr_vd_ff;
37
logic                        rs2_addr_vd_ff;
38
 
39
logic                        rs1_new_data_req;
40
logic                        rs2_new_data_req;
41
logic                        rs1_new_data_req_ff;
42
logic                        rs2_new_data_req_ff;
43
logic                        read_new_data_req;
44
 
45
logic    [`SCR1_XLEN-1:0]    rd_data_ff;
46
 
47
logic    [`SCR1_XLEN-1:0]    rs1_data_ff;
48
logic    [`SCR1_XLEN-1:0]    rs2_data_ff;
49
 
50
// when using RAM, 2 memories are needed because 3 simultaneous independent
51
// write/read operations can occur
52
 `ifdef SCR1_TRGT_FPGA_INTEL_MAX10
53
(* ramstyle = "M9K" *)      logic   [`SCR1_XLEN-1:0]    mprf_int   [1:`SCR1_MPRF_SIZE-1];
54
(* ramstyle = "M9K" *)      logic   [`SCR1_XLEN-1:0]    mprf_int2  [1:`SCR1_MPRF_SIZE-1];
55
 `elsif SCR1_TRGT_FPGA_INTEL_ARRIAV
56
(* ramstyle = "M10K" *)     logic   [`SCR1_XLEN-1:0]    mprf_int   [1:`SCR1_MPRF_SIZE-1];
57
(* ramstyle = "M10K" *)     logic   [`SCR1_XLEN-1:0]    mprf_int2  [1:`SCR1_MPRF_SIZE-1];
58
 `else
59
logic   [`SCR1_XLEN-1:0]    mprf_int   [1:`SCR1_MPRF_SIZE-1];
60
logic   [`SCR1_XLEN-1:0]    mprf_int2  [1:`SCR1_MPRF_SIZE-1];
61
 `endif
62
`else  // distributed logic implementation
63 21 dinesha
logic [`SCR1_XLEN-1:0]      mprf_int [1:`SCR1_MPRF_SIZE-1];
64 11 dinesha
`endif
65
 
66
//------------------------------------------------------------------------------
67
// MPRF control logic
68
//------------------------------------------------------------------------------
69
 
70
// control signals common for distributed logic and RAM implementations
71
assign  rs1_addr_vd  =   |exu2mprf_rs1_addr_i;
72
assign  rs2_addr_vd  =   |exu2mprf_rs2_addr_i;
73
 
74
assign  wr_req_vd  =   exu2mprf_w_req_i & |exu2mprf_rd_addr_i;
75
 
76
// RAM implementation specific control signals
77
`ifdef SCR1_MPRF_RAM
78
assign  rs1_new_data_req    =   wr_req_vd & ( exu2mprf_rs1_addr_i == exu2mprf_rd_addr_i );
79
assign  rs2_new_data_req    =   wr_req_vd & ( exu2mprf_rs2_addr_i == exu2mprf_rd_addr_i );
80
assign  read_new_data_req   =   rs1_new_data_req | rs2_new_data_req;
81
 
82
always_ff @( posedge clk ) begin
83
    rs1_addr_vd_ff          <=  rs1_addr_vd;
84
    rs2_addr_vd_ff          <=  rs2_addr_vd;
85
    rs1_new_data_req_ff     <=  rs1_new_data_req;
86
    rs2_new_data_req_ff     <=  rs2_new_data_req;
87
end
88
`endif // SCR1_MPRF_RAM
89
 
90
`ifdef  SCR1_MPRF_RAM
91
//-------------------------------------------------------------------------------
92
// RAM implementation
93
//-------------------------------------------------------------------------------
94
 
95
// RAM is implemented with 2 simple dual-port memories with sync read operation;
96
// logic for "write-first" RDW behavior is implemented externally to the embedded
97
// memory blocks
98
 
99
// bypass new wr_data to the read output if write/read collision occurs
100
assign  mprf2exu_rs1_data_o   =   ( rs1_new_data_req_ff ) ? rd_data_ff
101
                                : (( rs1_addr_vd_ff )   ? rs1_data_ff
102
                                                        : '0 );
103
 
104
assign  mprf2exu_rs2_data_o   =   ( rs2_new_data_req_ff ) ? rd_data_ff
105
                                : (( rs2_addr_vd_ff )   ? rs2_data_ff
106
                                                        : '0 );
107
 
108
always_ff @( posedge clk ) begin
109
    if ( read_new_data_req ) begin
110
        rd_data_ff     <=  exu2mprf_rd_data_i;
111
    end
112
end
113
 
114
// synchronous read operation
115
always_ff @( posedge clk ) begin
116
    rs1_data_ff   <=   mprf_int[exu2mprf_rs1_addr_i];
117
    rs2_data_ff   <=   mprf_int2[exu2mprf_rs2_addr_i];
118
end
119
 
120
// write operation
121
always_ff @( posedge clk ) begin
122
    if ( wr_req_vd ) begin
123
        mprf_int[exu2mprf_rd_addr_i]  <= exu2mprf_rd_data_i;
124
        mprf_int2[exu2mprf_rd_addr_i] <= exu2mprf_rd_data_i;
125
    end
126
end
127
`else   // distributed logic implementation
128
//------------------------------------------------------------------------------
129
// distributed logic implementation
130
//------------------------------------------------------------------------------
131
 
132
// asynchronous read operation
133
assign  mprf2exu_rs1_data_o = ( rs1_addr_vd ) ? mprf_int[exu2mprf_rs1_addr_i] : '0;
134
assign  mprf2exu_rs2_data_o = ( rs2_addr_vd ) ? mprf_int[exu2mprf_rs2_addr_i] : '0;
135
 
136
// write operation
137
 `ifdef SCR1_MPRF_RST_EN
138
always_ff @( posedge clk, negedge rst_n ) begin
139
    if ( ~rst_n ) begin
140
        mprf_int <= '{default: '0};
141
    end else if ( wr_req_vd ) begin
142
        mprf_int[exu2mprf_rd_addr_i] <= exu2mprf_rd_data_i;
143
    end
144
end
145
 `else // ~SCR1_MPRF_RST_EN
146
always_ff @( posedge clk ) begin
147
    if ( wr_req_vd ) begin
148
        mprf_int[exu2mprf_rd_addr_i] <= exu2mprf_rd_data_i;
149
    end
150
end
151
 `endif // ~SCR1_MPRF_RST_EN
152
`endif
153
 
154
`ifdef SCR1_TRGT_SIMULATION
155
//-------------------------------------------------------------------------------
156
// Assertion
157
//-------------------------------------------------------------------------------
158
`ifdef SCR1_MPRF_RST_EN
159
SCR1_SVA_MPRF_WRITEX : assert property (
160
    @(negedge clk) disable iff (~rst_n)
161
    exu2mprf_w_req_i |-> !$isunknown({exu2mprf_rd_addr_i, (|exu2mprf_rd_addr_i ? exu2mprf_rd_data_i : `SCR1_XLEN'd0)})
162
    ) else $error("MPRF error: unknown values");
163
`endif // SCR1_MPRF_RST_EN
164
 
165
`endif // SCR1_TRGT_SIMULATION
166
 
167
endmodule : scr1_pipe_mprf

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.