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

Subversion Repositories ssbcc

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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