update BlackParrot transducer
[litex.git] / litex / soc / cores / cpu / blackparrot / bp_litex / bp2wb_convertor.v
1 /**
2 * bp2wb_convertor.v
3 * DESCRIPTION: THIS MODULE ADAPTS BP MEMORY BUS TO 64-BIT WISHBONE
4 */
5
6 module bp2wb_convertor
7 import bp_common_pkg::*;
8 import bp_common_aviary_pkg::*;
9 import bp_cce_pkg::*;
10 import bp_me_pkg::*;
11 #(parameter bp_params_e bp_params_p = e_bp_single_core_cfg
12 `declare_bp_proc_params(bp_params_p)
13 `declare_bp_me_if_widths(paddr_width_p, cce_block_width_p, lce_id_width_p, lce_assoc_p)
14
15 // , parameter [paddr_width_p-1:0] dram_offset_p = '0
16 , localparam num_block_words_lp = cce_block_width_p / 64
17 , localparam num_block_bytes_lp = cce_block_width_p / 8
18 , localparam num_word_bytes_lp = dword_width_p / 8
19 , localparam block_offset_bits_lp = `BSG_SAFE_CLOG2(num_block_bytes_lp)
20 , localparam word_offset_bits_lp = `BSG_SAFE_CLOG2(num_block_words_lp)
21 , localparam byte_offset_bits_lp = `BSG_SAFE_CLOG2(num_word_bytes_lp)
22 , localparam wbone_data_width = 64
23 , localparam wbone_addr_ubound = paddr_width_p
24 , localparam mem_granularity = 64 //TODO: adapt selection bit parametrized
25 , localparam wbone_addr_lbound = 3 //`BSG_SAFE_CLOG2(wbone_data_width / mem_granularity) //dword granularity
26 , localparam total_datafetch_cycle_lp = cce_block_width_p / wbone_data_width
27 , localparam total_datafetch_cycle_width = `BSG_SAFE_CLOG2(total_datafetch_cycle_lp)
28 , localparam cached_addr_base = 32'h7000_0000//6000_0000 //32'h4000_4000//
29 )
30 ( input clk_i
31 ,(* mark_debug = "true" *) input reset_i
32
33 // BP side
34 ,(* mark_debug = "true" *) input [cce_mem_msg_width_lp-1:0] mem_cmd_i
35 ,(* mark_debug = "true" *) input mem_cmd_v_i
36 ,(* mark_debug = "true" *) output mem_cmd_ready_o
37
38 , output [cce_mem_msg_width_lp-1:0] mem_resp_o
39 , (* mark_debug = "true" *) output mem_resp_v_o
40 , (* mark_debug = "true" *) input mem_resp_yumi_i
41
42 // Wishbone side
43 , (* mark_debug = "true" *) input [63:0] dat_i
44 , (* mark_debug = "true" *) output logic [63:0] dat_o
45 , (* mark_debug = "true" *) input ack_i
46 , input err_i
47 // , input rty_i
48 , (* mark_debug = "true" *) output logic [wbone_addr_ubound-wbone_addr_lbound-1:0] adr_o//TODO: Double check!!!
49 , (* mark_debug = "true" *) output logic stb_o
50 , output cyc_o
51 , output [7:0] sel_o //TODO: double check!!!
52 , (* mark_debug = "true" *) output we_o
53 , output [2:0] cti_o //TODO: hardwire in Litex
54 , output [1:0] bte_o //TODO: hardwire in Litex
55
56 );
57
58 `declare_bp_me_if(paddr_width_p, cce_block_width_p, lce_id_width_p, lce_assoc_p);
59
60 //locals
61 (* mark_debug = "true" *) logic [total_datafetch_cycle_width:0] ack_ctr = 0;
62 (* mark_debug = "true" *) bp_cce_mem_msg_s mem_cmd_cast_i, mem_resp_cast_o, mem_cmd_debug, mem_cmd_debug2;
63 (* mark_debug = "true" *) logic ready_li, v_li, stb_justgotack;
64 (* mark_debug = "true" *) logic [cce_block_width_p-1:0] data_lo;
65 (* mark_debug = "true" *) logic [cce_block_width_p-1:0] data_li;
66 (* mark_debug = "true" *) wire [paddr_width_p-1:0] mem_cmd_addr_l;
67 (* mark_debug = "true" *) logic set_stb;
68
69
70 //Handshaking between Wishbone and BlackParrot through convertor
71 //3.1.3:At every rising edge of [CLK_I] the terminating signal(ACK) is sampled. If it
72 //is asserted, then [STB_O] is negated.
73
74 assign ready_li = ( ack_ctr == 0 ) & !set_stb & !mem_resp_v_o;
75 assign mem_cmd_ready_o = ready_li;//!stb_o then ready to take!
76 // assign v_li = (ack_ctr == total_datafetch_cycle_lp-1);
77 assign mem_resp_v_o = v_li;
78 assign stb_o = (set_stb) && !stb_justgotack;
79 assign cyc_o = stb_o;
80 assign sel_o = 8'b11111111;
81 assign cti_o = 0;
82 assign bte_o = 0;
83
84 initial begin
85 ack_ctr = 0;
86 end
87
88
89 //Flip stb after each ack--->RULE 3.20:
90 // Every time we get an ACK from WB, increment counter until the counter reaches to total_datafetch_cycle_lp
91 always_ff @(posedge clk_i)
92 begin
93
94 if(reset_i)
95 begin
96 ack_ctr <= 0;
97 set_stb <= 0;
98 v_li <=0;
99 end
100 // else if (v_li)
101 // begin
102 else if (mem_resp_yumi_i)
103 begin
104 v_li <= 0;
105 ack_ctr <= 0;
106 end
107 // end
108 else if (mem_cmd_v_i)
109 begin
110 //data_li <= 0;
111 set_stb <= 1;
112 v_li <= 0;
113 stb_justgotack <= 0;
114 end
115
116 else
117 begin
118 if (ack_i)//stb should be negated after ack
119 begin
120 stb_justgotack <= 1;
121 data_li[(ack_ctr*wbone_data_width) +: wbone_data_width] <= dat_i;
122 if ((ack_ctr == total_datafetch_cycle_lp-1) || (mem_cmd_addr_l < cached_addr_base && mem_cmd_r.header.msg_type == e_cce_mem_uc_wr )) //if uncached store, just one cycle is fine
123 begin
124 v_li <=1;
125 set_stb <= 0;
126 end
127 else
128 ack_ctr <= ack_ctr + 1;
129 end
130 else
131 begin
132 stb_justgotack <= 0;
133 v_li <=0;
134 end
135 end
136 end
137
138 //Packet Pass from BP to BP2WB
139 assign mem_cmd_cast_i = mem_cmd_i;
140 bp_cce_mem_msg_s mem_cmd_r;
141 bsg_dff_reset_en
142 #(.width_p(cce_mem_msg_width_lp))
143 mshr_reg
144 (.clk_i(clk_i)
145 ,.reset_i(reset_i)
146 ,.en_i(mem_cmd_v_i)//when
147 ,.data_i(mem_cmd_i)
148 ,.data_o(mem_cmd_r)
149 );
150
151 //Addr && Data && Command Pass from BP2WB to WB
152 logic [wbone_addr_lbound-1:0] throw_away;
153 assign mem_cmd_addr_l = mem_cmd_r.header.addr;
154 assign data_lo = mem_cmd_r.data;
155 logic [39:0] mem_cmd_addr_l_zero64;
156 always_comb begin
157 if( mem_cmd_addr_l < cached_addr_base )
158 begin
159 adr_o = mem_cmd_addr_l[wbone_addr_ubound-1:wbone_addr_lbound];//no need to change address for uncached stores/loads
160 dat_o = data_lo[(0*wbone_data_width) +: wbone_data_width];//unchached data is stored in LS 64bits
161 end
162
163 else
164 begin
165 mem_cmd_addr_l_zero64 = mem_cmd_addr_l >> 6 << 6;
166 {adr_o,throw_away} = mem_cmd_addr_l_zero64 + (ack_ctr*8);//TODO:careful
167 dat_o = data_lo[(ack_ctr*wbone_data_width) +: wbone_data_width];
168 end
169 end
170
171 assign we_o = (mem_cmd_r.header.msg_type inside {e_cce_mem_uc_wr, e_cce_mem_wr});
172
173 //Data Pass from BP2WB to BP
174
175 wire [cce_block_width_p-1:0] rd_word_offset = mem_cmd_r.header.addr[3+:3];
176 //wire [cce_block_width_p-1:0] rd_byte_offset = mem_cmd_r.addr[0+:3];
177 wire [cce_block_width_p-1:0] rd_bit_shift = rd_word_offset*64; // We rely on receiver to adjust bits
178
179 (* mark_debug = "true" *) wire [cce_block_width_p-1:0] data_li_resp = (mem_cmd_r.header.msg_type == e_cce_mem_uc_rd)
180 ? data_li >> rd_bit_shift
181 : data_li;
182
183
184
185 assign mem_resp_cast_o = '{data : data_li_resp
186 ,header :'{payload : mem_cmd_r.header.payload
187 ,size : mem_cmd_r.header.size
188 ,addr : mem_cmd_r.header.addr
189 ,msg_type: mem_cmd_r.header.msg_type
190 }
191 };
192
193 assign mem_resp_o = mem_resp_cast_o;
194
195 /*********************************************/
196 /*DEBUG SECTION*/
197
198
199
200 /*wire [3:0] fake_msg_type;
201 wire [10:0] fake_payload;
202 wire [2:0] fake_size;
203 wire [39:0] fake_addr;
204 assign fake_payload = mem_cmd_r.header.payload;
205 assign fake_size = mem_cmd_r.header.size;
206 assign fake_addr = mem_cmd_r.header.addr;
207 assign fake_msg_type = mem_cmd_r.header.msg_type;
208 */
209 /*(* mark_debug = "true" *) logic debug_wire;
210 initial begin
211 debug_wire = 0;
212 end
213
214 assign mem_cmd_debug = mem_cmd_i;
215
216 always_ff @(posedge clk_i)
217 debug_wire <= (ack_i && mem_cmd_debug.header.addr >= 32'h80000000);
218
219 always_ff @(posedge clk_i)
220 begin
221 if(mem_cmd_v_i && mem_cmd_debug.header.addr <= 32'h60000000)
222 begin
223 debug_wire <= 1;
224 // $display("addr == %x", mem_cmd_debug.header.addr);
225 end
226 /* if (mem_resp_v_o && debug_ctr < 64 && mem_cmd_debug.header.addr >= 32'h80000000)
227 begin
228 debug_gotdata[((debug_ctr-1)*512) +: 512] <= data_li_resp;
229 $display("data == %x", data_li_resp);
230 end*/
231 // end
232
233 wire [3:0] typean;
234 assign typean = mem_cmd_r.header.msg_type;
235
236 endmodule
237