Line 1... |
Line 1... |
//
|
//
|
// monitor_stack peripheral
|
// monitor_stack peripheral
|
// Copyright 2013, Sinclair R.F., Inc.
|
// Copyright 2013-2015, Sinclair R.F., Inc.
|
//
|
//
|
// Note: The validity of N and T are not monitored for invalid operations. For
|
// Note: The validity of N and T are not monitored for invalid operations. For
|
// example, if N is not valid and a "swap" is performed, then the data
|
// example, if N is not valid and a "swap" is performed, then the data
|
// stack is no longer valid and an error is detected. Thus, the validity
|
// stack is no longer valid and an error is detected. Thus, the validity
|
// of N and T do not need to be monitored for "swap" operations.
|
// of N and T do not need to be monitored for "swap" operations.
|
Line 23... |
Line 23... |
//
|
//
|
initial s__T_valid = 1'b0;
|
initial s__T_valid = 1'b0;
|
always @ (posedge i_clk)
|
always @ (posedge i_clk)
|
if (i_rst)
|
if (i_rst)
|
s__T_valid <= 1'b0;
|
s__T_valid <= 1'b0;
|
|
else if (s_interrupt || s_interrupted)
|
|
s__T_valid <= s__T_valid;
|
else case (s_bus_t)
|
else case (s_bus_t)
|
C_BUS_T_OPCODE: s__T_valid <= 1'b1;
|
C_BUS_T_OPCODE: s__T_valid <= 1'b1;
|
C_BUS_T_N: s__T_valid <= s__N_valid;
|
C_BUS_T_N: s__T_valid <= s__N_valid;
|
C_BUS_T_PRE: case (s_opcode[0+:2])
|
C_BUS_T_PRE: case (s_opcode[0+:2])
|
2'b00: s__T_valid <= s__T_valid;
|
2'b00: s__T_valid <= s__T_valid;
|
Line 87... |
Line 89... |
end
|
end
|
if (!s__N_valid && (s_Np_stack_ptr[2+:C_DATA_PTR_WIDTH-2] != {(C_DATA_PTR_WIDTH-2){1'b1}})) begin
|
if (!s__N_valid && (s_Np_stack_ptr[2+:C_DATA_PTR_WIDTH-2] != {(C_DATA_PTR_WIDTH-2){1'b1}})) begin
|
$display("%12d : Malformed next-to-top-of-data-stack validity in @CORENAME@", $time);
|
$display("%12d : Malformed next-to-top-of-data-stack validity in @CORENAME@", $time);
|
s__data_stack_error <= 1'b1;
|
s__data_stack_error <= 1'b1;
|
end
|
end
|
case (s_bus_t)
|
if (s_interrupt || s_interrupted)
|
|
; // do nothing
|
|
else case (s_bus_t)
|
C_BUS_T_MATH_ROTATE:
|
C_BUS_T_MATH_ROTATE:
|
if (!s__T_valid && (s_opcode[0+:3] != 3'h0)) begin
|
if (!s__T_valid && (s_opcode[0+:3] != 3'h0)) begin
|
$display("%12d : Illegal rotate on invalid top of data stack in @CORENAME@", $time);
|
$display("%12d : Illegal rotate on invalid top of data stack in @CORENAME@", $time);
|
s__data_stack_error <= 1'b1;
|
s__data_stack_error <= 1'b1;
|
end
|
end
|
Line 136... |
Line 140... |
s__data_stack_error <= 1'b1;
|
s__data_stack_error <= 1'b1;
|
end
|
end
|
default:
|
default:
|
;
|
;
|
endcase
|
endcase
|
if ((s_opcode == 9'b00_0111_000) && !s__T_valid) begin
|
if (s_interrupt || s_interrupted)
|
|
; // do nothing
|
|
else if ((s_opcode == 9'b00_0111_000) && !s__T_valid) begin
|
$display("%12d : Outport with invalid top-of-data-stack in @CORENAME@", $time);
|
$display("%12d : Outport with invalid top-of-data-stack in @CORENAME@", $time);
|
s__data_stack_error <= 1'b1;
|
s__data_stack_error <= 1'b1;
|
end
|
end
|
if ((s_opcode == 9'b00_0111_000) && !s__N_valid && !s__outport_pure_strobe) begin
|
if ((s_opcode == 9'b00_0111_000) && !s__N_valid && !s__outport_pure_strobe) begin
|
$display("%12d : Outport with invalid next-to-top-of-data-stack in @CORENAME@", $time);
|
$display("%12d : Outport with invalid next-to-top-of-data-stack in @CORENAME@", $time);
|
Line 191... |
Line 197... |
always @ (posedge i_clk)
|
always @ (posedge i_clk)
|
if (i_rst) begin
|
if (i_rst) begin
|
s__R_is_address <= 1'b0;
|
s__R_is_address <= 1'b0;
|
s__return_is_address <= {(2**C_RETURN_PTR_WIDTH){1'b0}};
|
s__return_is_address <= {(2**C_RETURN_PTR_WIDTH){1'b0}};
|
end else if (s_return == C_RETURN_INC) begin
|
end else if (s_return == C_RETURN_INC) begin
|
s__R_is_address <= (s_bus_r == C_BUS_R_PC);
|
s__R_is_address <= s_interrupt || (s_bus_r == C_BUS_R_PC);
|
s__return_is_address[s_R_stack_ptr_next] <= s__R_is_address;
|
s__return_is_address[s_R_stack_ptr_next] <= s__R_is_address;
|
end else if (s_return == C_RETURN_DEC) begin
|
end else if (s_return == C_RETURN_DEC) begin
|
s__R_is_address <= s__return_is_address[s_R_stack_ptr];
|
s__R_is_address <= s__return_is_address[s_R_stack_ptr];
|
end
|
end
|
//
|
//
|
Line 204... |
Line 210... |
if (!s__R_address_error) begin
|
if (!s__R_address_error) begin
|
if ((s_bus_pc == C_BUS_PC_RETURN) && !s__R_is_address) begin
|
if ((s_bus_pc == C_BUS_PC_RETURN) && !s__R_is_address) begin
|
$display("%12d : Non-address by return instruction in @CORENAME@", $time);
|
$display("%12d : Non-address by return instruction in @CORENAME@", $time);
|
s__R_address_error <= 1'b1;
|
s__R_address_error <= 1'b1;
|
end
|
end
|
if (((s_opcode == 9'b00_0001_001) || (s_opcode == 9'b00_1001_001)) && s__R_is_address) begin
|
if (s_interrupt || s_interrupted)
|
|
; // do nothing
|
|
else if (((s_opcode == 9'b00_0001_001) || (s_opcode == 9'b00_1001_001)) && s__R_is_address) begin
|
$display("%12d : Copied address to data stack in @CORENAME@", $time);
|
$display("%12d : Copied address to data stack in @CORENAME@", $time);
|
s__R_address_error <= 1'b1;
|
s__R_address_error <= 1'b1;
|
end
|
end
|
end
|
end
|
//
|
//
|
Line 219... |
Line 227... |
s__mem_address_limit[1] = @MEM_LIMIT_1@;
|
s__mem_address_limit[1] = @MEM_LIMIT_1@;
|
s__mem_address_limit[2] = @MEM_LIMIT_2@;
|
s__mem_address_limit[2] = @MEM_LIMIT_2@;
|
s__mem_address_limit[3] = @MEM_LIMIT_3@;
|
s__mem_address_limit[3] = @MEM_LIMIT_3@;
|
end
|
end
|
always @ (posedge i_clk)
|
always @ (posedge i_clk)
|
if ((s_opcode[3+:6] == 6'b000110) && ({ 1'b0, s_T } >= @LAST_INPORT@)) begin
|
if (s_interrupt || s_interrupted) begin
|
|
// do nothing
|
|
end else if ((s_opcode[3+:6] == 6'b000110) && ({ 1'b0, s_T } >= @LAST_INPORT@)) begin
|
$display("%12d : Range error on inport in @CORENAME@", $time);
|
$display("%12d : Range error on inport in @CORENAME@", $time);
|
s__range_error <= 1'b1;
|
s__range_error <= 1'b1;
|
end else if ((s_opcode[3+:6] == 6'b000111) && ({ 1'b0, s_T } >= @LAST_OUTPORT@)) begin
|
end else if ((s_opcode[3+:6] == 6'b000111) && ({ 1'b0, s_T } >= @LAST_OUTPORT@)) begin
|
$display("%12d : Range error on outport in @CORENAME@", $time);
|
$display("%12d : Range error on outport in @CORENAME@", $time);
|
s__range_error <= 1'b1;
|
s__range_error <= 1'b1;
|
Line 233... |
Line 243... |
end
|
end
|
//
|
//
|
reg [L__TRACE_SIZE-1:0] s__history[@HISTORY@-1:0];
|
reg [L__TRACE_SIZE-1:0] s__history[@HISTORY@-1:0];
|
reg [8:0] s__opcode_s = 9'b0;
|
reg [8:0] s__opcode_s = 9'b0;
|
reg [C_PC_WIDTH-1:0] s__PC_s[1:0];
|
reg [C_PC_WIDTH-1:0] s__PC_s[1:0];
|
|
reg s__interrupt_s = 1'b0;
|
|
reg s__interrupted_s = 1'b0;
|
integer ix__history;
|
integer ix__history;
|
initial begin
|
initial begin
|
for (ix__history=0; ix__history<@HISTORY@; ix__history=ix__history+1)
|
for (ix__history=0; ix__history<@HISTORY@; ix__history=ix__history+1)
|
s__history[ix__history] = {(L__TRACE_SIZE){1'b0}};
|
s__history[ix__history] = {(L__TRACE_SIZE){1'b0}};
|
s__PC_s[0] = {(C_PC_WIDTH){1'b0}};
|
s__PC_s[0] = {(C_PC_WIDTH){1'b0}};
|
s__PC_s[1] = {(C_PC_WIDTH){1'b0}};
|
s__PC_s[1] = {(C_PC_WIDTH){1'b0}};
|
end
|
end
|
always @ (posedge i_clk) begin
|
always @ (posedge i_clk) begin
|
s__PC_s[1] <= s__PC_s[0];
|
s__PC_s[1] <= s__PC_s[0];
|
s__PC_s[0] <= s_PC;
|
s__PC_s[0] <= s_PC;
|
|
s__interrupt_s <= s_interrupt;
|
|
s__interrupted_s <= s_interrupted;
|
s__opcode_s <= s_opcode;
|
s__opcode_s <= s_opcode;
|
for (ix__history=1; ix__history<@HISTORY@; ix__history=ix__history+1)
|
for (ix__history=1; ix__history<@HISTORY@; ix__history=ix__history+1)
|
s__history[ix__history-1] <= s__history[ix__history];
|
s__history[ix__history-1] <= s__history[ix__history];
|
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 };
|
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 };
|
end
|
end
|
wire s_terminate = s__PC_error || s__data_stack_error || s__return_stack_error || s__R_address_error || s__range_error;
|
wire s_terminate = s__PC_error || s__data_stack_error || s__return_stack_error || s__R_address_error || s__range_error;
|
always @ (posedge s_terminate) begin
|
always @ (posedge s_terminate) begin
|
for (ix__history=0; ix__history<@HISTORY@; ix__history=ix__history+1)
|
for (ix__history=0; ix__history<@HISTORY@; ix__history=ix__history+1)
|
display_trace(s__history[ix__history]);
|
display_trace(s__history[ix__history]);
|
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 });
|
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 });
|
$finish;
|
$finish;
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
No newline at end of file
|
No newline at end of file
|