1 |
11 |
dinesha |
/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
|
2 |
|
|
/// @file
|
3 |
|
|
/// @brief Tightly-Coupled Memory (TCM)
|
4 |
|
|
///
|
5 |
|
|
|
6 |
|
|
`include "scr1_memif.svh"
|
7 |
|
|
`include "scr1_arch_description.svh"
|
8 |
|
|
|
9 |
|
|
`ifdef SCR1_TCM_EN
|
10 |
|
|
module scr1_tcm
|
11 |
|
|
#(
|
12 |
|
|
parameter SCR1_TCM_SIZE = `SCR1_IMEM_AWIDTH'h00010000
|
13 |
|
|
)
|
14 |
|
|
(
|
15 |
|
|
// Control signals
|
16 |
|
|
input logic clk,
|
17 |
|
|
input logic rst_n,
|
18 |
|
|
|
19 |
|
|
// Core instruction interface
|
20 |
|
|
output logic imem_req_ack,
|
21 |
|
|
input logic imem_req,
|
22 |
|
|
input logic [`SCR1_IMEM_AWIDTH-1:0] imem_addr,
|
23 |
|
|
output logic [`SCR1_IMEM_DWIDTH-1:0] imem_rdata,
|
24 |
|
|
output type_scr1_mem_resp_e imem_resp,
|
25 |
|
|
|
26 |
|
|
// Core data interface
|
27 |
|
|
output logic dmem_req_ack,
|
28 |
|
|
input logic dmem_req,
|
29 |
|
|
input type_scr1_mem_cmd_e dmem_cmd,
|
30 |
|
|
input type_scr1_mem_width_e dmem_width,
|
31 |
|
|
input logic [`SCR1_DMEM_AWIDTH-1:0] dmem_addr,
|
32 |
|
|
input logic [`SCR1_DMEM_DWIDTH-1:0] dmem_wdata,
|
33 |
|
|
output logic [`SCR1_DMEM_DWIDTH-1:0] dmem_rdata,
|
34 |
|
|
output type_scr1_mem_resp_e dmem_resp
|
35 |
|
|
);
|
36 |
|
|
|
37 |
|
|
//-------------------------------------------------------------------------------
|
38 |
|
|
// Local signal declaration
|
39 |
|
|
//-------------------------------------------------------------------------------
|
40 |
|
|
logic imem_req_en;
|
41 |
|
|
logic dmem_req_en;
|
42 |
|
|
logic imem_rd;
|
43 |
|
|
logic dmem_rd;
|
44 |
|
|
logic dmem_wr;
|
45 |
|
|
logic [`SCR1_DMEM_DWIDTH-1:0] dmem_writedata;
|
46 |
|
|
logic [`SCR1_DMEM_DWIDTH-1:0] dmem_rdata_local;
|
47 |
|
|
logic [3:0] dmem_byteen;
|
48 |
|
|
logic [1:0] dmem_rdata_shift_reg;
|
49 |
|
|
//-------------------------------------------------------------------------------
|
50 |
|
|
// Core interface
|
51 |
|
|
//-------------------------------------------------------------------------------
|
52 |
|
|
assign imem_req_en = (imem_resp == SCR1_MEM_RESP_RDY_OK) ^ imem_req;
|
53 |
|
|
assign dmem_req_en = (dmem_resp == SCR1_MEM_RESP_RDY_OK) ^ dmem_req;
|
54 |
|
|
|
55 |
|
|
always_ff @(posedge clk, negedge rst_n) begin
|
56 |
|
|
if (~rst_n) begin
|
57 |
|
|
imem_resp <= SCR1_MEM_RESP_NOTRDY;
|
58 |
|
|
end else if (imem_req_en) begin
|
59 |
|
|
imem_resp <= imem_req ? SCR1_MEM_RESP_RDY_OK : SCR1_MEM_RESP_NOTRDY;
|
60 |
|
|
end
|
61 |
|
|
end
|
62 |
|
|
|
63 |
|
|
always_ff @(posedge clk, negedge rst_n) begin
|
64 |
|
|
if (~rst_n) begin
|
65 |
|
|
dmem_resp <= SCR1_MEM_RESP_NOTRDY;
|
66 |
|
|
end else if (dmem_req_en) begin
|
67 |
|
|
dmem_resp <= dmem_req ? SCR1_MEM_RESP_RDY_OK : SCR1_MEM_RESP_NOTRDY;
|
68 |
|
|
end
|
69 |
|
|
end
|
70 |
|
|
|
71 |
|
|
assign imem_req_ack = 1'b1;
|
72 |
|
|
assign dmem_req_ack = 1'b1;
|
73 |
|
|
//-------------------------------------------------------------------------------
|
74 |
|
|
// Memory data composing
|
75 |
|
|
//-------------------------------------------------------------------------------
|
76 |
|
|
assign imem_rd = imem_req;
|
77 |
|
|
assign dmem_rd = dmem_req & (dmem_cmd == SCR1_MEM_CMD_RD);
|
78 |
|
|
assign dmem_wr = dmem_req & (dmem_cmd == SCR1_MEM_CMD_WR);
|
79 |
|
|
|
80 |
|
|
always_comb begin
|
81 |
|
|
dmem_writedata = dmem_wdata;
|
82 |
|
|
dmem_byteen = 4'b1111;
|
83 |
|
|
case ( dmem_width )
|
84 |
|
|
SCR1_MEM_WIDTH_BYTE : begin
|
85 |
|
|
dmem_writedata = {(`SCR1_DMEM_DWIDTH / 8){dmem_wdata[7:0]}};
|
86 |
|
|
dmem_byteen = 4'b0001 << dmem_addr[1:0];
|
87 |
|
|
end
|
88 |
|
|
SCR1_MEM_WIDTH_HWORD : begin
|
89 |
|
|
dmem_writedata = {(`SCR1_DMEM_DWIDTH / 16){dmem_wdata[15:0]}};
|
90 |
|
|
dmem_byteen = 4'b0011 << {dmem_addr[1], 1'b0};
|
91 |
|
|
end
|
92 |
|
|
default : begin
|
93 |
|
|
end
|
94 |
|
|
endcase
|
95 |
|
|
end
|
96 |
|
|
//-------------------------------------------------------------------------------
|
97 |
|
|
// Memory instantiation
|
98 |
|
|
//-------------------------------------------------------------------------------
|
99 |
|
|
scr1_dp_memory #(
|
100 |
|
|
.SCR1_WIDTH ( 32 ),
|
101 |
|
|
.SCR1_SIZE ( SCR1_TCM_SIZE )
|
102 |
|
|
) i_dp_memory (
|
103 |
|
|
.clk ( clk ),
|
104 |
|
|
// Instruction port
|
105 |
|
|
// Port A
|
106 |
|
|
.rena ( imem_rd ),
|
107 |
|
|
.addra ( imem_addr[$clog2(SCR1_TCM_SIZE)-1:2] ),
|
108 |
|
|
.qa ( imem_rdata ),
|
109 |
|
|
// Data port
|
110 |
|
|
// Port B
|
111 |
|
|
.renb ( dmem_rd ),
|
112 |
|
|
.wenb ( dmem_wr ),
|
113 |
|
|
.webb ( dmem_byteen ),
|
114 |
|
|
.addrb ( dmem_addr[$clog2(SCR1_TCM_SIZE)-1:2] ),
|
115 |
|
|
.qb ( dmem_rdata_local ),
|
116 |
|
|
.datab ( dmem_writedata )
|
117 |
|
|
);
|
118 |
|
|
//-------------------------------------------------------------------------------
|
119 |
|
|
// Data memory output generation
|
120 |
|
|
//-------------------------------------------------------------------------------
|
121 |
|
|
always_ff @(posedge clk) begin
|
122 |
|
|
if (dmem_rd) begin
|
123 |
|
|
dmem_rdata_shift_reg <= dmem_addr[1:0];
|
124 |
|
|
end
|
125 |
|
|
end
|
126 |
|
|
|
127 |
|
|
assign dmem_rdata = dmem_rdata_local >> ( 8 * dmem_rdata_shift_reg );
|
128 |
|
|
|
129 |
|
|
endmodule : scr1_tcm
|
130 |
|
|
|
131 |
|
|
`endif // SCR1_TCM_EN
|