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

Subversion Repositories ssbcc

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

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

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

powered by: WebSVN 2.1.0

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