stack-machine/sram.v

126 lines
3.0 KiB
Verilog

module WB_SRAM (CLK_I, RST_I, ADR_I, DAT_I, DAT_O, STB_I, WE_I, SEL_I, ACK_O,
SRAM_IO1, SRAM_CE1, SRAM_UB1, SRAM_LB1, SRAM_ADR, SRAM_WE, SRAM_OE,
SRAM_IO2, SRAM_CE2, SRAM_UB2, SRAM_LB2);
// Wishbone signals
input CLK_I, RST_I, STB_I, WE_I;
input [17:0] ADR_I;
input [31:0] DAT_I;
output [31:0] DAT_O;
input [3:0] SEL_I;
output ACK_O;
// SRAM signals
output [17:0] SRAM_ADR;
output SRAM_WE, SRAM_OE;
inout [15:0] SRAM_IO1, SRAM_IO2;
output SRAM_CE1, SRAM_CE2;
output SRAM_UB1, SRAM_UB2;
output SRAM_LB1, SRAM_LB2;
assign SRAM_CE1 = 1'b0;
assign SRAM_CE2 = 1'b0;
// synthesis attribute iob of SRAM_ADR_O is true;
// synthesis attribute iob of SRAM_DAT_O is true;
// synthesis attribute iob of SRAM_SEL_O is true;
// synthesis attribute iob of SRAM_OE_O is true;
// synthesis attribute iob of SRAM_WE_O is true;
// synthesis attribute iob of HIGH_Z is true;
reg [17:0] SRAM_ADR_O;
reg [31:0] SRAM_DAT_O;
wire [31:0] SRAM_DAT_I;
reg [3:0] SRAM_SEL_O;
reg HIGH_Z = 1'b1;
assign SRAM_UB1 = SRAM_SEL_O[3];
assign SRAM_LB1 = SRAM_SEL_O[2];
assign SRAM_UB2 = SRAM_SEL_O[1];
assign SRAM_LB2 = SRAM_SEL_O[0];
assign SRAM_ADR = SRAM_ADR_O;
assign SRAM_IO1 = HIGH_Z ? 16'dZ : SRAM_DAT_O[31:16];
assign SRAM_IO2 = HIGH_Z ? 16'dZ : SRAM_DAT_O[15: 0];
assign SRAM_DAT_I = { SRAM_IO1, SRAM_IO2 };
`define SRS_IDLE 2'd0
`define SRS_READ 2'd1
`define SRS_WRITE 2'd2
reg [1:0] STATE = `SRS_IDLE;
reg SRAM_WE = 1'b1;
reg SRAM_OE = 1'b1;
reg ACK_O = 1'b0;
reg [31:0] DAT_O;
always @(negedge CLK_I)
SRAM_WE <= ~(STATE == `SRS_WRITE);
always @(posedge CLK_I)
begin
DAT_O <= SRAM_DAT_I;
if (RST_I)
begin
SRAM_OE <= 1'b1;
HIGH_Z <= 1'b1;
ACK_O <= 1'b0;
STATE <= `SRS_IDLE;
end
else
begin
case (STATE)
`SRS_IDLE:
begin
SRAM_ADR_O <= ADR_I;
SRAM_DAT_O <= DAT_I;
SRAM_SEL_O <= ~SEL_I;
ACK_O <= 1'b0;
if (STB_I)
begin
if (WE_I)
begin
SRAM_OE <= 1'b1;
HIGH_Z <= 1'b0;
STATE <= `SRS_WRITE;
end
else
begin
SRAM_OE <= 1'b0;
HIGH_Z <= 1'b1;
STATE <= `SRS_READ;
end
end
else
begin
SRAM_OE <= 1'b1;
HIGH_Z <= 1'b1;
STATE <= `SRS_IDLE;
end
end
`SRS_READ:
begin
SRAM_OE <= 1'b1;
HIGH_Z <= 1'b1;
ACK_O <= 1'b1;
STATE <= `SRS_IDLE;
end
`SRS_WRITE:
begin
SRAM_OE <= 1'b1;
HIGH_Z <= 1'b1;
ACK_O <= 1'b1;
STATE <= `SRS_IDLE;
end
default:
STATE <= `SRS_IDLE;
endcase
end
end
endmodule