blob: b58c14eb413a34b0511d5d3c801ff6e46260a376 [file] [log] [blame]
`timescale 1ns / 1ps
module addressalyzer (
input wire RST,
input wire SPI_CLK,
input start_of_transfer,
input end_of_transfer,
input [7:0] data_in_value,
input data_in_ready,
input data_out_request,
input write_enable_mask,
output wire [14:0] ram_address_out,
output reg address_strobe,
output ram_read_strobe,
output ram_write_strobe
);
wire read_cycle;
// //////////////////////////////////////////////////////
// Address FSM signals
parameter ADDR_SIZE = 6;
parameter ADDR_IDLE = 6'b000001;
parameter ADDR_ADDR1 = 6'b000010;
parameter ADDR_ADDR2 = 6'b000100;
parameter ADDR_RD_BYTES = 6'b001000;
parameter ADDR_WR_BYTEQ = 6'b010000;
parameter ADDR_WR_BYTES = 6'b100000;
reg [ADDR_SIZE - 1:0] addr_state;
reg [15:0] address_local;
assign read_cycle = address_local[15];
assign ram_address_out = address_local[14:0];
always @ (posedge SPI_CLK) begin
if(RST) begin
address_local <= 0;
address_strobe <= 0;
addr_state <= ADDR_IDLE;
end
else begin
case (addr_state)
ADDR_IDLE:
begin
address_local <= 0;
address_strobe <= 0;
if (start_of_transfer == 1'b1) begin
addr_state <= ADDR_ADDR1;
end
end
ADDR_ADDR1:
if (data_in_ready == 1'b1) begin
address_local <= {data_in_value, data_in_value};
addr_state <= ADDR_ADDR2;
end
ADDR_ADDR2:
if (data_in_ready == 1'b1) begin
address_local <= {address_local[15:8], data_in_value};
address_strobe <= 1;
if (read_cycle == 1'b1) begin
addr_state <= ADDR_RD_BYTES;
end else begin
addr_state <= ADDR_WR_BYTEQ;
end
end
ADDR_RD_BYTES:
if (data_out_request == 1'b1) begin
address_local <= address_local + 1'b1;
address_strobe <= 0;
end else if (end_of_transfer == 1'b1) begin
addr_state <= ADDR_IDLE;
address_strobe <= 0;
end
ADDR_WR_BYTEQ:
if (data_in_ready == 1'b1) begin
addr_state <= ADDR_WR_BYTES;
address_strobe <= 0;
end else if (end_of_transfer == 1'b1) begin
addr_state <= ADDR_IDLE;
address_strobe <= 0;
end
ADDR_WR_BYTES:
if (data_in_ready == 1'b1) begin
address_local <= address_local + 1'b1;
end else if (end_of_transfer == 1'b1) begin
addr_state <= ADDR_IDLE;
end
default: begin
addr_state <= ADDR_IDLE;
end
endcase
end
end
// //////////////////////////////////////////////////////
// Read/Write FSM signals
parameter RDWR_SIZE = 4;
parameter RDWR_IDLE = 4'b0001;
parameter RDWR_CLK_EN = 4'b0010;
parameter RDWR_STROBE0 = 4'b0100;
parameter RDWR_END = 4'b1000;
reg [RDWR_SIZE - 1:0] rdwr_state;
reg rdwr_read_en;
reg rdwr_write_en;
assign ram_read_strobe = rdwr_read_en;
assign ram_write_strobe = rdwr_write_en;
always @ (posedge SPI_CLK) begin
if(RST) begin
rdwr_state <= RDWR_IDLE;
rdwr_read_en <= 0;
rdwr_write_en <= 0;
end
else begin
case (rdwr_state)
RDWR_IDLE:
if (addr_state == ADDR_WR_BYTES) begin
rdwr_read_en <= 0;
rdwr_write_en <= write_enable_mask;
rdwr_state <= RDWR_CLK_EN;
end else if (addr_state == ADDR_RD_BYTES) begin
rdwr_read_en <= 0;
rdwr_write_en <= 0;
rdwr_state <= RDWR_CLK_EN;
end
RDWR_CLK_EN:
if (addr_state == ADDR_WR_BYTES) begin
rdwr_read_en <= 0;
rdwr_write_en <= 0;
rdwr_state <= RDWR_STROBE0;
end else if (addr_state == ADDR_RD_BYTES) begin
rdwr_read_en <= 1;
rdwr_write_en <= 0;
rdwr_state <= RDWR_STROBE0;
end
RDWR_STROBE0:
begin
rdwr_read_en <= 0;
rdwr_write_en <= 0;
rdwr_state <= RDWR_END;
end
RDWR_END:
begin
if (data_in_ready == 1'b1) begin
rdwr_state <= RDWR_IDLE;
end
end
default:
begin
rdwr_state <= RDWR_IDLE;
end
endcase
end
end
endmodule // addressalyzer