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

Subversion Repositories ssbcc

[/] [ssbcc/] [trunk/] [core/] [9x8/] [peripherals/] [monitor_stack.v] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sinclairrf
//
2
// monitor_stack peripheral
3
//
4
// Note: The validity of N and T are not monitored for invalid operations.  For
5
//       example, if N is not valid and a "swap" is performed, then the data
6
//       stack is no longer valid and an error is detected.  Thus, the validity
7
//       of N and T do not need to be monitored for "swap" operations. 
8
generate
9
reg s__PC_error = 1'b0;
10
localparam L__INSTRUCTION_MAX = @NINSTRUCTIONS@-1;
11
always @ (posedge i_clk)
12
  if (~&L__INSTRUCTION_MAX[0+:C_PC_WIDTH] && (s_PC > L__INSTRUCTION_MAX[0+:C_PC_WIDTH])) begin
13
    $display("%12d : PC passed instruction space in @CORENAME@", $time);
14
    s__PC_error <= 1'b1;
15
  end
16
//
17
reg s__N_valid;
18
reg s__R_valid;
19
reg s__T_valid;
20
reg s__data_stack_valid;
21
reg s__return_stack_valid;
22
//
23
initial s__T_valid = 1'b0;
24
always @ (posedge i_clk)
25
  if (i_rst)
26
    s__T_valid <= 1'b0;
27
  else case (s_bus_t)
28
    C_BUS_T_OPCODE:     s__T_valid <= 1'b1;
29
    C_BUS_T_N:          s__T_valid <= s__N_valid;
30
    C_BUS_T_PRE:        case (s_opcode[0+:2])
31
                          2'b00: s__T_valid <= s__T_valid;
32
                          2'b01: s__T_valid <= s__R_valid;
33
                          2'b10: s__T_valid <= s__N_valid;
34
                          default : s__T_valid <= s__T_valid;
35
                        endcase
36
    C_BUS_T_LOGIC:      case (s_opcode[2])
37
                          1'b0: s__T_valid <= s__T_valid;
38
                          1'b1: s__T_valid <= s__N_valid;
39
                          default : s__T_valid <= s__T_valid;
40
                        endcase
41
    default:            s__T_valid <= s__T_valid;
42
  endcase
43
//
44
initial s__N_valid = 1'b0;
45
always @ (posedge i_clk)
46
  if (i_rst)
47
    s__N_valid <= 1'b0;
48
  else case (s_bus_n)
49
    C_BUS_N_N:          s__N_valid <= s__N_valid;
50
    C_BUS_N_STACK:      s__N_valid <= s__data_stack_valid;
51
    C_BUS_N_T:          s__N_valid <= s__T_valid;
52
    C_BUS_N_MEM:        s__N_valid <= 1'b1;
53
    default:            s__N_valid <= s__N_valid;
54
  endcase
55
//
56
initial s__data_stack_valid = 1'b0;
57
always @ (posedge i_clk)
58
  if (i_rst)
59
    s__data_stack_valid <= 1'b0;
60
  else if (s_stack == C_STACK_INC)
61
    s__data_stack_valid <= s__N_valid;
62
  else if ((s_stack == C_STACK_DEC) && (s_Np_stack_ptr == {(C_DATA_PTR_WIDTH){1'b0}}))
63
    s__data_stack_valid <= 1'b0;
64
  else
65
    s__data_stack_valid <= s__data_stack_valid;
66
//
67
reg s__data_stack_error = 1'b0;
68
@OUTPORT_PURE_STROBE@
69
always @ (posedge i_clk)
70
  if (!s__data_stack_error) begin
71
    if ((s_stack == C_STACK_DEC) && !s__T_valid) begin
72
      $display("%12d : Data stack underflow in @CORENAME@", $time);
73
      s__data_stack_error <= 1'b1;
74
    end
75
    if ((s_stack == C_STACK_INC) && (s_Np_stack_ptr == {(C_DATA_PTR_WIDTH){1'b1}}) && s__data_stack_valid) begin
76
      $display("%12d : Data stack overflow in @CORENAME@", $time);
77
      s__data_stack_error <= 1'b1;
78
    end
79
    if (s__N_valid && !s__T_valid) begin
80
      $display("%12d : Data stack validity inversion in @CORENAME@", $time);
81
      s__data_stack_error <= 1'b1;
82
    end
83
    if (!s__T_valid && (s_Np_stack_ptr != { {(C_DATA_PTR_WIDTH-2){1'b1}}, 2'b01 })) begin
84
      $display("%12d : Malformed top-of-data-stack validity in @CORENAME@", $time);
85
      s__data_stack_error <= 1'b1;
86
    end
87
    if (!s__N_valid && (s_Np_stack_ptr[2+:C_DATA_PTR_WIDTH-2] != {(C_DATA_PTR_WIDTH-2){1'b1}})) begin
88
      $display("%12d : Malformed next-to-top-of-data-stack validity in @CORENAME@", $time);
89
      s__data_stack_error <= 1'b1;
90
    end
91
    case (s_bus_t)
92
      C_BUS_T_MATH_ROTATE:
93
        if (!s__T_valid && (s_opcode[0+:3] != 3'h0)) begin
94
          $display("%12d : Illegal rotate on invalid top of data stack in @CORENAME@", $time);
95
          s__data_stack_error <= 1'b1;
96
        end
97
      C_BUS_T_ADDER:
98
        if ((s_opcode[3+:4] == 4'b0011) && (!s__N_valid || !s__T_valid)) begin
99
          $display("%12d : Invalid addition in @CORENAME@", $time);
100
          s__data_stack_error <= 1'b1;
101
        end else if (!s__T_valid) begin
102
          $display("%12d : Invalid increment or decrement in @CORENAME@", $time);
103
          s__data_stack_error <= 1'b1;
104
        end
105
      C_BUS_T_COMPARE:
106
        if (!s__T_valid) begin
107
          $display("%12d : Comparison on invalid top of data stack in @CORENAME@", $time);
108
          s__data_stack_error <= 1'b1;
109
        end
110
      C_BUS_T_INPORT:
111
        if (!s__T_valid) begin
112
          $display("%12d : Inport using invalid top of data stack for address in @CORENAME@", $time);
113
          s__data_stack_error <= 1'b1;
114
        end
115
      C_BUS_T_LOGIC:
116
        case (s_opcode[0+:3])
117
          3'b000, 3'b001, 3'b010:
118
            if (!s__N_valid || !s__T_valid) begin
119
              $display("%12d : Illegal logical operation in @CORENAME@", $time);
120
              s__data_stack_error <= 1'b1;
121
            end
122
          3'b011:
123
            if (!s__N_valid || !s__T_valid) begin
124
              $display("%12d : Illegal nip in @CORENAME@", $time);
125
              s__data_stack_error <= 1'b1;
126
            end
127
          3'b100, 3'b101, 3'b110, 3'b111:
128
            ;
129
          default:
130
            ;
131
        endcase
132
      C_BUS_T_MEM:
133
        if (!s__T_valid) begin
134
          $display("%12d : Fetch using invalid top-of-data-stack in @CORENAME@", $time);
135
          s__data_stack_error <= 1'b1;
136
        end
137
      default:
138
        ;
139
    endcase
140
    if ((s_opcode == 9'b00_0111_000) && !s__T_valid) begin
141
      $display("%12d : Outport with invalid top-of-data-stack in @CORENAME@", $time);
142
      s__data_stack_error <= 1'b1;
143
    end
144
    if ((s_opcode == 9'b00_0111_000) && !s__N_valid && !s__outport_pure_strobe) begin
145
      $display("%12d : Outport with invalid next-to-top-of-data-stack in @CORENAME@", $time);
146
      s__data_stack_error <= 1'b1;
147
    end
148
  end
149
//
150
initial s__R_valid = 1'b0;
151
always @ (posedge i_clk)
152
  if (i_rst)
153
    s__R_valid <= 1'b0;
154
  else if (s_return == C_RETURN_INC)
155
    s__R_valid <= 1'b1;
156
  else if (s_return == C_RETURN_DEC)
157
    s__R_valid <= s__return_stack_valid;
158
  else
159
    s__R_valid <= s__R_valid;
160
//
161
initial s__return_stack_valid = 1'b0;
162
always @ (posedge i_clk)
163
  if (i_rst)
164
    s__return_stack_valid <= 1'b0;
165
  else if (s_return == C_RETURN_INC)
166
    s__return_stack_valid <= s__R_valid;
167
  else if (s_return == C_RETURN_DEC)
168
    if (s_R_stack_ptr == {(C_RETURN_PTR_WIDTH){1'b0}})
169
      s__return_stack_valid <= 1'b0;
170
    else
171
      s__return_stack_valid <= s__return_stack_valid;
172
  else
173
    s__return_stack_valid <= s__return_stack_valid;
174
//
175
reg s__return_stack_error = 1'b0;
176
always @ (posedge i_clk)
177
  if (!s__return_stack_error) begin
178
    if ((s_return == C_RETURN_DEC) && !s__R_valid) begin
179
      $display("%12d : Return stack underflow in @CORENAME@", $time);
180
      s__return_stack_error <= 1'b1;
181
    end
182
    if ((s_return == C_RETURN_INC) && (s_R_stack_ptr == {(C_RETURN_PTR_WIDTH){1'b1}}) && s__return_stack_valid) begin
183
      $display("%12d : Return stack overflow in @CORENAME@", $time);
184
      s__return_stack_error <= 1'b1;
185
    end
186
  end
187
//
188
reg s__R_is_address = 1'b0;
189
reg [2**C_RETURN_PTR_WIDTH-1:0] s__return_is_address = {(2**C_RETURN_PTR_WIDTH){1'b0}};
190
always @ (posedge i_clk)
191
  if (i_rst) begin
192
    s__R_is_address <= 1'b0;
193
    s__return_is_address <= {(2**C_RETURN_PTR_WIDTH){1'b0}};
194
  end else if (s_return == C_RETURN_INC) begin
195
    s__R_is_address <= (s_bus_r == C_BUS_R_PC);
196
    s__return_is_address[s_R_stack_ptr_next] <= s__R_is_address;
197
  end else if (s_return == C_RETURN_DEC) begin
198
    s__R_is_address <= s__return_is_address[s_R_stack_ptr];
199
  end
200
//
201
reg s__R_address_error = 1'b0;
202
always @ (posedge i_clk)
203
  if (!s__R_address_error) begin
204
    if ((s_bus_pc == C_BUS_PC_RETURN) && !s__R_is_address) begin
205
      $display("%12d : Non-address by return instruction in @CORENAME@", $time);
206
      s__R_address_error <= 1'b1;
207
    end
208
    if (((s_opcode == 9'b00_0001_001) || (s_opcode == 9'b00_1001_001)) && s__R_is_address) begin
209
      $display("%12d : Copied address to data stack in @CORENAME@", $time);
210
      s__R_address_error <= 1'b1;
211
    end
212
  end
213
//
214
reg s__range_error = 1'b0;
215
reg [8:0] s__mem_address_limit[0:3];
216
initial begin
217
  s__mem_address_limit[0] = @MEM_LIMIT_0@;
218
  s__mem_address_limit[1] = @MEM_LIMIT_1@;
219
  s__mem_address_limit[2] = @MEM_LIMIT_2@;
220
  s__mem_address_limit[3] = @MEM_LIMIT_3@;
221
end
222
always @ (posedge i_clk)
223
  if ((s_opcode[3+:6] == 6'b000110) && ({ 1'b0, s_T } >= @LAST_INPORT@)) begin
224
    $display("%12d : Range error on inport in @CORENAME@", $time);
225
    s__range_error <= 1'b1;
226
  end else if ((s_opcode[3+:6] == 6'b000111) && ({ 1'b0, s_T } >= @LAST_OUTPORT@)) begin
227
    $display("%12d : Range error on outport in @CORENAME@", $time);
228
    s__range_error <= 1'b1;
229
  end else if ((s_opcode[5+:4] == 4'b0011) && ({ 1'b0, s_T } >= s__mem_address_limit[s_opcode[0+:2]])) begin
230
    $display("%12d : Range error on memory operation in @CORENAME@", $time);
231
    s__range_error <= 1'b1;
232
  end
233
//
234
reg       [L__TRACE_SIZE-1:0] s__history[@HISTORY@-1:0];
235
reg                     [8:0] s__opcode_s = 9'b0;
236
reg          [C_PC_WIDTH-1:0] s__PC_s[1:0];
237
integer ix__history;
238
initial begin
239
  for (ix__history=0; ix__history<@HISTORY@; ix__history=ix__history+1)
240
    s__history[ix__history] = {(L__TRACE_SIZE){1'b0}};
241
  s__PC_s[0] = {(C_PC_WIDTH){1'b0}};
242
  s__PC_s[1] = {(C_PC_WIDTH){1'b0}};
243
end
244
always @ (posedge i_clk) begin
245
  s__PC_s[1] <= s__PC_s[0];
246
  s__PC_s[0] <= s_PC;
247
  s__opcode_s <= s_opcode;
248
  for (ix__history=1; ix__history<@HISTORY@; ix__history=ix__history+1)
249
    s__history[ix__history-1] <= s__history[ix__history];
250
  s__history[@HISTORY@-1] <= { s__PC_s[1], s__opcode_s, s_Np_stack_ptr, s__N_valid, s_N, s__T_valid, s_T, s__R_valid, s_R, s_R_stack_ptr };
251
end
252
wire s_terminate = s__PC_error || s__data_stack_error || s__return_stack_error || s__R_address_error || s__range_error;
253
always @ (posedge s_terminate) begin
254
  for (ix__history=0; ix__history<@HISTORY@; ix__history=ix__history+1)
255
    display_trace(s__history[ix__history]);
256
  display_trace({ s__PC_s[1], s__opcode_s, s_Np_stack_ptr, s__N_valid, s_N, s__T_valid, s_T, s__R_valid, s_R, s_R_stack_ptr });
257
  $finish;
258
end
259
endgenerate

powered by: WebSVN 2.1.0

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