`define ROM_SIZE 6'd15 module SPI_RAM (i_clk,i_res_L, i_address, o_readdata, i_writedata, i_read, i_write, i_rdy,o_data,o_valid ); input i_clk,i_res_L,i_rdy; input [1:0] i_address; output [31:0] o_readdata; input [31:0] i_writedata; input i_read,i_write; output [15:0] o_data; output reg o_valid; reg [2:0] r_fasi; reg [3:0] r_addr; reg [31:0] MEM [3:0]; wire [31:0] TMP; wire [7:0] REG32[3:0]; wire [1:0] w_indMEM; wire [1:0] w_indREG32; // ------Memory ACCESS ---------- // Read from MEM assign o_readdata = (i_read) ? MEM[i_address] : {32{1'bz}}; // Write MEM always @(posedge i_clk) if (i_write) MEM[i_address] = i_writedata; //------------------------------- // contatore delle fasi always @(posedge i_clk or negedge i_res_L) begin if (!i_res_L) r_fasi<=3'b000; else if (!i_rdy) r_fasi<=3'b000; else if ((i_rdy)&(r_fasi < 3'b111)) r_fasi <= r_fasi + 3'b001; end // generazione segnale "o_valid" always @(posedge i_clk or negedge i_res_L) begin if (!i_res_L) o_valid<=0; else if ((r_fasi==3'b100)) o_valid<=1; else o_valid<=0; end // incremento dell'indirizzo always @(posedge i_clk or negedge i_res_L) begin if (!i_res_L) r_addr = 0; else if (r_fasi==3'b001) // incremento dell'indirizzo un ciclo di clock dopo i_rdy r_addr=r_addr+1; else if (r_addr > `ROM_SIZE) // Contatore ciclico r_addr = 0; end //dato in uscita assign w_indMEM = r_addr[3:2]; assign w_indREG32 = r_addr[1:0]; assign TMP = MEM[w_indMEM]; assign REG32[0] = TMP[31:24]; assign REG32[1] = TMP[23:16]; assign REG32[2] = TMP[15:8]; assign REG32[3] = TMP[7:0]; assign o_data = {4'h0,r_addr[3:0],REG32[w_indREG32]}; endmodule