2021-09-25 20:00:36 +02:00
|
|
|
module n64_bootloader (
|
|
|
|
if_system.sys sys,
|
2021-10-26 23:44:09 +02:00
|
|
|
if_n64_bus bus,
|
2022-02-02 19:07:43 +01:00
|
|
|
if_config.flash cfg,
|
|
|
|
if_flash.flash flash
|
2021-09-25 20:00:36 +02:00
|
|
|
);
|
|
|
|
|
2021-10-26 23:44:09 +02:00
|
|
|
typedef enum bit [0:0] {
|
|
|
|
S_IDLE,
|
|
|
|
S_WAIT
|
|
|
|
} e_state;
|
|
|
|
|
|
|
|
typedef enum bit [0:0] {
|
|
|
|
T_N64,
|
|
|
|
T_CPU
|
|
|
|
} e_source_request;
|
|
|
|
|
|
|
|
e_state state;
|
|
|
|
e_source_request source_request;
|
|
|
|
|
2022-02-02 19:07:43 +01:00
|
|
|
logic request;
|
|
|
|
logic ack;
|
|
|
|
logic write;
|
|
|
|
logic [31:0] address;
|
|
|
|
logic [31:0] wdata;
|
|
|
|
logic [31:0] rdata;
|
2021-10-26 23:44:09 +02:00
|
|
|
|
2022-02-02 19:07:43 +01:00
|
|
|
always_ff @(posedge sys.clk) begin
|
2021-10-26 23:44:09 +02:00
|
|
|
if (sys.reset) begin
|
|
|
|
state <= S_IDLE;
|
2022-02-02 19:07:43 +01:00
|
|
|
request <= 1'b0;
|
2021-10-26 23:44:09 +02:00
|
|
|
end else begin
|
|
|
|
case (state)
|
|
|
|
S_IDLE: begin
|
|
|
|
if (bus.request || flash.request) begin
|
|
|
|
state <= S_WAIT;
|
2022-02-02 19:07:43 +01:00
|
|
|
request <= 1'b1;
|
2021-10-26 23:44:09 +02:00
|
|
|
if (bus.request) begin
|
2022-02-02 19:07:43 +01:00
|
|
|
write <= 1'b0;
|
|
|
|
address <= bus.address;
|
|
|
|
wdata <= bus.wdata;
|
2021-10-26 23:44:09 +02:00
|
|
|
source_request <= T_N64;
|
|
|
|
end else if (flash.request) begin
|
2022-02-02 19:07:43 +01:00
|
|
|
write <= flash.write;
|
|
|
|
address <= flash.address;
|
|
|
|
wdata <= flash.wdata;
|
2021-10-26 23:44:09 +02:00
|
|
|
source_request <= T_CPU;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
S_WAIT: begin
|
2022-02-02 19:07:43 +01:00
|
|
|
if (ack) begin
|
2021-10-26 23:44:09 +02:00
|
|
|
state <= S_IDLE;
|
2022-02-02 19:07:43 +01:00
|
|
|
request <= 1'b0;
|
2021-10-26 23:44:09 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
endcase
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
always_comb begin
|
2022-02-02 19:07:43 +01:00
|
|
|
bus.ack = source_request == T_N64 && ack;
|
2021-10-26 23:44:09 +02:00
|
|
|
bus.rdata = 16'd0;
|
2022-01-22 23:19:07 +01:00
|
|
|
if (bus.ack && bus.address < 32'h00010000) begin
|
2022-02-02 19:07:43 +01:00
|
|
|
if (bus.address[1]) bus.rdata = {rdata[23:16], rdata[31:24]};
|
|
|
|
else bus.rdata = {rdata[7:0], rdata[15:8]};
|
2021-10-26 23:44:09 +02:00
|
|
|
end
|
|
|
|
|
2022-02-02 19:07:43 +01:00
|
|
|
flash.ack = source_request == T_CPU && ack;
|
2021-10-26 23:44:09 +02:00
|
|
|
flash.rdata = 32'd0;
|
|
|
|
if (flash.ack) begin
|
2022-02-02 19:07:43 +01:00
|
|
|
flash.rdata = rdata;
|
2021-10-26 23:44:09 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-02-02 19:07:43 +01:00
|
|
|
vendor_flash vendor_flash_inst (
|
|
|
|
.clk(sys.clk),
|
|
|
|
.reset(sys.reset),
|
2021-10-26 23:44:09 +02:00
|
|
|
|
2022-02-02 19:07:43 +01:00
|
|
|
.erase_start(cfg.flash_erase_start),
|
|
|
|
.erase_busy(cfg.flash_erase_busy),
|
|
|
|
.wp_enable(cfg.flash_wp_enable),
|
|
|
|
.wp_disable(cfg.flash_wp_disable),
|
2021-10-26 23:44:09 +02:00
|
|
|
|
2022-02-02 19:07:43 +01:00
|
|
|
.request(request),
|
|
|
|
.ack(ack),
|
|
|
|
.write(write),
|
|
|
|
.address(address),
|
|
|
|
.wdata(wdata),
|
|
|
|
.rdata(rdata)
|
2021-09-25 20:00:36 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
endmodule
|