|
`timescale 1ns / 1ns
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 02:18:56 11/20/2009
// Design Name:
// Module Name: sram_ctrl_top
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
/////性能很低的SRAM控制器,好在简单易懂,占用资源也小。6个周期完成一个读或者写操作......////
/////只能操作一片16位宽的异步SRAM,想控制更多可以自己修改..//////
/////以下信号名称顾名思义.../////
module sram_ctrl_top(
bus2ip_clk,
bus2ip_reset,
ip2bus_data,
ip2bus_wrack,
ip2bus_rdack,
bus2ip_addr,
bus2ip_data,
bus2ip_rnw,
bus2ip_cs,
mem_a,
mem_dout,
mem_din,
mem_cen,
mem_oen,
mem_wen
);
parameter IDLE = 'd0;
parameter RD_LATCH = 'd1;
parameter RD_ACTIVE = 'd2;
parameter RD_FINISH = 'd3;
parameter WR_LATCH = 'd4;
parameter WR_ACTIVE1 = 'd5;
parameter WR_ACTIVE2 = 'd6;
parameter WR_FINISH = 'd7;
input bus2ip_clk, bus2ip_reset, bus2ip_rnw, bus2ip_cs;
input [31:0]bus2ip_addr;
input [15:0]bus2ip_data;
input [15:0]mem_din;
output ip2bus_wrack, ip2bus_rdack;
output [15:0]ip2bus_data;
output [15:0]mem_dout;
output [31:0]mem_a;
output mem_cen, mem_oen, mem_wen;
reg [3:0]NS, CS;
reg [15:0]mem_dout, ip2bus_data;
reg [31:0]mem_a;
reg mem_cen, mem_oen, mem_wen;
reg ip2bus_wrack, ip2bus_rdack;
always@(posedge bus2ip_clk)
if(bus2ip_reset == 1'b1)
CS <= IDLE;
else
CS <= NS;
always@(*)
begin
case(CS)
IDLE:begin //// CS信号有效后,根据RNW的高低,1进入读状态,0进入写状态.....////
if(bus2ip_cs)
if(bus2ip_rnw)
NS = RD_LATCH;
else
NS = WR_LATCH;
else
NS = IDLE;
end
RD_LATCH:begin ////在这个状态锁存读地址数据,CE和OE信号也拉低....////
NS = RD_ACTIVE;
end
RD_ACTIVE:begin////在这个状态保持,等待SRAM的输出稳定..../////
NS = RD_FINISH;
end
RD_FINISH:begin/////锁存SRAM输出的数据并给出RDACK信号...,然后回到初始状态.//////
NS = IDLE;
end
WR_LATCH:begin/////在这个状态锁存上层给的写地址和写数据.../////
NS = WR_ACTIVE1;
end
WR_ACTIVE1:begin/////拉低CE,OE,WE信号.../////
NS = WR_ACTIVE2;
end
WR_ACTIVE2:begin////继续拉低这些信号等待稳定...////
NS = WR_FINISH;
end
WR_FINISH:begin ////拉高WE信号,同时给出WRACK信号,注意此时ADDR和DOUT的数据继续给出,防止不稳定..../////
NS = IDLE;
end
default: NS = IDLE;
endcase
end
////下面是具体的操作,很容易看懂就不详细说了...///
always@(posedge bus2ip_clk)
if(CS == IDLE)
mem_a <= 1'b0;
else
if((CS == RD_LATCH)||(CS == WR_LATCH))
mem_a <= bus2ip_addr;
else
mem_a <= mem_a;
always@(posedge bus2ip_clk)
if(CS == IDLE)
mem_dout <= 1'b0;
else
if(CS == WR_LATCH)
mem_dout <= bus2ip_data;
else
mem_dout <= mem_dout;
always@(posedge bus2ip_clk)
if(CS == IDLE)
ip2bus_data <= 1'b0;
else
if(CS == RD_FINISH)
ip2bus_data <= mem_din;
else
ip2bus_data <= ip2bus_data;
always@(posedge bus2ip_clk)
if(CS == IDLE)
ip2bus_rdack <= 1'b0;
else
if(CS == RD_FINISH)
ip2bus_rdack <= 1'b1;
else
ip2bus_rdack <= 1'b0;
always@(posedge bus2ip_clk)
if(CS == IDLE)
ip2bus_wrack <= 1'b0;
else
if(CS == WR_FINISH)
ip2bus_wrack <= 1'b1;
else
ip2bus_wrack <= 1'b0;
always@(posedge bus2ip_clk)
if(CS == IDLE)
mem_cen <= 1'b1;
else
mem_cen <= 1'b0;
always@(posedge bus2ip_clk)
if(CS == IDLE)
mem_oen <= 1'b1;
else
mem_oen <= 1'b0;
always@(posedge bus2ip_clk)
if(CS == IDLE)
mem_wen <= 1'b1;
else
if((CS == WR_ACTIVE1)||(CS == WR_ACTIVE2))
mem_wen <= 1'b0;
else
mem_wen <= 1'b1;
endmodule |
阿莫论坛20周年了!感谢大家的支持与爱护!!
你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。
|