Skip to content

Instantly share code, notes, and snippets.

@jdesiloniz
Created March 14, 2020 20:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jdesiloniz/1ed9fdfafbb535c52ecc912d638c57bb to your computer and use it in GitHub Desktop.
Save jdesiloniz/1ed9fdfafbb535c52ecc912d638c57bb to your computer and use it in GitHub Desktop.
A draft for a breakpoint controller unit within a CPU debugger component
`default_nettype none
module breakpoint_controller #(parameter AW = 16)(
input wire clk,
input wire rstn,
input wire [AW-1:0] address, // Address to check/write/clear
input wire read_stb, // Strobe for check a breakpoint
input wire write_stb, // Strobe for writing a breakpoint
input wire clear_stb, // Strobe for clearing a breakpoint
output wire read_result // Result of a breakpoint check (1 = yup), active next cycle after read_stb
);
// Each register holds an breakpoint associated to an address. MSB is 1 if the
// breakpoint is active.
reg [AW:0] br0;
reg [AW:0] br1;
reg [AW:0] br2;
reg [AW:0] br3;
reg [AW:0] br4;
reg [AW:0] br5;
reg [AW:0] br6;
reg [AW:0] br7;
reg read_result;
wire [7:0] active_breakpoint_bits;
assign active_breakpoint_bits = {br0[AW], br1[AW], br2[AW], br3[AW], br4[AW], br5[AW], br6[AW], br7[AW]};
always @(posedge clk) begin
if (rstn == 1'b0) begin
// Initial values:
br0 <= 0;
br1 <= 0;
br2 <= 0;
br3 <= 0;
br4 <= 0;
br5 <= 0;
br6 <= 0;
br7 <= 0;
read_result <= 1'b0;
end else begin
// A breakpoint controller isn't meant to be used by multiple components,
// or to perform two operations at once.
// Checking for a breakpoint:
if (read_stb == 1'b1) begin
if (br0 == {1'b1, address})
read_result <= 1'b1;
else if (br1 == {1'b1, address})
read_result <= 1'b1;
else if (br2 == {1'b1, address})
read_result <= 1'b1;
else if (br3 == {1'b1, address})
read_result <= 1'b1;
else if (br4 == {1'b1, address})
read_result <= 1'b1;
else if (br5 == {1'b1, address})
read_result <= 1'b1;
else if (br6 == {1'b1, address})
read_result <= 1'b1;
else if (br7 == {1'b1, address})
read_result <= 1'b1;
else read_result <= 1'b0;
end else if (write_stb == 1'b1) begin
// Writing a breakpoint
// Each breakpoint register's MSB is 0 if inactive or 1 if active. So if we
// get all these bits together we can know which breakpoint is the "oldest inactive",
// and we use that spot to write a new one:
case (active_breakpoint_bits)
8'h00: br0 <= {1'b1, address};
8'h80: br1 <= {1'b1, address};
8'hC0: br2 <= {1'b1, address};
8'hE0: br3 <= {1'b1, address};
8'hF0: br4 <= {1'b1, address};
8'hF8: br5 <= {1'b1, address};
8'hFC: br6 <= {1'b1, address};
8'hFE: br7 <= {1'b1, address};
8'hFF: begin
// If all breakpoints are in use, we sacrifice the oldest one (br0)
// and write the new one in br7.
br0 <= br1;
br1 <= br2;
br2 <= br3;
br3 <= br4;
br4 <= br5;
br5 <= br6;
br6 <= br7;
br7 <= {1'b1, address};
end
endcase // active_breakpoint_bits
end else if (clear_stb == 1'b1) begin
// Clearing a breakpoint
// Depending of its position, if we find a breakpoint to clear it'll
// imply more or less breakpoint registers to move around.
// Key is to keep all "active" breakpoints as a contiguous set of registers.
if (br0 == {1'b1, address}) begin
br0 <= br1;
br1 <= br2;
br2 <= br3;
br3 <= br4;
br4 <= br5;
br5 <= br6;
br6 <= br7;
br7 <= AW'b0;
end else if (br1 == {1'b1, address}) begin
br1 <= br2;
br2 <= br3;
br3 <= br4;
br4 <= br5;
br5 <= br6;
br6 <= br7;
br7 <= AW'b0;
end else if (br2 == {1'b1, address}) begin
br2 <= br3;
br3 <= br4;
br4 <= br5;
br5 <= br6;
br6 <= br7;
br7 <= AW'b0;
end else if (br3 == {1'b1, address}) begin
br3 <= br4;
br4 <= br5;
br5 <= br6;
br6 <= br7;
br7 <= AW'b0;
end else if (br4 == {1'b1, address}) begin
br4 <= br5;
br5 <= br6;
br6 <= br7;
br7 <= AW'b0;
end else if (br5 == {1'b1, address}) begin
br5 <= br6;
br6 <= br7;
br7 <= AW'b0;
end else if (br6 == {1'b1, address}) begin
br6 <= br7;
br7 <= AW'b0;
end else if (br7 == {1'b1, address}) begin
br7 <= AW'b0;
end
end
end
end
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment