Forum: FPGA, VHDL & Co. Lattice Diamond: UART Receiver Siganl Wegoptimiert


von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

Kann mir jemand sagen, wieso in Diamond1.3 die uart_srx_i Signal 
komplett wegoptimiert wird?


1
// $Id: top_basic.v,v 1.2 2008/07/02 19:10:29 jfreed Exp $
2
3
4
module top  (   
5
   rstn,
6
   FLIP_LANES, LED_INV,
7
   
8
    
9
   refclkp, refclkn,
10
   hdinp, hdinn,                   
11
   hdoutp, hdoutn, 
12
13
   pll_lk, poll, l0, dl_up, usr0, usr1, usr2, usr3,
14
 //  na_pll_lk, na_poll, na_l0, na_dl_up, na_usr0, na_usr1, na_usr2, na_usr3,   // cngd frm org
15
   dip_switch,  uart_srx_i, led_out, dp
16
   );
17
18
input rstn;
19
input refclkp, refclkn;
20
input hdinp, hdinn;
21
output hdoutp, hdoutn;
22
23
// These two inputs are set in the .lpf file
24
input FLIP_LANES; // Flip PCIe lanes
25
input LED_INV;  // LED polarity inverted
26
27
28
output pll_lk, poll, l0, dl_up, usr0, usr1, usr2, usr3;
29
         // na_pll_lk, na_poll, na_l0, na_dl_up, na_usr0, na_usr1, na_usr2, na_usr3;   // cngd frm org
30
input [7:0] dip_switch;
31
output [13:0] led_out; // cngd frm org
32
output dp;
33
//output [15:0] TP;
34
//output [33:0] la;// cngd frm org
35
output uart_stx_o;
36
input uart_srx_i;
37
38
reg  [19:0] rstn_cnt;
39
reg  core_rst_n;
40
wire [13:0] led_out_int;
41
42
wire [3:0]               phy_ltssm_state; 
43
wire dl_up_int;
44
45
wire [15:0] rx_data, tx_data,  tx_dout_wbm, tx_dout_ur;
46
wire [6:0] rx_bar_hit;
47
48
wire [7:0] pd_num, pd_num_ur, pd_num_wb;
49
50
wire [15:0] pcie_dat_i, pcie_dat_o;
51
wire [31:0] pcie_adr;
52
wire [1:0] pcie_sel;  
53
wire [2:0] pcie_cti;
54
wire pcie_cyc;
55
wire pcie_we;
56
wire pcie_stb;
57
wire pcie_ack;
58
59
60
//------------ GPIO
61
wire [15:0] gpio_dat_i, gpio_dat_o;
62
wire [31:0] gpio_adr;
63
wire [1:0] gpio_sel;
64
wire [2:0] gpio_cti;
65
wire gpio_cyc;
66
wire gpio_we;
67
wire gpio_stb;
68
wire gpio_ack;
69
70
//------------ UART
71
wire [15:0] uart_dat_i, uart_dat_o;
72
wire [31:0] uart_adr;
73
wire [1:0] uart_sel;
74
wire [2:0] uart_cti;
75
wire uart_cyc;
76
wire uart_we;
77
wire uart_stb;
78
wire uart_ack;
79
80
//------------ EBR
81
wire [15:0] ebr_dat_i, ebr_dat_o;
82
wire [31:0] ebr_adr;
83
wire [1:0] ebr_sel;
84
wire [2:0] ebr_cti;
85
wire ebr_cyc;
86
wire ebr_we;
87
wire ebr_stb;
88
wire ebr_ack;
89
90
wire [7:0] bus_num ; 
91
wire [4:0] dev_num ; 
92
wire [2:0] func_num ;
93
94
95
wire [8:0] tx_ca_ph ;
96
wire [12:0] tx_ca_pd  ;
97
wire [8:0] tx_ca_nph ;
98
wire [12:0] tx_ca_npd ;
99
wire [8:0] tx_ca_cplh;
100
wire [12:0] tx_ca_cpld ;
101
wire clk_125;
102
wire tx_eop_wbm;
103
//=============================================================================
104
// Reset management
105
//=============================================================================
106
always @(posedge clk_125 or negedge rstn) begin
107
   if (!rstn) begin
108
       rstn_cnt   <= 20'd0 ;
109
       core_rst_n <= 1'b0 ;
110
   end
111
   else begin
112
      if (rstn_cnt[19])            // 4ms in real hardware
113
         core_rst_n <= 1'b1 ;
114
      // synthesis translate_off
115
         else if (rstn_cnt[7])     // 128 clocks 
116
            core_rst_n <= 1'b1 ;
117
      // synthesis translate_on
118
      else 
119
         rstn_cnt <= rstn_cnt + 1'b1 ;
120
   end
121
end
122
// LED Assignments
123
led_status led(.clk(clk_125), .rstn(core_rst_n), .invert(LED_INV),
124
        .lock(1'b1), .ltssm_state(phy_ltssm_state), .dl_up_in(dl_up_int), .bar1_hit(rx_bar_hit[1] | rx_bar_hit[0]),
125
        .pll_lk(pll_lk), .poll(poll), .l0(l0), .dl_up_out(dl_up), 
126
        .usr0(usr0), .usr1(usr1), .usr2(usr2), .usr3(usr3),
127
        .na_pll_lk(na_pll_lk), .na_poll(na_poll), .na_l0(na_l0), .na_dl_up_out(na_dl_up), 
128
        .na_usr0(na_usr0), .na_usr1(na_usr1), .na_usr2(na_usr2), .na_usr3(na_usr3), .dpn(dp)
129
);
130
131
132
pcie_top pcie(   
133
   .refclkp                    ( refclkp ),    
134
   .refclkn                    ( refclkn ),   
135
   .sys_clk_125                ( clk_125 ),
136
   .ext_reset_n                ( rstn ),
137
   .rstn                       ( core_rst_n ),    
138
   .flip_lanes                 ( FLIP_LANES ),
139
                               
140
   .hdinp0                     ( hdinp ), 
141
   .hdinn0                     ( hdinn ), 
142
   .hdoutp0                    ( hdoutp ), 
143
   .hdoutn0                    ( hdoutn ), 
144
                               
145
   .msi                        (  8'd0 ),
146
   .inta_n                     (  1'b1 ),
147
   
148
   // This PCIe interface uses dynamic IDs. 
149
   .vendor_id                  (16'h1204),       
150
   .device_id                  (16'hec30),       
151
   .rev_id                     (8'h00),          
152
   .class_code                 (24'h000000),      
153
   .subsys_ven_id              (16'h1204),   
154
   .subsys_id                  (16'h3010),       
155
   .load_id                    (1'b1),         
156
   
157
   
158
   // Inputs
159
   .force_lsm_active           ( 1'b0 ), 
160
   .force_rec_ei               ( 1'b0 ),     
161
   .force_phy_status           ( 1'b0 ), 
162
   .force_disable_scr          ( 1'b0 ),
163
                               
164
   .hl_snd_beacon              ( 1'b0 ),
165
   .hl_disable_scr             ( 1'b0 ),
166
   .hl_gto_dis                 ( 1'b0 ),
167
   .hl_gto_det                 ( 1'b0 ),
168
   .hl_gto_hrst                ( 1'b0 ),
169
   .hl_gto_l0stx               ( 1'b0 ),
170
   .hl_gto_l1                  ( 1'b0 ),
171
   .hl_gto_l2                  ( 1'b0 ),
172
   .hl_gto_l0stxfts            ( 1'b0 ),
173
   .hl_gto_lbk                 ( 1'd0 ),
174
   .hl_gto_rcvry               ( 1'b0 ),
175
   .hl_gto_cfg                 ( 1'b0 ),
176
   .no_pcie_train              ( 1'b0 ),    
177
178
   // Power Management Interface
179
   .tx_dllp_val                ( 2'd0 ),
180
   .tx_pmtype                  ( 3'd0 ),
181
   .tx_vsd_data                ( 24'd0 ),
182
183
   .tx_req_vc0                 ( tx_req ),    
184
   .tx_data_vc0                ( tx_data ),    
185
   .tx_st_vc0                  ( tx_st ), 
186
   .tx_end_vc0                 ( tx_end ), 
187
   .tx_nlfy_vc0                ( 1'b0 ), 
188
   .ph_buf_status_vc0       ( 1'b0 ),
189
   .pd_buf_status_vc0       ( 1'b0 ),
190
   .nph_buf_status_vc0      ( 1'b0 ),
191
   .npd_buf_status_vc0      ( 1'b0 ),
192
   .ph_processed_vc0        ( ph_cr ),
193
   .pd_processed_vc0        ( pd_cr ),
194
   .nph_processed_vc0       ( nph_cr ),
195
   .npd_processed_vc0       ( npd_cr ),
196
   .pd_num_vc0              ( pd_num ),
197
   .npd_num_vc0             ( 8'd1 ),   
198
   
199
200
   // From User logic
201
   .cmpln_tout                 ( 1'b0 ),       
202
   .cmpltr_abort_np            ( 1'b0 ),
203
   .cmpltr_abort_p             ( 1'b0 ),
204
   .unexp_cmpln                ( 1'b0 ),
205
   .ur_np_ext                  ( 1'b0 ),       
206
   .ur_p_ext                   ( 1'b0 ),
207
   .np_req_pend                ( 1'b0 ),     
208
   .pme_status                 ( 1'b0 ),      
209
         
210
   .tx_dllp_sent               (  ),
211
   .rxdp_pmd_type              (  ),
212
   .rxdp_vsd_data              (  ),
213
   .rxdp_dllp_val              (  ),
214
  
215
 
216
   .phy_ltssm_state            ( phy_ltssm_state ),     
217
   .phy_ltssm_substate         ( ),     
218
   .phy_pol_compliance         ( ),   
219
220
   .tx_rdy_vc0                 ( tx_rdy),  
221
   .tx_ca_ph_vc0               ( tx_ca_ph),
222
   .tx_ca_pd_vc0               ( tx_ca_pd),
223
   .tx_ca_nph_vc0              ( tx_ca_nph),
224
   .tx_ca_npd_vc0              ( tx_ca_npd ), 
225
   .tx_ca_cplh_vc0             ( tx_ca_cplh ),
226
   .tx_ca_cpld_vc0             ( tx_ca_cpld ),
227
   .tx_ca_p_recheck_vc0        ( tx_ca_p_recheck ),
228
   .tx_ca_cpl_recheck_vc0      ( tx_ca_cpl_recheck ),
229
   .rx_data_vc0                ( rx_data),    
230
   .rx_st_vc0                  ( rx_st),     
231
   .rx_end_vc0                 ( rx_end),   
232
   .rx_us_req_vc0              ( rx_us_req ), 
233
   .rx_malf_tlp_vc0            ( rx_malf_tlp ), 
234
   .rx_bar_hit                 ( rx_bar_hit ), 
235
   .mm_enable                  (  ),
236
   .msi_enable                 (  ),
237
238
   // From Config Registers
239
   .bus_num                    ( bus_num  ),           
240
   .dev_num                    ( dev_num  ),           
241
   .func_num                   ( func_num  ),  
242
   .pm_power_state             (  ) , 
243
   .pme_en                     (  ) , 
244
   .cmd_reg_out                (  ),
245
   .dev_cntl_out               (  ),  
246
   .lnk_cntl_out               (  ),  
247
248
   .tx_rbuf_empty              (  ),   // Transmit retry buffer is empty
249
   .tx_dllp_pend               (  ),    // DLPP is pending to be transmitted
250
   .rx_tlp_rcvd                (  ),     // Received a TLP   
251
252
   // Datal Link Control SM Status
253
   .dl_inactive                (  ),
254
   .dl_init                    (  ),
255
   .dl_active                  (  ),
256
   .dl_up                      ( dl_up_int )   
257
);
258
reg rx_st_d;
259
reg tx_st_d;
260
reg [15:0] tx_tlp_cnt;
261
reg [15:0] rx_tlp_cnt;
262
always @(posedge clk_125 or negedge core_rst_n)
263
   if (!core_rst_n) begin
264
      tx_st_d <= 0;
265
      rx_st_d <= 0;
266
      tx_tlp_cnt <= 0;
267
      rx_tlp_cnt <= 0;
268
   end
269
   else begin
270
      tx_st_d <= tx_st;
271
      rx_st_d <= rx_st;
272
      if (tx_st_d) tx_tlp_cnt <= tx_tlp_cnt + 1;
273
      if (rx_st_d) rx_tlp_cnt <= rx_tlp_cnt + 1;
274
         
275
   end
276
277
ip_rx_crpr cr (.clk(clk_125), .rstn(core_rst_n), .rx_bar_hit(rx_bar_hit),
278
               .rx_st(rx_st), .rx_end(rx_end), .rx_din(rx_data),
279
               .pd_cr(pd_cr_ur), .pd_num(pd_num_ur), .ph_cr(ph_cr_ur), .npd_cr(npd_cr_ur), .nph_cr(nph_cr_ur)               
280
);
281
282
ip_crpr_arb crarb(.clk(clk_125), .rstn(core_rst_n), 
283
            .pd_cr_0(pd_cr_ur), .pd_num_0(pd_num_ur), .ph_cr_0(ph_cr_ur), .npd_cr_0(npd_cr_ur), .nph_cr_0(nph_cr_ur),
284
            .pd_cr_1(pd_cr_wb), .pd_num_1(pd_num_wb), .ph_cr_1(ph_cr_wb), .npd_cr_1(1'b0), .nph_cr_1(nph_cr_wb),               
285
            .pd_cr(pd_cr), .pd_num(pd_num), .ph_cr(ph_cr), .npd_cr(npd_cr), .nph_cr(nph_cr)               
286
);
287
288
UR_gen ur (.clk(clk_125), .rstn(core_rst_n),  
289
            .rx_din(rx_data), .rx_sop(rx_st), .rx_eop(rx_end), .rx_us(rx_us_req), .rx_bar_hit(rx_bar_hit),
290
             .tx_rdy(tx_rdy_ur), .tx_ca_cpl_recheck(1'b0), .tx_ca_cplh(tx_ca_cplh),
291
             .tx_req(tx_req_ur), .tx_dout(tx_dout_ur), .tx_sop(tx_sop_ur), .tx_eop(tx_eop_ur),
292
             .comp_id({bus_num, dev_num, func_num})
293
);
294
         
295
ip_tx_arbiter #(.c_DATA_WIDTH (16))
296
           tx_arb(.clk(clk_125), .rstn(core_rst_n), .tx_val(1'b1),
297
                  .tx_req_0(tx_req_wbm), .tx_din_0(tx_dout_wbm), .tx_sop_0(tx_sop_wbm), .tx_eop_0(tx_eop_wbm), .tx_dwen_0(1'b0),                 
298
                  .tx_req_1(1'b0), .tx_din_1(16'd0), .tx_sop_1(1'b0), .tx_eop_1(1'b0), .tx_dwen_1(1'b0),
299
                  .tx_req_2(1'b0), .tx_din_2(16'd0), .tx_sop_2(1'b0), .tx_eop_2(1'b0), .tx_dwen_2(1'b0),
300
                  .tx_req_3(tx_req_ur), .tx_din_3(tx_dout_ur), .tx_sop_3(tx_sop_ur), .tx_eop_3(tx_eop_ur), .tx_dwen_3(1'b0),
301
                  .tx_rdy_0(tx_rdy_wbm), .tx_rdy_1(), .tx_rdy_2( ), .tx_rdy_3(tx_rdy_ur),
302
                  .tx_req(tx_req), .tx_dout(tx_data), .tx_sop(tx_st), .tx_eop(tx_end), .tx_dwen(),
303
                  .tx_rdy(tx_rdy)
304
                  
305
);                           
306
307
wb_tlc wb_tlc(.clk_125(clk_125), .wb_clk(clk_125), .rstn(core_rst_n),
308
              .rx_data(rx_data), .rx_st(rx_st), .rx_end(rx_end), .rx_bar_hit(rx_bar_hit),
309
              .wb_adr_o(pcie_adr), .wb_dat_o(pcie_dat_o), .wb_cti_o(pcie_cti), .wb_we_o(pcie_we), .wb_sel_o(pcie_sel), .wb_stb_o(pcie_stb), .wb_cyc_o(pcie_cyc), .wb_lock_o(), 
310
              .wb_dat_i(pcie_dat_i), .wb_ack_i(pcie_ack),
311
              .pd_cr(pd_cr_wb), .pd_num(pd_num_wb), .ph_cr(ph_cr_wb), .npd_cr(npd_cr_wb), .nph_cr(nph_cr_wb),
312
              .tx_rdy(tx_rdy_wbm),
313
              .tx_req(tx_req_wbm), .tx_data(tx_dout_wbm), .tx_st(tx_sop_wbm), .tx_end(tx_eop_wbm), .tx_ca_cpl_recheck(1'b0), .tx_ca_cplh(tx_ca_cplh), .tx_ca_cpld(tx_ca_cpld),
314
              .comp_id({bus_num, dev_num, func_num}),
315
              .debug()
316
);
317
318
319
wb_arb #(.c_DATA_WIDTH(16),
320
         .S0_BASE     (32'h0000), //GPIO
321
         .S1_BASE     (32'h4000), // UART
322
         .S2_BASE     (32'h1000), //EBR
323
         .S3_BASE     (32'h5000)
324
) wb_arb (
325
    .clk(clk_125),
326
    .rstn(core_rst_n),
327
  
328
    // PCIe Master 
329
    .m0_dat_i(pcie_dat_o), 
330
    .m0_dat_o(pcie_dat_i), 
331
    .m0_adr_i(pcie_adr),
332
    .m0_sel_i(pcie_sel), 
333
    .m0_we_i(pcie_we), 
334
    .m0_cyc_i(pcie_cyc),
335
    .m0_cti_i(pcie_cti),
336
    .m0_stb_i(pcie_stb), 
337
    .m0_ack_o(pcie_ack), 
338
    .m0_err_o(), 
339
    .m0_rty_o(), 
340
    
341
    // DMA Master  //  // not used
342
    .m1_dat_i(16'd0), 
343
    .m1_dat_o(), 
344
    .m1_adr_i(32'd0),
345
    .m1_sel_i(2'd0), 
346
    .m1_we_i( 1'b0), 
347
    .m1_cyc_i(1'b0),
348
    .m1_cti_i(3'd0),
349
    .m1_stb_i(1'b0), 
350
    .m1_ack_o(), 
351
    .m1_err_o(), 
352
    .m1_rty_o(),         
353
354
    // GPIO 32-bit
355
    .s0_dat_i(gpio_dat_o), 
356
    .s0_dat_o(gpio_dat_i), 
357
    .s0_adr_o(gpio_adr), 
358
    .s0_sel_o(gpio_sel), 
359
    .s0_we_o (gpio_we), 
360
    .s0_cyc_o(gpio_cyc),
361
    .s0_cti_o (gpio_cti),
362
    .s0_stb_o(gpio_stb), 
363
    .s0_ack_i(gpio_ack), 
364
    .s0_err_i(gpio_err),
365
    .s0_rty_i(gpio_rty), 
366
    
367
    // UART Slave
368
    .s1_dat_i(uart_dat_o), 
369
    .s1_dat_o(uart_dat_i), 
370
    .s1_adr_o(uart_adr), 
371
    .s1_sel_o(uart_sel), 
372
    .s1_we_o (uart_we), 
373
    .s1_cyc_o(uart_cyc),
374
    .s1_cti_o(uart_cti),
375
    .s1_stb_o(uart_stb), 
376
    .s1_ack_i(uart_ack), 
377
    .s1_err_i(1'b0),
378
    .s1_rty_i(1'b0),
379
    
380
    // EBR
381
    .s2_dat_i(ebr_dat_o), 
382
    .s2_dat_o(ebr_dat_i), 
383
    .s2_adr_o(ebr_adr), 
384
    .s2_sel_o(ebr_sel), 
385
    .s2_we_o (ebr_we), 
386
    .s2_cyc_o(ebr_cyc),
387
    .s2_cti_o(ebr_cti),
388
    .s2_stb_o(ebr_stb), 
389
    .s2_ack_i(ebr_ack), 
390
    .s2_err_i(ebr_err),
391
    .s2_rty_i(ebr_rty),
392
    
393
    // Not used
394
    .s3_dat_i(16'd0), 
395
    .s3_dat_o(), 
396
    .s3_adr_o(), 
397
    .s3_sel_o(), 
398
    .s3_we_o (), 
399
    .s3_cyc_o(),
400
    .s3_cti_o(),
401
    .s3_stb_o(), 
402
    .s3_ack_i(1'b0),
403
    .s3_rty_i(1'b0), 
404
    .s3_err_i(1'b0)
405
);
406
407
408
             
409
wbs_gpio gpio(.wb_clk_i(clk_125), .wb_rst_i(~core_rst_n),
410
          .wb_dat_i(gpio_dat_i), .wb_adr_i(gpio_adr[8:0]), .wb_cti_i(gpio_cti), .wb_cyc_i(gpio_cyc), .wb_lock_i(1'b0), .wb_sel_i(gpio_sel), .wb_stb_i(gpio_stb), .wb_we_i(gpio_we),          
411
          .wb_dat_o(gpio_dat_o), .wb_ack_o(gpio_ack), .wb_err_o(gpio_err), .wb_rty_o(gpio_rty), 
412
          .switch_in(dip_switch), .led_out(led_out_int), 
413
          .dma_req(dma_req_gpio), .dma_ack(5'd0), 
414
          .ca_pd(tx_ca_pd), .ca_nph(tx_ca_nph), .dl_up(dl_up_int),
415
          .int_out()
416
);
417
assign led_out = ~led_out_int[13:0];          
418
419
420
wbs_uart uart(
421
      //wishbone signals
422
      .wb_clk_i(clk_125), 
423
      .wb_rst_i(~core_rst_n),
424
          .wb_dat_i(uart_dat_i), 
425
      .wb_adr_i(uart_adr), 
426
      .wb_cti_i(uart_cti), 
427
      .wb_cyc_i(uart_cyc), 
428
      .wb_lock_i(1'b0), 
429
      .wb_sel_i(uart_sel), .wb_stb_i(uart_stb), .wb_we_i(uart_we),          
430
          .wb_dat_o(uart_dat_o), .wb_ack_o(uart_ack), 
431
      .wb_err_o(uart_err), 
432
      .wb_rty_o(uart_rty), 
433
      
434
      //uart signals
435
      .stx_pad_o(), 
436
      .srx_pad_i(uart_srx_i), 
437
438
      //modem signals
439
      //.rts_pad_o(), .cts_pad_i(), .dtr_pad_o(), .dsr_pad_i(), .ri_pad_i(), .dcd_pad_i(),
440
441
      //interrupt
442
          .wb_int_o(int)
443
);
444
445
446
wbs_32kebr ebr(.wb_clk_i(clk_125), .wb_rst_i(~core_rst_n),
447
          .wb_dat_i(ebr_dat_i), .wb_adr_i(ebr_adr), .wb_cyc_i(ebr_cyc), .wb_sel_i(ebr_sel), .wb_stb_i(ebr_stb), .wb_we_i(ebr_we), .wb_cti_i(ebr_cti),
448
          .wb_dat_o(ebr_dat_o), .wb_ack_o(ebr_ack), .wb_err_o(ebr_err), .wb_rty_o(ebr_rty)          
449
);                          
450
  
451
452
453
// DEBUG OUPUT OPTIONS
454
//assign la = 34'd0; // cngd frm org
455
//assign TP = 16'd0;
456
                  
457
                
458
459
460
461
endmodule

Grüsse,
Henry

von Lattice User (Gast)


Lesenswert?

Wo hast du wbs_uart her?

von Keller T. (fabito)


Lesenswert?

Hallo,

Ich habe den Grund herausgefunden.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Ngii Rayan schrieb:
> Ich habe den Grund herausgefunden.
Schön.
Aber viel schöner wäre es, wenn du auch noch schreiben würdest, WAS es 
war. Immerhin könnte dein Wissen jemand Anderem später mal 
weiterhelfen...

von Keller T. (fabito)


Lesenswert?

Hallo,

Das Problem lag an Wishbone Arbiter.Also einfach UART als Slave 0 wird 
es gelöst:

    // UART Slave
    .s0_dat_i(uart_dat_o),
    .s0_dat_o(uart_dat_i),
    .s0_adr_o(uart_adr),
    .s0_sel_o(uart_sel),
    .s0_we_o (uart_we),
    .s0_cyc_o(uart_cyc),
    .s0_cti_o(uart_cti),
    .s0_stb_o(uart_stb),
    .s0_ack_i(uart_ack),
    .s0_err_i(1'b0),
    .s0_rty_i(1'b0),

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> Das Problem lag an Wishbone Arbiter.Also einfach UART als Slave 0 wird
> es gelöst:

Falsche Lösung, denn das Problem wird wieder auftauchen.

Ich habe mit den Arbiter angeschaut, die Slave Addressen müssen in 
aufsteigender Reihenfolge sein.

z.B:

         .S0_BASE     (32'h0000), //GPIO
         .S1_BASE     (32'h0800), // UART
         .S2_BASE     (32'h1000), //EBR
         .S3_BASE     (32'h5000)

von Keller T. (fabito)


Lesenswert?

Ich gebe dir Recht!
Stimmt tauscht das Problem wieder bei mehrere Komponente. Nur wollte ich 
in meinem Fall nur UART Komponent testen.
Aber gilt deine Lösung allgemein für mehrere Komponente.

von Keller T. (fabito)


Lesenswert?

Ich habe gerade deine Lösung getestet.
Leider tauscht wieder das Problem aus.
1
wb_arb #(.c_DATA_WIDTH(16),
2
         .S0_BASE     (32'h0000), // UART Slave
3
         .S1_BASE     (32'h0800), // GPIO
4
         .S2_BASE     (32'h1000), //EBR
5
         .S3_BASE     (32'h5000)
6
) wb_arb (
7
    .clk(clk_125),
8
    .rstn(core_rst_n),
9
  
10
    // PCIe Master 
11
    .m0_dat_i(pcie_dat_o), 
12
    .m0_dat_o(pcie_dat_i), 
13
    .m0_adr_i(pcie_adr),
14
    .m0_sel_i(pcie_sel), 
15
    .m0_we_i(pcie_we), 
16
    .m0_cyc_i(pcie_cyc),
17
    .m0_cti_i(pcie_cti),
18
    .m0_stb_i(pcie_stb), 
19
    .m0_ack_o(pcie_ack), 
20
    .m0_err_o(), 
21
    .m0_rty_o(), 
22
    
23
    // DMA Master  //  // not used
24
    .m1_dat_i(16'd0), 
25
    .m1_dat_o(), 
26
    .m1_adr_i(32'd0),
27
    .m1_sel_i(2'd0), 
28
    .m1_we_i( 1'b0), 
29
    .m1_cyc_i(1'b0),
30
    .m1_cti_i(3'd0),
31
    .m1_stb_i(1'b0), 
32
    .m1_ack_o(), 
33
    .m1_err_o(), 
34
    .m1_rty_o(),         
35
36
    // GPIO 32-bit
37
    .s1_dat_i(gpio_dat_o), 
38
    .s1_dat_o(gpio_dat_i), 
39
    .s1_adr_o(gpio_adr), 
40
    .s1_sel_o(gpio_sel), 
41
    .s1_we_o (gpio_we), 
42
    .s1_cyc_o(gpio_cyc),
43
    .s1_cti_o (gpio_cti),
44
    .s1_stb_o(gpio_stb), 
45
    .s1_ack_i(gpio_ack), 
46
    .s1_err_i(gpio_err),
47
    .s1_rty_i(gpio_rty), 
48
    
49
    // UART Slave
50
    .s0_dat_i(uart_dat_o), 
51
    .s0_dat_o(uart_dat_i), 
52
    .s0_adr_o(uart_adr), 
53
    .s0_sel_o(uart_sel), 
54
    .s0_we_o (uart_we), 
55
    .s0_cyc_o(uart_cyc),
56
    .s0_cti_o(uart_cti),
57
    .s0_stb_o(uart_stb), 
58
    .s0_ack_i(uart_ack), 
59
    .s0_err_i(1'b0),
60
    .s0_rty_i(1'b0),
61
    
62
    // EBR
63
    .s2_dat_i(ebr_dat_o), 
64
    .s2_dat_o(ebr_dat_i), 
65
    .s2_adr_o(ebr_adr), 
66
    .s2_sel_o(ebr_sel), 
67
    .s2_we_o (ebr_we), 
68
    .s2_cyc_o(ebr_cyc),
69
    .s2_cti_o(ebr_cti),
70
    .s2_stb_o(ebr_stb), 
71
    .s2_ack_i(ebr_ack), 
72
    .s2_err_i(ebr_err),
73
    .s2_rty_i(ebr_rty),
74
);

Es fehlt noch etwas damit alles 100% klappt

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> Es fehlt noch etwas damit alles 100% klappt

Mein Fehler, habe übersehen dass der Arbiter nur Adr[31:12] vergleicht.

Also:
1
         .S0_BASE     (32'h0000), //GPIO
2
         .S1_BASE     (32'h1000), // UART
3
         .S2_BASE     (32'h2000), //EBR
4
         .S3_BASE     (32'h5000)

von Keller T. (fabito)


Lesenswert?

Genau das meinte ich !

Nun zum UART Test unter Linux: Hat jemand eine Idee warum ich meine GPIO 
Problemlos schreiben/lesen kann aber nicht meine UART Komponent?
1
[root@localhost pci_sample_2]# ./regrw ECP3_SFIF_1
2
User Space Lattice PCIe device driver using mmap
3
Board ECP3_SFIF_1
4
Opening access to lscpcie/ECP3_SFIF_1
5
fd = 2
6
pmem=0xb77eb000
7
*p0 = b77eb000  
8
9
Register Read/Write Access
10
r - read a 32 bit register
11
w - write a 32 bit value into a register
12
addresses are on 4 byte boundaries
13
q,x - exit
14
r|w <addr> [data]: w 0008 0000ffff     // ON LEDs 
15
r|w <addr> [data]: r 0008 0000ffff
16
00000008: 0xffff
17
r|w <addr> [data]: w 0008 00000000    // OFF LEDs


Aber das gleiche Verfahren kalppt nicht zum UART Zugriff:
Also
1
r|w <addr> [data]: w 1010 0000ffff     // UART Write to IER Register
2
r|w <addr> [data]: r 1000 0000ffff 
3
00001010:0x0                           // adress 1000: Rx/Tx Register

bin ich auf dem falschen Weg oder wie?

von Lattice User (Gast)


Lesenswert?

Ich muss nochmal fragen, wo hast du wbs_uart her? Selbstgemacht?
Im Versakit, von dem du den toplevel wohl her hast, ist es jedenfalls 
nicht enthalten.

von Keller T. (fabito)


Lesenswert?

Ja !

wbs_uart.v entpricht einfach uart_top.v von Opencore was ich mit Lattice 
Mico32 erfolgsreich getestet habe.
Also habe ich nur die toplevel Dateiename umbennant zur klarheit für das 
gesamte Projekt.

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> wbs_uart.v entpricht einfach uart_top.v von Opencore was ich mit Lattice
> Mico32 erfolgsreich getestet habe.

Und welcher der vielen UARTS, die es dort gibt? Setze doch einfach mal 
einen Link.

Du hast natürlich die Unterschiede in der Addressierung und 
Datenbusbreite beachtet?

von Keller T. (fabito)


Lesenswert?

Here ist der Link: http://opencores.org/project,uart16550

Unter uart_defines.v sind Data und Adress Breite definiert:
1
// remove comments to restore to use the new version with 8 data bit interface
2
// in 32bit-bus mode, the wb_sel_i signal is used to put data in correct place
3
// also, in 8-bit version there'll be no debugging features included
4
// CAUTION: doesn't work with current version of OR1200
5
//`define DATA_BUS_WIDTH_8
6
7
`ifdef DATA_BUS_WIDTH_8
8
 `define UART_ADDR_WIDTH 3
9
 `define UART_DATA_WIDTH 8
10
`else
11
 `define UART_ADDR_WIDTH 5
12
 `define UART_DATA_WIDTH 32
13
`endif
14
15
Mit LatticeMico System hat folgende zu Lattice Mico32 CPU geklappt:
16
17
[vhdl]
18
opencoreuart2 
19
 opencoreuart2( 
20
.wb_ADR_I(SHAREDBUS_ADR_I[31:0]),
21
.wb_DAT_I(opencoreuart2wb_DAT_I[31:0]),
22
.wb_DAT_O(opencoreuart2wb_DAT_O[31:0]),
23
.wb_SEL_I(opencoreuart2wb_SEL_I[3:0]),
24
.wb_WE_I(SHAREDBUS_WE_I),
25
.wb_ACK_O(opencoreuart2wb_ACK_O),
26
.wb_ERR_O(opencoreuart2wb_ERR_O),
27
.wb_RTY_O(opencoreuart2wb_RTY_O),
28
.wb_CTI_I(SHAREDBUS_CTI_I),
29
.wb_BTE_I(SHAREDBUS_BTE_I),
30
.wb_LOCK_I(SHAREDBUS_LOCK_I),
31
.wb_CYC_I(SHAREDBUS_CYC_I & opencoreuart2wb_en),
32
.wb_STB_I(SHAREDBUS_STB_I & opencoreuart2wb_en),
33
.srx_pad_i(opencoreuart2srx_pad_i),
34
.stx_pad_o(opencoreuart2stx_pad_o),
35
.wb_int_o(opencoreuart2wb_int_o),
36
.wb_clk_i(clk_i), .wb_rst_i(sys_reset));

Und nun versuche ich folgende
1
//------------ UART
2
wire [31:0] uart_dat_i, uart_dat_o;
3
wire [31:0] uart_adr;
4
wire [1:0] uart_sel;
5
wire [2:0] uart_cti;
6
wire uart_cyc;
7
wire uart_we;
8
wire uart_stb;
9
wire uart_ack;
10
11
.....
12
13
wbs_uart uart(
14
      //wishbone signals
15
      .wb_clk_i(clk_125), 
16
      .wb_rst_i(~core_rst_n),
17
          .wb_dat_i(uart_dat_i), 
18
      .wb_adr_i(uart_adr), 
19
      //.wb_cti_i(uart_cti), 
20
      .wb_cyc_i(uart_cyc), 
21
      //.wb_lock_i(1'b0), 
22
      .wb_sel_i(uart_sel), .wb_stb_i(uart_stb), .wb_we_i(uart_we),          
23
          .wb_dat_o(uart_dat_o), .wb_ack_o(uart_ack), 
24
      //.wb_err_o(uart_err), 
25
      //.wb_rty_o(uart_rty), 
26
      
27
      
28
      //uart signals
29
      .stx_pad_o(uart_stx_o), 
30
      .srx_pad_i(uart_srx_i), 
31
32
      //modem signals
33
      //.rts_pad_o(), .cts_pad_i(), .dtr_pad_o(), .dsr_pad_i(), .ri_pad_i(), .dcd_pad_i(),
34
35
      //interrupt
36
          .int_o(int)
37
);

von Lattice User (Gast)


Lesenswert?

Das geht so nicht.

Dein WB Datenbus ist 16bit breit (im Gegensatz zum Mico32).

Vom PC werden bei PCIe immer 32bit Zugriffe durchgeführt, dabei sind die 
Addressbits 0 und 1 immer auf 0 und zu ignorieren. Byteauswahl erfolgt 
durch Byte enables.

Der wb_tlc (PCIe -> Wishbone) Module übersetzt JEDEN PCIe Zugriff in 
ZWEI Wishbone cycles, wobei die Adresse um 2 incrementiert wird. Dieses 
Verhalten muss in deinem Slave berücksichtigt werden.

Sowas schaut man sich natürlich am besten in einer Simulation an. Da 
aber das Aufsetzen und schreiben einer PCIe testbench nicht einfach ist, 
bietet sich als Alternative auch Reveal an.

von Keller T. (fabito)


Lesenswert?

Ich habe einen ersten Experiment mit Reveal gemacht und sie sehr 
nutzlich aus.
Was mir noch unklar ist folgende:

Der wb_tlc (PCIe -> Wishbone) Module übersetzt JEDEN PCIe Zugriff in
ZWEI Wishbone cycles für wishbone Slaves.

Meine Meinung: Stimmt aber nur wenn es um einen 32 bit Daten 
Übertragung.

Das ist beispielweise der Fall beim Zugriff auf 32 bit GPIO Register 
(Versa) und Byteauswahl erfolgt  durch wb_sel_i[0/1], wobei die Adresse 
um 2 incrementiert wird.
1
.....
2
assign wb_dat_o = wb_dat_local;
3
.....
4
5
      9'h004: begin
6
         if (rd) wb_dat_local <= scratch_pad[15:0];
7
         else if (wr) begin
8
            scratch_pad[15:8] <= wb_sel_i[0] ? wb_dat_i[15:8] : scratch_pad[15:8];
9
            scratch_pad[7:0]  <= wb_sel_i[1] ? wb_dat_i[7:0]  : scratch_pad[7:0];
10
         end
11
      end
12
      9'h006: begin
13
         if (rd) wb_dat_local <= scratch_pad[31:16];
14
         else if (wr) begin
15
            scratch_pad[31:24] <= wb_sel_i[0] ? wb_dat_i[15:8] : scratch_pad[31:24];
16
            scratch_pad[23:16] <= wb_sel_i[1] ? wb_dat_i[7:0]  : scratch_pad[23:16];
17
         end
18
      end

Nun meine Frage wie wäre falls PCIe TLP nur 8 bits schreiben/lesen soll? 
(8/16 Slave Devices). Der wb_tlc (PCIe -> Wishbone) Module in diesem 
Fall nur wb_sel_i[0] braucht um es zu machen. Folglich keine Adresse 
incrementierung .

Das ist der Fall für Opencore UART/CAN die 8 Bit Daten sind .Was 
bedeutet jeder Register vom Host über TLP Packet mit 8 Bits 
lesbar/schreibar ist .
1
9'h000: begin // Transmit/Receive Register
2
         if (rd) wb_dat_local <= receiv_reg[7:0];
3
         else if (wr) begin
4
            transmit_reg[7:0] <= wb_dat_i[7:0];
5
         end
6
9'h001: begin // Interrupt Enable Register
7
         if (rd) wb_dat_local <= int_enable_reg[7:0];
8
         else if (wr) begin
9
            int_enable_reg[7:0] <= wb_dat_i[7:0];
10
         end
11
.....

oder bin ich falsh !

von Franke (Gast)


Lesenswert?

siehe oben

>Vom PC werden bei PCIe immer 32bit Zugriffe durchgeführt

und das ist so...

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> Meine Meinung: Stimmt aber nur wenn es um einen 32 bit Daten
> Übertragung.

Meinungen zählen hier nicht. Im Versa Kit ist der wb_tlc in source form 
enthalten. Schau ihn dir an.
(die WB Schreibzyklen werden in wb_tlc/wb_intf.v Zeile 179-218 
generiert.)

Nochmal, es gibt KEINE 8bit TLPs. TLPs sind IMMER vielfache von 4 Bytes, 
auch
wenn die PC einen 8 bit Zugriff macht. Dafür gibt es die wb_sel Signale.


Das gleiche Problem hast du übrigens wenn du ein 8 bit Slave (OpenCan) 
an einen 32bit Master anschliesst (Mico32).

von Keller T. (fabito)


Lesenswert?

OK !

Da bedeutet in Lattice Fall: TLP Daten max = 1 DW (allgemein PCIe bis 
1024 DW möglich)
also
Length = 0x001

und um die benotige Byte zu wissen werden First DW Byte Enables und Last 
DW Byte Enables gebraucht also

bei 32 bits Datentransfer :Last BE = 0x0 und First BE = 0xf(1111)

bei 16 bits Datentransfer :Last BE = 0x0 und First BE = 0x3 (0011)

bei 8 bits Datentransfer :Last BE = 0x0 und First BE = 0x1 (0001)


Nun zu 8 bit Slave (OpenCan) an einen 32bit Master anschliesst (Mico32):

 bei 8 bit Opencore UART (beinhaltet ein sel_i Signal )also wurde kein 
Problem fesgestellt.

 aber mit 8 bit Opencore CAN(beinhaltet kein sel_i Signal ):lässt sich 
Read/Write Operationen mit Mico32 ausführen .

  Dies Problem lässt sich mit ALTERA mit dem 8 Bit Befehl IOWR_8DIRECT 
lösen auch wenn NIOS 32 bit ist.

  Wie wird es nun ohne sel_i Signal von Opencore CAN gelöst oder gibt es 
eine Opencore CAN Variante mit sel_i Signale?

von Lattice User (Gast)


Angehängte Dateien:

Lesenswert?

Ngii Rayan schrieb:
> Da bedeutet in Lattice Fall: TLP Daten max = 1 DW (allgemein PCIe bis
> 1024 DW möglich)
> also
> Length = 0x001

Wenn ich es richtig sehe unterstützt wb_tlc auch längere TLP, es werden 
dann halt auch entsprechend viele WB Zyklen erzeugt.

Allerdings erzeugt die CPU in einem PC bei Memorymapped IO  nur TLPs mit 
max 4 Bytes Payload, eventuell verteilt auf 2 DW. (Siehe Bild 1).

Ein memcopy mit 16 bytes wird auf viele TLPs verteilt (Siehe Bild 2).

>
> und um die benotige Byte zu wissen werden First DW Byte Enables und Last
> DW Byte Enables gebraucht also
>
> bei 32 bits Datentransfer :Last BE = 0x0 und First BE = 0xf(1111)
>
> bei 16 bits Datentransfer :Last BE = 0x0 und First BE = 0x3 (0011)
>
> bei 8 bits Datentransfer :Last BE = 0x0 und First BE = 0x1 (0001)

Das gilt nur wenn die Addresse auf PC Seite ein vielfaches von 4 ist.
Siehe die angehängten Beispiele

>
>
> Nun zu 8 bit Slave (OpenCan) an einen 32bit Master anschliesst (Mico32):
>
>  bei 8 bit Opencore UART (beinhaltet ein sel_i Signal )also wurde kein
> Problem fesgestellt.
>
>  aber mit 8 bit Opencore CAN(beinhaltet kein sel_i Signal ):lässt sich
> Read/Write Operationen mit Mico32 ausführen .
>
>   Dies Problem lässt sich mit ALTERA mit dem 8 Bit Befehl IOWR_8DIRECT
> lösen auch wenn NIOS 32 bit ist.

Das sieht aus wie ein Macro, das die passenden Addressumrechnungen 
macht.


>
>   Wie wird es nun ohne sel_i Signal von Opencore CAN gelöst oder gibt es
> eine Opencore CAN Variante mit sel_i Signale?

Mach dir eine. Ist ja schliesslich Opensource.

Beim Mico32 ist das Problem vermutlich einfach zu lösen indem du doe 
Registeroffsets mit 4 multiplizierst.

von Lattice User (Gast)


Angehängte Dateien:

Lesenswert?

Das 2. Bild nochmal mit Spaltenüberschriften.

von Keller T. (fabito)


Lesenswert?

Danke für Klarheit durch ein echtes Beispiel. ich werde davon lernen um 
weiter zu implementieren.
Das Buch PCIe Architechture habe ich aber
so dargestellt wie dieses Beipiel lernt man mehr auf einmal.

Danke nochmals

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Mit dem Offset *4 für Opencore CAN blokiert ab

OPENCORECAN_REGISTER(OPENCORECAN2_BASE_ADDRESS, CAN_ACCEPTANCE_MASK)= 
bMASK; Zeile.

Ursprungliche ALTERA Code sieh so aus:(Sieh Anhang für OWR_8DIRECT 
Beschreibung)
1
IOWR_8DIRECT(CAN_CONTROL_BASE, CAN_CONTROL_REG, 0x1F);
2
    IOWR_8DIRECT(CAN_CONTROL_BASE, CAN_ACCEPTANCE_CODE, bCODE);
3
    IOWR_8DIRECT(CAN_CONTROL_BASE, CAN_ACCEPTANCE_MASK, bMASK);
4
    IOWR_8DIRECT(CAN_CONTROL_BASE, CAN_BUSTIMING_0, bBTR0);
5
    IOWR_8DIRECT(CAN_CONTROL_BASE, CAN_BUSTIMING_1, bBTR1);
6
    IOWR_8DIRECT(CAN_CONTROL_BASE, CAN_CLK_DIVIDER, 0x05);
7
    // now switch to operating mode
8
    bTmp = IORD_8DIRECT(CAN_CONTROL_BASE, CAN_CONTROL_REG);
9
    bTmp = bTmp & 0xFE;
10
    IOWR_8DIRECT(CAN_CONTROL_BASE, CAN_CONTROL_REG, bTmp);

Habe ich Mal 4 pro Offset und Mico 32 blokiert ab 4 Zeile:
1
   
2
   // turn on reset mode
3
    OPENCORECAN_REGISTER(OPENCORECAN2_BASE_ADDRESS, CAN_CONTROL_REG)=0x1F;
4
    
5
    // set acceptance mask
6
    OPENCORECAN_REGISTER(OPENCORECAN2_BASE_ADDRESS, CAN_ACCEPTANCE_CODE)=bCODE;
7
8
    OPENCORECAN_REGISTER(OPENCORECAN2_BASE_ADDRESS, CAN_ACCEPTANCE_MASK)= bMASK;
9
10
   // set bus timing registers
11
    OPENCORECAN_REGISTER(OPENCORECAN2_BASE_ADDRESS, CAN_BUSTIMING_0)= bBTR0;
12
13
    OPENCORECAN_REGISTER(OPENCORECAN2_BASE_ADDRESS, CAN_BUSTIMING_1)= bBTR1;
14
15
    // set clock divider field 
16
    OPENCORECAN_REGISTER(OPENCORECAN2_BASE_ADDRESS, CAN_CLK_DIVIDER)=0x05; //0101
17
18
    // turn off reset mode : operating mode
19
    bTmp=OPENCORECAN_REGISTER(OPENCORECAN2_BASE_ADDRESS, CAN_CONTROL_REG);
20
    bTmp = bTmp & 0xFE;
21
    OPENCORECAN_REGISTER(OPENCORECAN2_BASE_ADDRESS, CAN_CONTROL_REG)=bTmp;

von Lattice User (Gast)


Lesenswert?

Schau dir das ganze mit Reveal an, sonst wird das nichts.

von Keller T. (fabito)


Lesenswert?

Hallo

Mit Reveal Analyser bin ich dabei die DatenZugriff (8/32 Bits) über 
Lattice Wishbone Interface (wb_tlc/wb_intf.v) zu analysieren:

Dafür habe ich 2 Slaves über PCIe gebunden(32 Bit und 8 Bit)

sind folgende Betrachtungen für die Analyse richtig ?

SLAVE 32 Bit wird folgende erwartet:
-------------------------------------
32 Bit Zugriff auf Slave = 2 Wishbone Cycles
  Cycle one = wb_sel_i[1:0]=11 also 16 Bit werden übertragen
  Cycle two =  wb_sel_i[1:0]=11 also 16 Bit werden Bit werden übertragen

16 Bit Zugriff auf Slave = 1 Wishbone Cycles
  Cycle one = wb_sel_i[1:0]=11 also 16 Bit
  Cycle two =  wb_sel_i[1:0]=00 kein Zugriff auf Slave da nur 16 Bit


8 Bit Zugriff auf Slave = 1 Wishbone Cycles
  Cycle one = wb_sel_i[1:0]=01 also 8 Bit
  Cycle two =  wb_sel_i[1:0]=00 kein Zugriff auf Slave da nur 8 Bits


BEI SLAVE 8 Bits wird folgende erwartet:
------------------------------------------
32 Bit Zugriff auf Slave = 4 Wishbone Cycles
  Cycle one = wb_sel_i[1:0]=01 also 8 Bit werden übertragen
  Cycle two =  wb_sel_i[1:0]=01 also 8 Bit werden Bit werden übertragen
  Cycle three = wb_sel_i[1:0]=01 also 8 Bit werden übertragen
  Cycle four =  wb_sel_i[1:0]=01 also 8 Bit werden Bit werden übertragen

16 Bit Zugriff auf Slave = 2 Wishbone Cycles
  Cycle one = wb_sel_i[1:0]=01 also 8 Bit werden übertragen
  Cycle two =  wb_sel_i[1:0]=01 also 8 Bit werden Bit werden übertragen


8 Bit Zugriff auf Slave = 1 Wishbone Cycles
  Cycle one = wb_sel_i[1:0]=01 also 8 Bit werden übertragen

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> sind folgende Betrachtungen für die Analyse richtig ?

Nein.
Du gehst immer noch davon auss, dass es bei WB einen Busbreitenkonverter 
gibt. Gibt es in dem Beispiel nicht, und hat sich vermutlich auch noch 
niemand die Mühe gemsaht einen zu schreiben.

Schau dir in Reveal einfach nur die WB Signale in deinem Toplevel an.

von Keller T. (fabito)


Lesenswert?

OK hast du Recht gibt es nicht in meinem Besipiel.(Versa)
Nur möchte ich einen Opencore UART 8 Bit Breite dazu binden und Zugriff 
ermöglichen.

Wenn man aus folgenden GPIO 32 Bit Zugriff Beispiel geht. Wie soll den 
Zugriff auf UART 8 Bit implementiert werden mit Bezug wb_intf.v Module?
(Ich habe einiges erfolglos probiert.)

So dass die 2 Wishbone Cycles Verhalten in UART Slave berücksichtigt 
wird.
1
      9'h004: begin
2
         if (rd) wb_dat_local <= scratch_pad[15:0];
3
         else if (wr) begin
4
            scratch_pad[15:8] <= wb_sel_i[0] ? wb_dat_i[15:8] : scratch_pad[15:8];
5
            scratch_pad[7:0]  <= wb_sel_i[1] ? wb_dat_i[7:0]  : scratch_pad[7:0];
6
         end
7
      end
8
      9'h006: begin
9
         if (rd) wb_dat_local <= scratch_pad[31:16];
10
         else if (wr) begin
11
            scratch_pad[31:24] <= wb_sel_i[0] ? wb_dat_i[15:8] : scratch_pad[31:24];
12
            scratch_pad[23:16] <= wb_sel_i[1] ? wb_dat_i[7:0]  : scratch_pad[23:16];
13
         end
14
      end

Der wb_tlc (PCIe -> Wishbone) Module übersetzt JEDEN PCIe Zugriff in
ZWEI Wishbone cycles, wobei die Adresse um 2 incrementiert wird. Dieses
Verhalten muss in deinem Slave berücksichtigt werden.

von Duke Scarring (Gast)


Lesenswert?

Ngii Rayan schrieb:
> Der wb_tlc (PCIe -> Wishbone) Module übersetzt JEDEN PCIe Zugriff in
> ZWEI Wishbone cycles, wobei die Adresse um 2 incrementiert wird. Dieses
> Verhalten muss in deinem Slave berücksichtigt werden.
Wie wäre es, wenn Du die überflüssigen Bits einfach ignorierst?
Das macht so ziemlich jeder Busteilnehmer, wenn die zu übertragende 
Bitbreite kleiner ist als die native Bitbreite des Bussystems.
Und es zwingt Dich auch niemand in Deinem IP-Core auf jede Adresse zu 
reagieren, oder?

Duke

von Keller T. (fabito)


Lesenswert?

Ouahh !

Ich bin mit dem Thema einen Schritt weiter. Ich habe ein GPIO Register 8 
Bit implementiert und konnte lesen/schreiben mit 8 Bit.

Nun werde ich einfach die gleiche Vorgehenweise für Opencore UART 8 Bits 
und damit sollte es gehen....

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Bei Interesse so sieht meine 8 Bit GPIO Module zur Kommunikation mit 
Lattice PCIe Wishbone Interface aus....

von Keller T. (fabito)


Lesenswert?

Hallo zusammen,

Wie kann ich ein Trigger mit Reveal Analyser einstellen so dass ich ab 
rx_st Signal 20 Samples clock nacher warte.
Amders formuliert das Ziel ist es ein gesamte Wishbone Zyklus anschauen 
zu können bis ack_o Signal von GPIO Slave auf 1 wird ?
Ich habe einiges erfolglos probiert....

von Lattice User (Gast)


Lesenswert?

Ist jetzt schon eine Weile her, dass ich mich damit beschäftigt habe. 
Momentan schaffe ich es, meine Bugs mit Simulation ond Nachdenken 
auszumerzen.

Du schreibts nicht, was genau du schon probiert hast.
Also erst mal ins blaue.

Du musst im Reavel Inserter erst mal Triggerunits anlegen, ist etwas 
komplex da man auch Sequenzen definieren kann. Im Analyzer kann man dann 
einzelne Triggerunits auswählen.

Am besten Screenshots(*) bei weiteren Fragen.

(*) Im PNG Format!, sonst gibtes Haue von allen möglichen Leuten denen 
langweilig ist.

von Keller T. (fabito)



Lesenswert?

Ich gebe dir voll Recht. Also beigefügt entsprechende Reveal 
Inserter/Analyser und Linux Befehle:

Schritt 1: Unter Linux habe ich Memory Write Paket gesendet mit folgende 
Befehle:

q,x - exit
(1)- r|w <addr> [data]: w 0004 FF                      // 0004 
isGPIO:LEDs
(2)- r|w <addr> [data]: w 0004 AA
(3)- r|w <addr> [data]: w 0004 CC

ERKLÄRUNG: Write an ADRESSE xxxx DATEN xx (hexadecimal)

Mein Trigger wird immer ausgelöst wenn es ein TLP (MWr)also start of 
paket =1

Waveform_Memory_Write_0xAA.PNG für (2)
Waveform_Memory_Write_0xCC.PNG für (3)

Nun meine Fragen:

Frage 1: Warum gpio/wb_adr_i also Endpoint nicht die Adresse 0x0004 
bekommt ?

Frage 2: Warum erhalt man immer die Daten an naschte Waveform (Beispiel: 
AA sieht man nur nach Linux Operation 3) FIFO oder?
Habe ich versucht über Reset leer zu machen um entprenche Daten für jede 
Operation zu empfangen aber nichts gebracht.

Frage 3: Wie is Reveal Inserter einzustellen um nnach dem gesendeten TLP 
Paket(MWr) die gesamte Wishbone Zyklus von gpio/wb_cyc_i bis 
gpio/wb_ack_o
anzuschauen?

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> Nun meine Fragen:
>
> Frage 1: Warum gpio/wb_adr_i also Endpoint nicht die Adresse 0x0004
> bekommt ?

Siehe PCI/PCIe Spec. Jedes Device bekommt vom BIOS mindestens eine 
Adresse zugewiesen.

>
> Frage 2: Warum erhalt man immer die Daten an naschte Waveform (Beispiel:
> AA sieht man nur nach Linux Operation 3) FIFO oder?
> Habe ich versucht über Reset leer zu machen um entprenche Daten für jede
> Operation zu empfangen aber nichts gebracht.

Du hast als MaxSequence 2 angegeben, beim Analyzer vielleicht 
eingestellt dass er 2 Triggerevents braucht?

>
> Frage 3: Wie is Reveal Inserter einzustellen um nnach dem gesendeten TLP
> Paket(MWr) die gesamte Wishbone Zyklus von gpio/wb_cyc_i bis
> gpio/wb_ack_o
> anzuschauen?

Grössere Buffertiefe, oder einfach mehr als nur 16 im Analyzer 
anschauen.
Buffertiefe 512 statt 256 geht ohne dass mehr EBRs gebraucht werden.
(Ob es reicht weiss ich nicht)

rx_st als einzige Triggerbedingung ist u.U. etwas knapp, bei einem Intel 
basierendem Motherboard kann es sein, dass du mit Vendorspecific 
Messages zugemüllt wirst.

Vielleicht besser auf wb_cyc triggern.

von Keller T. (fabito)


Lesenswert?

Hallo zusammen,

Es ist mir gelungen ein 8 Bit Module über Lattice Wishbone Interface 
wb_intf.v anzuschliessen mit Lesen/Schreiben Möglichkeit.

[vhdl]
module wbs_gpio(wb_clk_i, wb_rst_i,
          wb_dat_i, wb_adr_i, wb_cti_i, wb_cyc_i, wb_lock_i, wb_sel_i, 
wb_stb_i, wb_we_i,
          wb_dat_o, wb_ack_o, wb_err_o, wb_rty_o,
          switch_in, led_out
);

input         wb_clk_i;
input         wb_rst_i;

input  [7:0] wb_dat_i;
input  [8:0] wb_adr_i;
input  [2:0] wb_cti_i;
input         wb_cyc_i;
input         wb_lock_i;
input   [1:0] wb_sel_i;
input         wb_stb_i;
input         wb_we_i;
output [7:0] wb_dat_o;
output        wb_ack_o;
output        wb_err_o;
output        wb_rty_o;

input [7:0] switch_in;
output [13:0] led_out; //output [7:0] led_out;


//reg [31:0] scratch_pad;

reg [13:0] led_out;
reg [7:0] wb_dat_local;

//reg [15:0] temp_data;
reg wb_ack_o;

reg wr_delayed; //For VERSA



assign rd = ~wb_we_i && wb_cyc_i && wb_stb_i;
assign wr = wb_we_i && wb_cyc_i && wb_stb_i;

assign wr_use = (!wr_delayed) && wr; //for VERSA

// Need to pipeline the write side to allow the read side time to read 
data
always @(posedge wb_rst_i or posedge wb_clk_i)
begin
  if (wb_rst_i)
  begin
    //scratch_pad <= 32'd0;
    led_out <= 14'd0;
    wb_dat_local <= 32'd0;

    //temp_data <= 0;

    wr_delayed <= 0;//for VERSA
  end
  else
  begin
    wr_delayed<=wr;

  if (wb_cyc_i)
  begin

    case (wb_adr_i)

      9'h000: begin
         if (rd) wb_dat_local <= 8'h30;
      end
      9'h002: begin
         if (rd) wb_dat_local <= 8'h12;
      end

    9'h003: begin
       if (rd) wb_dat_local <= {led_out[13:8],2'b11};
       else if (wr) begin
        led_out[13:8] <= wb_sel_i[0] ? wb_dat_i[5:0] : led_out[13:8];
        //led_out[7:0]  <= wb_sel_i[1] ? wb_dat_i[7:0]  : led_out[7:0];
       end
    end

`ifdef VERSA

    9'h004: begin

     if (rd) wb_dat_local <= 
{led_out[5:4],led_out[3],led_out[3],led_out[2:1],led_out[0],led_out[0]};

    else if (wr_use) begin

          if (led_out[0]&led_out[3]) begin

      led_out[7:0] <= wb_sel_i[1] ? wb_dat_i[7:0] : led_out[7:0];
       end

    else if  (led_out[0]&(!led_out[3])) begin

             led_out[7:0] <= wb_sel_i[1] ? wb_dat_i[7:0] : led_out[7:0];
       end

    else if ((!led_out[0])&led_out[3]) begin
      led_out[7:0] <= wb_sel_i[1] ? wb_dat_i[7:0] : led_out[7:0];
      end

          else if ((!led_out[0])&(!led_out[3])) begin
         led_out[7:0] <= wb_sel_i[1] ? wb_dat_i[7:0] : led_out[7:0];
       end
         end
    end // case: 9'h004


`else


  9'h004: begin
         if (rd) wb_dat_local <= led_out;
         else if (wr) begin
            //led_out[15:8] <= wb_sel_i[0] ? wb_dat_i[15:8] : 
led_out[15:8];
            led_out[7:0]  <= wb_sel_i[1] ? wb_dat_i[7:0]  : 
led_out[7:0];
         end
     end

 `endif

  9'h006: begin
        if (rd) wb_dat_local <= {switch_in};


    end

    endcase

  end // cyc

  end //clk
end

assign wb_dat_o = wb_dat_local;

assign wb_err_o = 1'b0;
assign wb_rty_o = 1'b0;

always @(posedge wb_rst_i or posedge wb_clk_i)
   if (wb_rst_i) begin
      wb_ack_o   <= 0;
   end
   else begin
      wb_ack_o   <= wb_cyc_i & wb_stb_i & (~ wb_ack_o);
   end
endmodule
/vhdl]

Aus diese Vorgehenweeise möchte ich auch Opencore UART 8 Bit Zugriff 
über
Lattice Wishbone Interface wb_intf.v ermöglicen.

ABER diese hat nicht die gleiche Architekture um direkt Zugriff auf 
Register um mein Adressdekoder wie mit GPIO Module zu schreiben.

Hat vielleicht jemand eine Idee wie ich vorgehen sollte ?

von Keller T. (fabito)


Lesenswert?

Ich habe eine Idee!

ich glaube es wird über das Module uart_wb.v also uart interface.
Sobald ich damit fertig bin dann melde ich mich
Aber ich würde mich auf weitere Idee freuen.

von Keller T. (fabito)


Lesenswert?

Hallo Leute,

Kann man mir vielleicht erklären warum unter the Lattice Wishbone 
Interface Module wb_intf.v wird das Signal wb_sel_o immer wieder gleich 
Werte also auf 1 gesetzt.

Ich habe unterschedliche TLP Datenlänge probiert(length = 1 DW, 
2DW,3DW,4DW) und immer wieder gleich Werte also wb_sel_o <= 2'b11;

Gibt es Fälle wo first_be[3:0] andere Werte aufnehmen als 1111?

Ich würde mich auf Klarheit hier freuen...
1
     DAT: // start length counter
2
     begin      
3
       wb_cyc_o <= 1'b1;
4
       wb_stb_o <= 1'b1;              
5
       din_ren_inner <= 1'b0;
6
       if (wb_ack_i) begin
7
          wb_adr_o <= wb_adr_o + 2;
8
          wb_dat_o <= {din[7:0], din[15:8]};
9
          
10
          if (word_cnt == {length, 1'b0}) begin 
11
             sm <= CLEAR;
12
             wb_cyc_o <= 1'b0;
13
             wb_stb_o <= 1'b0;
14
          end
15
          else begin
16
             word_cnt <= word_cnt + 1;
17
          end
18
          
19
          if (word_cnt == 1) //second
20
             wb_sel_o <= {first_be[2], first_be[3]};//first_be[3:2];
21
          else if (word_cnt == {length_minus1, 1'b0})        //length_minus1 = length - 1 = 2 -1 = 1
22
             wb_sel_o <= {last_be[0], last_be[1]};//last_be[1:0];
23
          else if (word_cnt == {length_minus1, 1'b1})              
24
             wb_sel_o <= {last_be[2], last_be[3]};//last_be[3:2];
25
          else
26
             wb_sel_o <= 2'b11;

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> Gibt es Fälle wo first_be[3:0] andere Werte aufnehmen als 1111?

Ja natürlich,
Schau dir meine PCIe Traces von oben mal genau an.

Für die meisten hier wären deine Fragen leichter nachzuvollziehen, wenn 
du auch Screenshots von einer Simulation, bzw von Reveal anhängen 
würdest. So muss man immer erst den Quellcode studieren (obendrein 
Verilog, die überwiegende Mehrheit hier nutzt VHDL). Ausserdem aus einem 
einzelenen Schnipsel den gesamten Zusammenhang zu erkennen ist oft nicht 
möglich.

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

OK

Ich habe dein Beispiel nochmals angeschaut und die erste Zeile 
beinhaltet folgende:

Length =001 Last BE = 0 First BE = 8

Was dies Datenmäßig bedeutet ? also wieviel Datenmenge werden da 
übertragen ?
1 Byte oder ?

beigefügt meine PCIe Traces (gesendet habe ich nur 1 Byte = 0xFF)also 
sollte ich First BE = 1 oder ?  aber bekomme ich First BE=0xF

Mein Hauptziel ist erkennen zu können aus einem TLP Paket welche 
Datenmenge für Read/Write gebraucht wird (Endpoint)?

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> beigefügt meine PCIe Traces (gesendet habe ich nur 1 Byte = 0xFF)also
>
Nein, hast du nicht.
Deine Software/Treiber auf dem PC macht immer 32 bit Zugriffe. Wenn du 
Byte Zugriffe sehen möchtest muss man Treiber buw SW entsrechend 
abändern.

Versuch mal eine ungerade Addresse einzugeben, vielleicht lässt die 
SW/Treiber das ja zu.

von Lattice User (Gast)


Lesenswert?

ich habe nochmal nachgeschaut, bei der Windowsvesrion der Lattice SW 
schreibts du einzele Bytes mit
1
wb 0004 AA

Dürfte bei der Linuxversion das gleiche sein.

Aber eine Einschränkung: Ich verwende diese Software nicht, kann mich 
also irren.

Noch eine Ergänzung

Ngii Rayan schrieb:
> Length =001 Last BE = 0 First BE = 8
>
> Was dies Datenmäßig bedeutet ? also wieviel Datenmenge werden da
> übertragen ?
> 1 Byte oder ?

Übertragen werden 4 Bytes, sieht man auch im Trace, aber nur 1 Byte ist 
gültig.

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Hallo,

Nun habe ich herausgefunden warum ich immer wieder nicht die gesendete 
Daten bisher gesehen habe (oder First BE Signal nicht genau wie erwartet 
passt)

Schauen Sie einfach auf mein TRACE . Da ist festzustellen dass ich mit 
Vendorspecific  Messages zugemüllt werde. Mein TLP Paket kommt erst an 
der dritte Stelle.

gesendet wurde: 1 Byte 0xAA
Jetzt simmt es mit First BE = 1 überein.

Nun eine Frage : Wie kann ich Zugriff für ungerade Adresse steuern.
Mein erste Gedanken ist bei UART beispielsweise jede Adresse zu 
vershieben also Mal 2.

Aber unbenutzte Speichebereiche (bei UART 0 bis 6 Offset wird 0 bis 12)
Hinweis: Endpoint mit 8/16 Slaves Devices alle über Wb_intf.v Module.

Auf Hinweise würde ich mich freuen...

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> Schauen Sie einfach auf mein TRACE . Da ist festzustellen dass ich mit
> Vendorspecific  Messages zugemüllt werde. Mein TLP Paket kommt erst an
> der dritte Stelle.

Auf dieses Problem habe ich schon hier hingewiesen:

Beitrag "Re: Lattice Diamond: UART Receiver Siganl Wegoptimiert"

(Letzer Abschnitt)

Ngii Rayan schrieb:
> Nun eine Frage : Wie kann ich Zugriff für ungerade Adresse steuern.
> Mein erste Gedanken ist bei UART beispielsweise jede Adresse zu
> vershieben also Mal 2.

Das ist das einfachste.
Aber auf die Enable achten, bei deinem Slave kommen immer 2 Zugriffe an.
Der 2. mit wb_sel = 00!

(Wobei ich mal 4 nehmen würde)

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> Schauen Sie einfach auf mein TRACE . Da ist festzustellen dass ich mit
> Vendorspecific  Messages zugemüllt werde. Mein TLP Paket kommt erst an
> der dritte Stelle.

Habe es noch einmal angeschaut:

In dem Trace ist KEINE Vendorspecific  Message.
(Die würden mit 03xx oder 07xx anfangen)

1. TLP, Schreiben auf Addresse 8 und BE = 3,
2. TLP. Lesen von Addresse 4 und BE = 1
3. TLP, Schreiben auf Addresse 4 und BE = 1

Du hast ganz nebenbei auch noch ein Softwareproblem.

von Keller T. (fabito)


Lesenswert?

Mal 2 habe ich vor weil ein 8 Bit UART/CAN nur bitemäßig vom Host 
gelesen wird.

Bei wordweise dann hätte ich sofort an Mal 4 gedacht. Aber bitte dies 
nur Gedanken die geprüft werden sollte.Nicht als Contra (x4) ansehen 
sondern Überlegung.

Ich simuliere erstmals dann melde ich mich mit dem Ergebnis....

von Keller T. (fabito)


Lesenswert?

OK ich schaue mir noch meine Software !

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Zum Testzweck habe ich vor 1 Monat ein Paar Read/Write Befehle in meinem 
Treiber eingefügt.(und vergessen!)


Also jetzt endlich ein perfekter TLP Pakete:

Gesendet wurde: 0xAA an Adresse 0x0004

Aus folgende Zeile wurde die wishbone Adresse im Wishbone Interface 
Module berechnet.
1
       else begin //3DW header
2
          if (word_cnt == 4) begin
3
             wb_adr_o[31:16] <= {14'd0, din[1:0]};
4
             din_ren_inner <= write;
5
          end
6
             
7
          if (word_cnt == 5) begin
8
             wb_adr_o[15:0]  <= din;
9
             tran_addr <= din[6:2];


Also wb_adr_o = 0008

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> Also wb_adr_o = 0008

Der Wishbonecyclus ist im Trace nicht sichtbar, das was da auf wb_adr 
sichtbar ist stammt von einem vorherigen Zugriff, und hat mit deinem Mal 
2 nichts zu tun.

Du musst auf wb_cyc triggern, oder weit mehr Samples im Reveal anzeigen.

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

OK habe ich folgende gemacht

Damit ich TLP Pakete und Wishbone Cycle anschauen kann, habe ich 
folgende Trigger genutzt: rx_st oder ebr_cyc .

Dadurch lassen sich Abläufe von MWr TLP bis Wishbone Zyklus(ebr) 
darstellen.

Gesendet wurde: 0xEE an Adresse 0x2004

passt jetzt oder ?

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Hier mein TRACE für 8 Bit Slave Zugriff (hier : led_out[7:0])

Ich glaube es gut aussieht mit gpio/wb_sel_i= 0 beim zweiten Zugriff 
oder verpasse was da ?

Auf Anmerkungen würde ich mich freuen...

Gesendet wurde: 0xFF an Adresse 0x0000 (8 Bit led)

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> Ich glaube es gut aussieht mit gpio/wb_sel_i= 0 beim zweiten Zugriff
> oder verpasse was da ?

Genau darum geht es.
Damit kommen die typischen 8bit WB slaves nicht zurande.

von Keller T. (fabito)



Lesenswert?

Hallo zusammen


Nachdem ich erfolgsreich 8 Bit GPIO Slave Module implementiert habe,
habe ich das Ziel Opencore Uart 32 Bit hinten Lattice Wishbone interface 
anzuhängen (wb_intf.v)

Auf diesem Grund habe ich alle UART Adresse verschoben um 4 wie 
folgende:
1
//`define DATA_BUS_WIDTH_8
2
3
`ifdef DATA_BUS_WIDTH_8
4
 `define UART_ADDR_WIDTH 3
5
 `define UART_DATA_WIDTH 8
6
`else
7
 `define UART_ADDR_WIDTH 5
8
 `define UART_DATA_WIDTH 32
9
`endif
10
11
// Uncomment this if you want your UART to have
12
// 16xBaudrate output port.
13
// If defined, the enable signal will be used to drive baudrate_o signal
14
// It's frequency is 16xbaudrate
15
16
// `define UART_HAS_BAUDRATE_OUTPUT
17
18
// Register addresses
19
/*
20
`define UART_REG_RB  `UART_ADDR_WIDTH'd0  // receiver buffer
21
`define UART_REG_TR  `UART_ADDR_WIDTH'd0  // transmitter
22
`define UART_REG_IE  `UART_ADDR_WIDTH'd1  // Interrupt enable
23
`define UART_REG_II  `UART_ADDR_WIDTH'd2  // Interrupt identification
24
`define UART_REG_FC  `UART_ADDR_WIDTH'd2  // FIFO control
25
`define UART_REG_LC  `UART_ADDR_WIDTH'd3  // Line Control
26
`define UART_REG_MC  `UART_ADDR_WIDTH'd4  // Modem control
27
`define UART_REG_LS  `UART_ADDR_WIDTH'd5  // Line status
28
`define UART_REG_MS  `UART_ADDR_WIDTH'd6  // Modem status
29
`define UART_REG_SR  `UART_ADDR_WIDTH'd7  // Scratch register
30
`define UART_REG_DL1  `UART_ADDR_WIDTH'd0  // Divisor latch bytes (1-2)
31
`define UART_REG_DL2  `UART_ADDR_WIDTH'd1
32
33
*/
34
35
`define UART_REG_RB  `UART_ADDR_WIDTH'd0  // receiver buffer
36
`define UART_REG_TR  `UART_ADDR_WIDTH'd0  // transmitter
37
`define UART_REG_IE  `UART_ADDR_WIDTH'd4  // Interrupt enable
38
`define UART_REG_II  `UART_ADDR_WIDTH'd8  // Interrupt identification
39
`define UART_REG_FC  `UART_ADDR_WIDTH'd8  // FIFO control
40
`define UART_REG_LC  `UART_ADDR_WIDTH'd12  // Line Control
41
`define UART_REG_MC  `UART_ADDR_WIDTH'd16  // Modem control
42
`define UART_REG_LS  `UART_ADDR_WIDTH'd20  // Line status
43
`define UART_REG_MS  `UART_ADDR_WIDTH'd24  // Modem status
44
`define UART_REG_SR  `UART_ADDR_WIDTH'd28  // Scratch register
45
`define UART_REG_DL1  `UART_ADDR_WIDTH'd0  // Divisor latch bytes (1-2)
46
`define UART_REG_DL2  `UART_ADDR_WIDTH'd4

Aber Schauen Sie bitte mein Track ! Das Output entpricht nicht was 
erwartet wird.

Uart Base Adresse: 0x1000

vier Transaktionen habe ich gamacht:
1) Write Daten 0x03 Adresse: 0x1004 (MWr_32Bit_uart_0x03_0x1004.PNG)
2) Read Adresse: 0x1004 (MRd_32Bit_uart_0x1004.PNG )
3) Write Daten 0x83 Adresse: 0x100C(MWr_32Bit_uart_0x83_0x100C.PNG)
4) Read Adresse: 0x100C (MRd_32Bit_uart_0x100C.PNG )

beigefügt mein UART Interface (uart_wb.v)

Ich würde mich auf Hinweise freuen !

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> Aber Schauen Sie bitte mein Track ! Das Output entpricht nicht was
> erwartet wird.
>

Doch,
z.B. Addresse 0x1004  kommt als Addresse 0x0004 bei der UART an.

Aber:
1
//`define DATA_BUS_WIDTH_8

heisst die UART ist als 32 bit Slave konfiguriert. Und wenn ich richtig 
verstanden habe, enthählt sie einen Layer der dann 32bit Zugriffe nach
8 bit übersetzt. Und damit geht alles daneben!
So ein Layer ist keineswegs WB Standard, und schränkt IMO die 
Verwendbarkeit des Cores ein.

Im 8bit Mode wird aber wb_sel nicht ausgwertet, und das wiederum macht 
hier Probleme, da Zugriffe mit wb_sel = 0 erfolgen.

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Hast du völlig Recht !

genauso sieht folgende Trace im 8 Bit Mode aus (Sieh Anhang)
2 Transaktionen habe ich gamacht:

1) Write Daten 0x03 Adresse: 0x1004 (MWr_8Bit_uart_0x03_0x1004.PNG)
2) Read Adresse: 0x1004 (MRd_8Bit_uart_0x1004.PNG )

Dann würde ich gern das UART Interface Module(uart_wb.v sih voheriges 
Anhang) so ändern mit select Signal für 8 Bit Mode:

`ifdef DATA_BUS_WIDTH_8 // 8-bit data bus
always @(posedge clk or posedge wb_rst_i)
  if (wb_rst_i)
    wb_dat_o <= #1 0;
  else
    wb_dat_o <= #1 wb_dat8_o;

always @(wb_dat_is)
  //wb_dat8_i = wb_dat_is;

---- >        wb_dat8_i <= wb_sel_i[1] ? wb_dat_is : wb_dat8_i;    < ---

`else // 32-bit bus
// put output to the correct byte in 32 bits using select line


Und Mal schauen oder bringt diese allein NICHT!

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> Dann würde ich gern das UART Interface Module(uart_wb.v sih voheriges
> Anhang) so ändern mit select Signal für 8 Bit Mode:

Ja genau.
Ob die Änderungen ausreichen wird man sehen.

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Hier meine Simulation mit wb_sel_i für UART Slave Device.

Nur habe ich immer wb_dat8_i = xx

Hat jemand vielleicht eine Idee was mir noch fehlt ?
1
always @(wb_dat_is)
2
3
        //Hier meine Änderung
4
       //wb_dat8_i = wb_dat_is;
5
   wb_dat8_i = wb_sel_i[1] ? wb_dat_is : wb_dat8_i;

gesendet wurde: 0xDCBA an Adresse :0x0002

von Lattice User (Gast)


Lesenswert?

Der gezeigte Ausschnitt (Es ist ein kombinatorischer Prozess) hat gleich 
2 Probleme.

1. Die Sensitivitylist ist unvollständig.
2. Es ist ein Latch beschrieben, sollte man bei einem FPGA vermeiden.

Zu 1: In Verilog 2001 (default bei Lattice) kann man faul sein und 
einfach @(*) schreiben. (Nur für kombinatorische Prozesse)

Im Trace fehlt wb_dat_is.

Übrigens auch ein kleines Lob.
Du hast erkannt, dass man bei komplexen Designs auch Ausschnitte 
simulieren kann, im Gegensatz zu manchen mit angeblichen 10 Jahren 
Aerospace erfahrung, die meinen weil das Gesamtdesign zu komplex ist man 
auf die Simulation verzichten muss.

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Hallo,

Danke für das Lob! Durch die Simulation versteht man einfach besser was 
drin lauft! Also würde ich empfehlen...

jetzt sieht meine Simulation gut aus!

Gesendet wurde
0x08 an Adresse 0x04 (also ier = Interrupt Enable Register)
Sieh Simulation_MWr_0x08_IER.PNG

und

0x83 an Adresse 0x0C (also lcr = Line Control Register)
Sieh Simulation_MWr_0x83_LCR.PNG

Die Inhalte dieser Registern sind ganz unten zu sehen (Simulation)

Nochmals zur Errinerung wurde die Offset Register wegen Wishbone 
Interface Module um 4 verschoben.

Also ier = offset:1 nun 4
     lcr = offset:3 nun C

Auf Hinweise würde ich mich freuen ...

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Hier eine Verbesserung !

Bei
0x83 an Adresse 0x0C (also lcr = Line Control Register)

Stimmen die Adresse nicht anstatt 0x04 sollte man eher 0x0C

Nun korrigiert

Sieh Simulation_MWr_0x83_LCR.PNG

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Simulation verbessert mit first_be = 1 Byte (Signal hinzugefügt)

gesendet 1 Byte = 0x83 an Adresse 0x0C (also lcr = Line Control 
Register)

Sieh Simulation_MWr_0x83_LCR.PNG

von Keller T. (fabito)


Lesenswert?

Auf der vorherige Simulation wurde auch die sel Signals besser behandelt 
(0 sobald die Daten geschrieben wurden)

von Keller T. (fabito)



Lesenswert?

Hallo zusammen,

Ich habe erfolgreich mein OpencoreCAN Controller über Wishbone interface 
(wsb.v)simuliert.

Siehe Anhang...

alle Adresse wurden Mal 4 also :
     Control Register = 0x00
     Command Register = 0x04
     Status Register = 0x08
     Interrupt Register = 0x0C
     Acceptance Code Register = 0x10
     .....

Nur habe ich Probleme nach dem *.bit Download auf dem Board.
Nach dem Schreiben kann ich nicht das Gleiche Lesen...

Hat es vielleicht mit Timing zu tun da ich 125 MHz für wb_clk_i und 
clk_i benutzt habe? Siehe unten
1
 can_top   can ( 
2
    .wb_clk_i      (clk_125),
3
    .wb_rst_i        (~core_rst_n),
4
      .wb_adr_i      (can_adr_i),
5
      .wb_dat_i       (can_dat_i),
6
      //.wb_sel_i       (can_sel_i),   
7
      .wb_we_i        (can_we),
8
      .wb_stb_i       (can_stb),
9
      .wb_cyc_i       (can_cyc),
10
      .wb_ack_o       (can_ack),
11
      .wb_dat_o       (can_dat_o),   
12
    
13
    //CAN signals
14
    .tx_o(can_stx_o), 
15
      .rx_i(can_srx_i),  
16
    
17
      //ack clock
18
    .clk_i(clk_125),
19
20
      //interrupt
21
          .irq_on(),
22
      .clkout_o()
23
    
24
    );

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> Hat es vielleicht mit Timing zu tun da ich 125 MHz für wb_clk_i und
> clk_i benutzt habe? Siehe unten

Geht es denn in der Simulation?

Wenn die Constraints stimmen, und die Timinganalyse keine Fehler findet, 
sollte es von dieser Seite in Ordnung sein.

von Keller T. (fabito)


Lesenswert?

Hallo,

Es hat mit dem CAN Bus geklappt es war einen kleinen Fehler von mir. 
Also der Adresse Bus war in der Luft .

Mit 125 MHz für wishbone und CAN_clock hat problemlos funktioniert.
Also gleicher Takt für PCIe - CAN

Nun meine Frage:

PCI Express ist mit125 MHZ getaktet.
Welche Vorteil oder Risiken gibt es wenn ich Enpoint Devices mit andere 
Clock takte.
Beispiel
1)- 50 MHz On Board für Asynchrone SRAM zum Waitstate Generierung.
2)- 25 MHz PLL für CAN wishbone(wb_clk_i) + CAN Clock(clk_i).


Gibt es zpezielle Anforderungen für Transport von Daten zwischen 
unterschiedliche
Taktdomänen (125MHZ-PCIe und 50MHZ-CAN) oder (125MHZ-PCIe und 25 
MHZ-CAN)?

Was wäre die sichere Lösungsansatzt ?

von Lattice User (Gast)


Lesenswert?

Was spricht dagegen den CAN Controller mit 125 MHz zu betreiben?

Zu klären ist allerdings folgendes:
Die 125 MHz des PCI Express Designs leiten sich von der Rerefenzclock 
des PC's ab. Und diese ist mit SCC (Spread Spectrum Clocking) verseucht. 
Kann man bei manchen MBs abschalten. Ansonsten wie sind die 
Anforderungen von CAN an die Clockgenauigkeit und Stabilität?

Ngii Rayan schrieb:
> Gibt es zpezielle Anforderungen für Transport von Daten zwischen
> unterschiedliche
> Taktdomänen (125MHZ-PCIe und 50MHZ-CAN) oder (125MHZ-PCIe und 25
> MHZ-CAN)?

Ja, die gibt es. Lothar schreibt dass es nichts für den Anfänger ist, 
wenn man da etwas falsch macht gibt es sporadische scheinbar 
unerklärliche Fehler und in der Folge viele graue oder ausgerissene 
Haare.

von Keller T. (fabito)


Lesenswert?

Anforderungen von CAN:
Bis jetzt wurde 25MHz Ozillator für 12.5 MHz(CAN Controller) und 500 
kbps genutzt. Die Kompatibilität sollte gewährleistet werden .

Soll ich da Waitstates implementieren ?
Wenn Ja wie kann ich es am einfachstens mit Lattice implementieren?

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> Soll ich da Waitstates implementieren ?

Das reicht nicht.


Wishbone ist ein synchroner Bus, d.h. man muss alle Teilnehmer (Master 
und Slaves) mit der gleichen Clock versorgen.
Es ist sicher möglich eine WB -> WB Bridge zu implementieren um 
Clockdomaingrenzen zu überwinden, das ist aber nicht ganz trivial.

Übrigens hat das mit dem ursprünglichen Thema nichts mehr zu tun, es 
wäre vielleicht sinnvoll einen neuen Thread speziell zum Wishbone Thema 
aufzumachen, um wieder ein breiteres Publikum anzusprechen.

von Martin M. (capiman)


Lesenswert?

Wäre es möglich, einen Stand deiner Implementierung zu bekommen
(z.B. dein Beispiel mit einem UART würde schon reichen),
so dass man dies als Grundlage für eigene Versuche benutzen kann?
Oder sind deine Entwicklungen closed source
und damit leider nicht verfügbar?

von Keller T. (fabito)


Lesenswert?

Das wäre eine Lösung !
Von Lattice umsetzbar über IP Express Tool


FIFO_DC

A dual-clock FIFO using EBR (Embedded Block RAM). The FIFO_DC module 
provides a variety of FIFO memory organizations. This FIFO has two 
clocks. The generated netlist has gray counters to handle clock domain 
transfer. Ports, properties, and functionality are described in detail 
in the “See Also” section below.

Ich werde es umsetzen!

von Keller T. (fabito)


Lesenswert?

Hallo !

Es hat problemlos funktioniert.
Grund dafür ist : PCIe 125 MHz zur gleiche clock domäne mit mein 25 MHz 
PLL can_clk.
1
can_top   can ( 
2
    .wb_clk_i      (clk_125),
3
    .wb_rst_i        (~core_rst_n),
4
      .wb_adr_i      (can_adr),
5
      .wb_dat_i       (can_dat_i),
6
      //.wb_sel_i       (can_sel_i),   
7
      .wb_we_i        (can_we),
8
      .wb_stb_i       (can_stb),
9
      .wb_cyc_i       (can_cyc),
10
      .wb_ack_o       (can_ack),
11
      .wb_dat_o       (can_dat_o),   
12
    
13
    //CAN signals
14
    .tx_o(can_stx_o), 
15
      .rx_i(can_srx_i),  
16
    
17
      //ack clock
18
    .clk_i(can_clk), // .clk_i(clk_125),
19
20
      //interrupt
21
          .irq_on(),
22
      .clkout_o()
23
    
24
    );

von Keller T. (fabito)


Lesenswert?

Zur Martin Maurer (capiman) Nachfrage!

Ich kann leider nur wegen Datenschtutz
dir nur Hinweise über deine Probleme geben.
Mehr darf ich leider nicht.
Überdies lernst du auch viel by learning by doing.

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> Es hat problemlos funktioniert.
> Grund dafür ist : PCIe 125 MHz zur gleiche clock domäne mit mein 25 MHz
> PLL can_clk.

Nein, das ist nicht der Grund.

Der Grund ist, dass die Entwickler des Opencore CANs es vorgesehen haben 
(aber nirgends dokumentiert, daher taugt der Core nicht wirklich für 
Anfänger).

Hier ein kleiner Auszug (für den Rückweg):
1
  always @ (posedge wb_clk_i)
2
  begin
3
    cs_ack1 <=#Tp cs_sync3;
4
    cs_ack2 <=#Tp cs_ack1;
5
    cs_ack3 <=#Tp cs_ack2;
6
  end
7
 
8
  // Generating acknowledge signal
9
  always @ (posedge wb_clk_i)
10
  begin
11
    wb_ack_o <=#Tp (cs_ack2 & (~cs_ack3));
12
  end

Da ist noch viel mehr.
Wenn du verstanden hast um was es hier geht wirst du sehen dass es auch 
mit einer asynchronen CAN Clock gehen sollte.

von Keller T. (fabito)


Lesenswert?

Danke für den Hinweis!

Ich komme wieder zu dir nachdem ich es analysiert und verstanden habe.

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> Zur Martin Maurer (capiman) Nachfrage!
>
> Ich kann leider nur wegen Datenschtutz
> dir nur Hinweise über deine Probleme geben.
> Mehr darf ich leider nicht.
> Überdies lernst du auch viel by learning by doing.

Dir ist klar dass sowohl der CAN Core, als auch der UART Core von 
Opencores unter der LGPL Lizenz stehen?
Spätesten deinen eigenen Kunden wirst du alle deinen Modifikationen 
offenlegen müssen. Obendrein musst du ihnen die Möglichkeit geben selbst 
Änderungen an den LPGL Cores zu machen, was im Prinzip darauf 
hinausläuft, dass du deinen gesamten Source überreichen musst.

Also was soll die Geheimniskrämerei.

von Keller T. (fabito)


Lesenswert?

Bin ich einverstanden!

Nur darf ich nicht das gesamte Design senden.(Vielleicht am Ende )
Hinweis was zur Opencore geändert werden soll ok!

Ich möchte auch dass er viel verstehe. Von dir habe ich Hinweis immer 
bekommen dann habe ich versuche by doing herauszufinden.

Wenn du alles zu mir gesendet hättest. Glaub mir hätte ich keine 
Simulation gemacht was meinn Vertandnis verstärkt hat.

Also ich bin bereit zu helfen. Ich schreibe eine Private Mail zu ihm so 
können wir Kontakt halten.

Übrigens in welchem Opencore Can Controller Module ist dein kleiner 
Auszug (für den Rückweg):
1
  always @ (posedge wb_clk_i)
2
  begin
3
    cs_ack1 <=#Tp cs_sync3;
4
    cs_ack2 <=#Tp cs_ack1;
5
    cs_ack3 <=#Tp cs_ack2;
6
  end
7
 
8
  // Generating acknowledge signal
9
  always @ (posedge wb_clk_i)
10
  begin
11
    wb_ack_o <=#Tp (cs_ack2 & (~cs_ack3));
12
  end

Das finde ich nicht hast du vielleicht ein anderer Opencore ?

von Keller T. (fabito)


Lesenswert?

Zum Thema Clock Domain Crossing und Lösungsansätze

würde ich folgende Link empfehlen.

http://filebox.ece.vt.edu/~athanas/4514/ledadoc/html/pol_cdc.html

von Keller T. (fabito)


Lesenswert?

Ich habe der kleiner Auszug (für den Rückweg gesehen

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> Das finde ich nicht hast du vielleicht ein anderer Opencore ?

Ich habe keinen, nur online geschaut. (http://opencores.org/project,can)
Da ich auf Opencores nur einen CAN Controller für WB in Verilog gefunden 
habe, nahm ich an, dass es der ist den du auch benutzt. Ausserdem gibt 
es dort die 2 getrennten Clocks wb_clk_i und clk_i, wie in deinen 
Auszügen.

Die Stelle ist im module can_top, ziemlich weit unten.

von Keller T. (fabito)


Lesenswert?

OK

Das habe ich gesehen. Ich mache nicht weiter ohne es verstanden zu 
haben!

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Zu Synchronistaion Wishbone_Clk und Can Clock !

Zum besseren Verstandnis

von Lattice User (Gast)


Lesenswert?

Kleiner Hinweis:

Das #Tp im Opencan Core ist überflüssig und wirkt nur auf die 
Simulation, manche brauchen es halt um sich Sand in die Augen zu 
streuen.
Damit hat der kleine Versatz zwischen der roten Linie und den Clocks 
nichts zu sagen. (Wie gesagt nur Sand im Auge des Betrachters)

(An die VHDLer, das ist das Gleiche wie ein after in VHDL)

Um zu sehen was da wirklich passiert, solltes du die Simulation mal mit 
einer asynchronen Clock machen, mit einer möglichst krummen bezogen auf 
die 125 MHz.

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

OK!

so sieht es aus: sieh Anhang: besser habe ich verstanden und bin 
gespannt was mit dem UART für 25 MHz passieren wird ?

Nun eine Frage:

Aus meinem bisherigen Verstandnis dachte ich dass, Prefetchable Memory 
BAR immer 64 Bit sein sollte.Kann man auch mit 32 Bit oder ?

Mein Ziel ist Asynchrone SRAM 1 MB als Endpoint Device was Prefetchable 
bedeutet.
Nun darf man 32 Bit (1 BAR) oder muss man 64 Bits(also 2 BARs) ?

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Tut mir Leid Hier die Simulation !


Nun eine Frage:

Aus meinem bisherigen Verstandnis dachte ich dass, Prefetchable Memory
BAR immer 64 Bit sein sollte.Kann man auch mit 32 Bit oder ?

Mein Ziel ist Asynchrone SRAM 1 MB als Endpoint Device was Prefetchable
bedeutet.
Nun darf man 32 Bit (1 BAR) oder muss man 64 Bits(also 2 BARs) ?

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Hat als auch mit dem UART Opencore (25 MHz) zumindest mit der Simulation 
geklappt.

Wishbone Inerface= 125 MHz
UART = 25 MHz

Auch wenn Ack Signal 4 Mal gesendet wird
nur der erster berücksichtigt ist (we_0=1 sonst we_0=0)

von Lattice User (Gast)


Lesenswert?

Ngii Rayan schrieb:
> Aus meinem bisherigen Verstandnis dachte ich dass, Prefetchable Memory
> BAR immer 64 Bit sein sollte.Kann man auch mit 32 Bit oder ?
>

Ja sollte gehen.

Bei PCI Express ist das übrigens egal, du kannst sowohl 32 als 64 Bit 
BARS beliebig kennzeichnen.

Die Unterscheidung stammt aus der PCI Bridge Spezification und hat damit 
zu tun dass es beim PCI Protokol keine Burstlänge gibt, sondern der 
Burst beendet ist wenn die CPU keine Lust mehr hat. Damit es schnell 
geht muss eine PCI Bridge also auf der Deviceseite vorrauslesen 
(prefetch) und zuvielgelesene Daten wegschmeissen.

Damit die PCI Bridge unterscheiden kann ob prefetch erlaubt its, hat sie 
zwei Addressfenster, je eines für nonprefetch und prefetch. Das für 
nonprefetch kann nur 32bit Addressen umsetzen.

Eine PCIe Bridge hat wegen der Rückwärtskompatibiltät auch diese 2 
Fenster, braucht aber die Zugriffe nicht unterschiedlich behandeln da 
das PCIe Protokoll eine Längenangabe enthält.

Allerdings dürften die meisten BIOSe und Betriebsysteme immer noch so 
tun als ob es wichtig wäre.
Wenn das BIOS/OS auf eine 64bit Bar ohne prefetch stösst, wird halt 
immer noch eine 32bit Addresse zugewiesen und verschwendet wertvollen 
Addressraum im < 4GByte Bereich. Übrigens für jedes Device gleich 1 
MByte, egal wie klein deine BARs sind.


> Mein Ziel ist Asynchrone SRAM 1 MB als Endpoint Device was Prefetchable
> bedeutet.
> Nun darf man 32 Bit (1 BAR) oder muss man 64 Bits(also 2 BARs) ?

Die ist klar was Prefetchable auch cachable aus der Sicht der CPU 
bedeutet und du extra Aufwand im Treiber hast?

Ngii Rayan schrieb:
> Hat als auch mit dem UART Opencore (25 MHz) zumindest mit der Simulation
> geklappt.
>
> Wishbone Inerface= 125 MHz
> UART = 25 MHz
>

Wofür wird die UART Clock verwendet? Nur für den Baudrategenerator, oder 
auch für den Registerzugriff?
Wenn ersteres, hat das Uartmodule intern korrekte Clockdomaincrossings?

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

eine Woche lang war ich krank !

Erstens vien Dank für die 32/64 Bit BARs Erklärung. Ich werde weiterhin 
mit 64 Bits für SRAM machen.

Nun zu deiner Fragen:

1) Wofür wird die UART Clock verwendet? Nur für den Baudrategenerator, 
oder auch für den Registerzugriff?
2) Wenn ersteres, hat das Uartmodule intern korrekte 
Clockdomaincrossings?

Antworte: auch für den Registerzugriff

Nach dem Test funktioniert es aber ich werde den Test mehrmal 
durchführen um eine Sicherheit zu haben.

Nun meine Fragen:

Es is nirgendwo geschrieben ob Opencore CAN/UART Interrupt Hight oder 
Low aktive sind.

Aber wenn man der Blockdiagram anschaut(Sieh Anhang),
scheint UART16550 aktive High aktive und CAN aktive Low zu sein. Ist es 
So oder bin ich falsch?
Ich benutze MSI (rising Edge Interrupt). Nur wollte ich mir klar machen 
welche Typ von Interrupts von Slave Device generiert werden.

von Keller T. (fabito)


Angehängte Dateien:

Lesenswert?

Hallo alle Lattice user,

Hier ein Beispiel zur Lattice Wishbone Interface <-->8Bit UART Slave 
Kommunikation als Basis für einen Einstieg.
Bei Fragen stehe ich gern zur Verfügung.

von Raya N. (rayan)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich arbeite auch mit Lattice IP Core und habe Problem mit der 
Adressierung:

Ursprunglich wird der Zugrrif auf Devices wie folgende:
1
wb_arb #(.c_DATA_WIDTH(16),
2
         .S0_BASE     (32'h0000),
3
         .S1_BASE     (32'h4000),
4
         .S2_BASE     (32'h1000),
5
         .S3_BASE     (32'h5000)
6
) wb_arb (
7
    .clk(clk_125),
8
    .rstn(core_rst_n),
9
  
10
    // PCIe Master 
11
    .m0_dat_i(pcie_dat_o), 
12
    .m0_dat_o(pcie_dat_i), 
13
    .m0_adr_i(pcie_adr),
14
    .m0_sel_i(pcie_sel), 
15
    .m0_we_i(pcie_we), 
16
    .m0_cyc_i(pcie_cyc),
17
    .m0_cti_i(pcie_cti),
18
    .m0_stb_i(pcie_stb), 
19
    .m0_ack_o(pcie_ack), 
20
    .m0_err_o(), 
21
    .m0_rty_o(), 
22
    
23
    // DMA Master
24
    .m1_dat_i(16'd0), 
25
    .m1_dat_o(), 
26
    .m1_adr_i(32'd0),
27
    .m1_sel_i(2'd0), 
28
    .m1_we_i( 1'b0), 
29
    .m1_cyc_i(1'b0),
30
    .m1_cti_i(3'd0),
31
    .m1_stb_i(1'b0), 
32
    .m1_ack_o(), 
33
    .m1_err_o(), 
34
    .m1_rty_o(),         
35
36
    // GPIO 32-bit
37
    .s0_dat_i(gpio_dat_o), 
38
    .s0_dat_o(gpio_dat_i), 
39
    .s0_adr_o(gpio_adr), 
40
    .s0_sel_o(gpio_sel), 
41
    .s0_we_o (gpio_we), 
42
    .s0_cyc_o(gpio_cyc),
43
    .s0_cti_o (gpio_cti),
44
    .s0_stb_o(gpio_stb), 
45
    .s0_ack_i(gpio_ack), 
46
    .s0_err_i(gpio_err),
47
    .s0_rty_i(gpio_rty), 
48
    
49
    // DMA Slave
50
    .s1_dat_i(16'd0), 
51
    .s1_dat_o(), 
52
    .s1_adr_o(), 
53
    .s1_sel_o(), 
54
    .s1_we_o (), 
55
    .s1_cyc_o(),
56
    .s1_cti_o(),
57
    .s1_stb_o(), 
58
    .s1_ack_i(1'b0), 
59
    .s1_rty_i(1'b0),
60
    .s1_err_i(1'b0),
61
    
62
    // EBR
63
    .s2_dat_i(ebr_dat_o), 
64
    .s2_dat_o(ebr_dat_i), 
65
    .s2_adr_o(ebr_adr), 
66
    .s2_sel_o(ebr_sel), 
67
    .s2_we_o (ebr_we), 
68
    .s2_cyc_o(ebr_cyc),
69
    .s2_cti_o(ebr_cti),
70
    .s2_stb_o(ebr_stb), 
71
    .s2_ack_i(ebr_ack), 
72
    .s2_err_i(ebr_err),
73
    .s2_rty_i(ebr_rty),
74
    
75
    // Not used
76
    .s3_dat_i(16'd0), 
77
    .s3_dat_o(), 
78
    .s3_adr_o(), 
79
    .s3_sel_o(), 
80
    .s3_we_o (), 
81
    .s3_cyc_o(),
82
    .s3_cti_o(),
83
    .s3_stb_o(), 
84
    .s3_ack_i(1'b0),
85
    .s3_rty_i(1'b0), 
86
    .s3_err_i(1'b0)
87
);

Nur möchte ich eher sowas:

wb_arb #(.c_DATA_WIDTH(16),
         .S0_BASE     (32'h4000),
         .S1_BASE     (32'h4008),
         .S2_BASE     (32'h4010),
         .S3_BASE     (32'h4018)
) wb_arb (

erlauben dann habe der Wishbone Arbiter so angepasst:
1
always @(posedge clk or negedge rstn)
2
begin
3
  if (~rstn)
4
  begin
5
    s0_sel <= 1'b0;
6
    s1_sel <= 1'b0;
7
    s2_sel <= 1'b0;
8
    s3_sel <= 1'b0;
9
  s4_sel <= 1'b0;
10
  s5_sel <= 1'b0;
11
  s6_sel <= 1'b0;
12
  s7_sel <= 1'b0;
13
  s8_sel <= 1'b0;
14
  s9_sel <= 1'b0;
15
  end
16
  else
17
  begin
18
    s0_sel <= ~rr[0] ? (m0_adr_i[15:0] >= S0_BASE[15:0]) : 1'b0; // M0 (PCIe) only talks to S0 and S1
19
    s1_sel <= ~rr[0] ? (m0_adr_i[15:0] >= S1_BASE[15:0]) : 1'b0;
20
    s2_sel <= (m_adr[15:0] >= S2_BASE[15:0]);
21
    s3_sel <= (m_adr[15:0] >= S3_BASE[15:0]); 
22
  s4_sel <= (m_adr[15:0] >= S4_BASE[15:0]); 
23
  s5_sel <= (m_adr[15:0] >= S5_BASE[15:0]); 
24
  s6_sel <= (m_adr[15:0] >= S6_BASE[15:0]); 
25
  s7_sel <= (m_adr[15:0] >= S7_BASE[15:0]); 
26
  s8_sel <= (m_adr[15:0] >= S8_BASE[15:0]);
27
  s9_sel <= (m_adr[15:0] >= S9_BASE[15:0]);  
28
  end
29
end

Leider kann ich damit nur Devices 4000 und 4010 zugreifen aber nicht
4008 und 4018


Bitte was soll ich noch da machen um mein Ziel zu erreichen ?

Beigefügt ist der Arbiter zu finden..

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.