OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [src_processor/] [mor1kx-5.0/] [rtl/] [verilog/] [mor1kx_pcu.v] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 alirezamon
/* ****************************************************************************
2
  This Source Code Form is subject to the terms of the
3
  Open Hardware Description License, v. 1.0. If a copy
4
  of the OHDL was not distributed with this file, You
5
  can obtain one at http://juliusbaxter.net/ohdl/ohdl.txt
6
 
7
  Description: mor1kx Perfomance Counters Unit
8
 
9
  Copyright (C) 2016 Authors
10
 
11
  Author(s): Alexey Baturo <baturo.alexey@gmail.com>
12
 
13
***************************************************************************** */
14
 
15
`include "mor1kx-defines.v"
16
 
17
module mor1kx_pcu
18
  #(
19
    parameter OPTION_PERFCOUNTERS_NUM = 7
20
  )
21
  (
22
   input clk,
23
   input rst,
24
 
25
   // SPR Bus interface
26
   input         spr_access_i,
27
   input         spr_we_i,
28
   input         spr_re_i,
29
   input [15:0]  spr_addr_i,
30
   input [31:0]  spr_dat_i,
31
   output        spr_bus_ack,
32
   output [31:0] spr_dat_o,
33
 
34
   // Current cpu mode: user/supervisor
35
   input         spr_sys_mode_i,
36
   // Events that can occur
37
   input         pcu_event_load_i,            // track load insn
38
   input         pcu_event_store_i,           // track store insn
39
   input         pcu_event_ifetch_i,          // track insn fetch
40
   input         pcu_event_dcache_miss_i,     // track data cache miss
41
   input         pcu_event_icache_miss_i,     // track insn cache miss
42
   input         pcu_event_ifetch_stall_i,    // track SOME stall
43
   input         pcu_event_lsu_stall_i,       // track LSU stall
44
   input         pcu_event_brn_stall_i,       // track brn miss
45
   input         pcu_event_dtlb_miss_i,       // track data tlb miss
46
   input         pcu_event_itlb_miss_i,       // track insn tlb miss
47
   input         pcu_event_datadep_stall_i    // track SOME stall
48
   );
49
 
50
   // Registers
51
   reg [31:0]    pcu_pccr[0:OPTION_PERFCOUNTERS_NUM];
52
   reg [31:0]    pcu_pcmr[0:OPTION_PERFCOUNTERS_NUM];
53
 
54
   wire pcu_pccr_access;
55
   wire pcu_pcmr_access;
56
 
57
   // check if we access pcu
58
   // TODO: generate this signals according to present units
59
   assign pcu_pccr_access =
60
     spr_access_i &
61
     ((`SPR_OFFSET(spr_addr_i) == `SPR_OFFSET(`OR1K_SPR_PCCR0_ADDR)) |
62
      (`SPR_OFFSET(spr_addr_i) == `SPR_OFFSET(`OR1K_SPR_PCCR1_ADDR)) |
63
      (`SPR_OFFSET(spr_addr_i) == `SPR_OFFSET(`OR1K_SPR_PCCR2_ADDR)) |
64
      (`SPR_OFFSET(spr_addr_i) == `SPR_OFFSET(`OR1K_SPR_PCCR3_ADDR)) |
65
      (`SPR_OFFSET(spr_addr_i) == `SPR_OFFSET(`OR1K_SPR_PCCR4_ADDR)) |
66
      (`SPR_OFFSET(spr_addr_i) == `SPR_OFFSET(`OR1K_SPR_PCCR5_ADDR)) |
67
      (`SPR_OFFSET(spr_addr_i) == `SPR_OFFSET(`OR1K_SPR_PCCR6_ADDR)) |
68
      (`SPR_OFFSET(spr_addr_i) == `SPR_OFFSET(`OR1K_SPR_PCCR7_ADDR)));
69
 
70
   assign pcu_pcmr_access =
71
     spr_access_i &
72
     ((`SPR_OFFSET(spr_addr_i) == `SPR_OFFSET(`OR1K_SPR_PCMR0_ADDR)) |
73
      (`SPR_OFFSET(spr_addr_i) == `SPR_OFFSET(`OR1K_SPR_PCMR1_ADDR)) |
74
      (`SPR_OFFSET(spr_addr_i) == `SPR_OFFSET(`OR1K_SPR_PCMR2_ADDR)) |
75
      (`SPR_OFFSET(spr_addr_i) == `SPR_OFFSET(`OR1K_SPR_PCMR3_ADDR)) |
76
      (`SPR_OFFSET(spr_addr_i) == `SPR_OFFSET(`OR1K_SPR_PCMR4_ADDR)) |
77
      (`SPR_OFFSET(spr_addr_i) == `SPR_OFFSET(`OR1K_SPR_PCMR5_ADDR)) |
78
      (`SPR_OFFSET(spr_addr_i) == `SPR_OFFSET(`OR1K_SPR_PCMR6_ADDR)) |
79
      (`SPR_OFFSET(spr_addr_i) == `SPR_OFFSET(`OR1K_SPR_PCMR7_ADDR)));
80
 
81
   // put data on data bus
82
   assign spr_bus_ack = spr_access_i;
83
   assign spr_dat_o   = (spr_access_i & pcu_pccr_access & spr_re_i) ? pcu_pccr[spr_addr_i[2:0]] :
84
                        (spr_access_i & pcu_pcmr_access & spr_re_i & spr_sys_mode_i) ? pcu_pcmr[spr_addr_i[2:0]] :
85
                        0;
86
   genvar pcu_num;
87
   generate
88
      for(pcu_num = 0; pcu_num < OPTION_PERFCOUNTERS_NUM + 1; pcu_num = pcu_num + 1) begin: pcu_generate
89
         wire [`OR1K_PCMR_DDS:`OR1K_PCMR_LA] pcu_events_active;
90
         wire [`OR1K_PCMR_DDS:`OR1K_PCMR_LA] pcu_events_hit;
91
 
92
         assign pcu_events_active =
93
            (pcu_event_load_i << `OR1K_PCMR_LA) |
94
            (pcu_event_store_i << `OR1K_PCMR_SA) |
95
            (pcu_event_ifetch_i << `OR1K_PCMR_IF) |
96
            (pcu_event_dcache_miss_i << `OR1K_PCMR_DCM) |
97
            (pcu_event_icache_miss_i << `OR1K_PCMR_ICM) |
98
            (pcu_event_ifetch_stall_i << `OR1K_PCMR_IFS) |
99
            (pcu_event_lsu_stall_i << `OR1K_PCMR_LSUS) |
100
            (pcu_event_brn_stall_i << `OR1K_PCMR_BS) |
101
            (pcu_event_dtlb_miss_i << `OR1K_PCMR_DTLBM) |
102
            (pcu_event_itlb_miss_i << `OR1K_PCMR_ITLBM) |
103
            (pcu_event_datadep_stall_i << `OR1K_PCMR_DDS);
104
 
105
         assign pcu_events_hit =
106
            pcu_events_active & pcu_pcmr[pcu_num];
107
 
108
         always @(posedge clk `OR_ASYNC_RST) begin
109
            if (rst) begin
110
               pcu_pccr[pcu_num] <= 32'd0;
111
               pcu_pcmr[pcu_num] <= 32'd0 | 1 << `OR1K_PCMR_CP;
112
            // we could write pcu registers only in system mode
113
            end else if (spr_we_i && spr_sys_mode_i) begin
114
               if (pcu_pccr_access & (spr_addr_i[2:0] == pcu_num))
115
                  pcu_pccr[pcu_num] <= spr_dat_i;
116
               // WPE are not implemented, hence we do not update WPE part
117
               if (pcu_pcmr_access && (spr_addr_i[2:0] == pcu_num)) begin
118
                  pcu_pcmr[pcu_num][`OR1K_PCMR_DDS:`OR1K_PCMR_CISM] <=
119
                     spr_dat_i[`OR1K_PCMR_DDS:`OR1K_PCMR_CISM];
120
               end
121
            end else if (((pcu_pcmr[pcu_num][`OR1K_PCMR_CISM] & spr_sys_mode_i) |
122
                       (pcu_pcmr[pcu_num][`OR1K_PCMR_CIUM] & ~spr_sys_mode_i))) begin
123
               pcu_pccr[pcu_num] <= pcu_pccr[pcu_num] +
124
                  pcu_events_hit[`OR1K_PCMR_LA] +
125
                  pcu_events_hit[`OR1K_PCMR_SA] +
126
                  pcu_events_hit[`OR1K_PCMR_IF] +
127
                  pcu_events_hit[`OR1K_PCMR_DCM] +
128
                  pcu_events_hit[`OR1K_PCMR_ICM] +
129
                  pcu_events_hit[`OR1K_PCMR_IFS] +
130
                  pcu_events_hit[`OR1K_PCMR_LSUS] +
131
                  pcu_events_hit[`OR1K_PCMR_BS] +
132
                  pcu_events_hit[`OR1K_PCMR_DTLBM] +
133
                  pcu_events_hit[`OR1K_PCMR_ITLBM] +
134
                  pcu_events_hit[`OR1K_PCMR_DDS];
135
            end
136
         end
137
      end
138
   endgenerate
139
 
140
endmodule // mor1kx_pcu

powered by: WebSVN 2.1.0

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