搜索
bottom↓
回复: 16

无聊了,发个SRAM控制器的verilog代码吧,仿真通过。

[复制链接]

出0入0汤圆

发表于 2009-11-20 04:22:04 | 显示全部楼层 |阅读模式
`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周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2009-11-20 04:23:11 | 显示全部楼层
附上简易仿真代码。能看一下读写波形。

module sram_ctrl_top_tb;

        // Inputs
        reg bus2ip_clk;
        reg bus2ip_reset;
        reg [31:0] bus2ip_addr;
        reg [15:0] bus2ip_data;
        reg bus2ip_rnw;
        reg bus2ip_cs;
        reg [15:0] mem_din;

        // Outputs
        wire [15:0] ip2bus_data;
        wire ip2bus_wrack;
        wire ip2bus_rdack;
        wire [31:0] mem_a;
        wire [15:0] mem_dout;
        wire mem_cen;
        wire mem_oen;
        wire mem_wen;

        // Instantiate the Unit Under Test (UUT)
        sram_ctrl_top uut (
                .bus2ip_clk(bus2ip_clk),
                .bus2ip_reset(bus2ip_reset),
                .ip2bus_data(ip2bus_data),
                .ip2bus_wrack(ip2bus_wrack),
                .ip2bus_rdack(ip2bus_rdack),
                .bus2ip_addr(bus2ip_addr),
                .bus2ip_data(bus2ip_data),
                .bus2ip_rnw(bus2ip_rnw),
                .bus2ip_cs(bus2ip_cs),
                .mem_a(mem_a),
                .mem_dout(mem_dout),
                .mem_din(mem_din),
                .mem_cen(mem_cen),
                .mem_oen(mem_oen),
                .mem_wen(mem_wen)
        );

        initial begin
                // Initialize Inputs
                bus2ip_clk = 0;
                bus2ip_reset = 0;
                bus2ip_addr = 32'h12345678;
                bus2ip_data = 16'hA0A0;
                bus2ip_rnw = 0;
                bus2ip_cs = 0;
                mem_din = 16'hFAFA;

                // Wait 100 ns for global reset to finish
                #100;
                bus2ip_reset = 1;
                #100;
                bus2ip_reset = 0;
                #100;
                bus2ip_cs = 1;
                bus2ip_rnw = 1;
                #20;
                bus2ip_cs = 0;
                bus2ip_rnw = 0;
                #100;
                bus2ip_cs = 1;
                #20;
                bus2ip_cs = 0;
                #200;
                $stop;
               
        
                // Add stimulus here

        end
      
               
always #10 bus2ip_clk = ~bus2ip_clk;

               
endmodule

出0入0汤圆

发表于 2009-11-20 08:28:52 | 显示全部楼层
还是打个包吧
顶!!!!!!!

出0入0汤圆

 楼主| 发表于 2009-11-20 18:36:43 | 显示全部楼层
嗯,发现了一个BUG,先不说。

出0入0汤圆

发表于 2010-4-20 14:32:52 | 显示全部楼层
mark.

出0入0汤圆

发表于 2010-6-16 16:37:13 | 显示全部楼层
过两天来看程序 找找你留下的bug回复【3楼】ngzhang 兽哥
-----------------------------------------------------------------------

过两天来看程序 找找你留下的bug

出0入0汤圆

发表于 2011-7-7 17:20:50 | 显示全部楼层
if((CS == WR_ACTIVE1)||(CS == WR_ACTIVE2))
mem_wen <= 1'b0;
这个好像是bug吧?经波形仿真,有问题
改成:
if(CS == WR_ACTIVE1)
   mem_wen <= 1'b0;
else if(CS == WR_ACTIVE2)
   mem_wen <= 1'b0;
else
   mem_wen <= 1'b1;
就OK啦!不过具体怎么回事我不清楚啊,菜鸟一个,请高手解答!

出0入0汤圆

发表于 2011-7-23 17:01:01 | 显示全部楼层
mark.

出0入0汤圆

发表于 2011-10-10 16:45:55 | 显示全部楼层
mark

出0入8汤圆

发表于 2011-10-10 20:36:00 | 显示全部楼层
SRAM要用6周期这个咋想的啊

出0入0汤圆

 楼主| 发表于 2011-10-11 13:16:47 | 显示全部楼层
回复【9楼】uindex  
-----------------------------------------------------------------------

简单稳定。

出0入0汤圆

发表于 2011-10-11 14:09:55 | 显示全部楼层
有没有操作双口RAM的程序啊?

出0入0汤圆

发表于 2011-10-12 00:02:53 | 显示全部楼层
hehe 学习了

出0入0汤圆

发表于 2011-10-14 09:53:31 | 显示全部楼层
SRAM时序很简单,只需要在CE使能的时候,掌握好数据线、地址线、与写使能之间的建立和释放 就好。

出0入0汤圆

发表于 2012-6-14 10:55:47 | 显示全部楼层
不错的,但是这是针对那个芯片的啊

出0入0汤圆

发表于 2012-6-14 13:36:09 | 显示全部楼层
仿真过了,实际驱动芯片试过吗?

出0入0汤圆

发表于 2012-6-15 14:48:07 | 显示全部楼层
          mark
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 09:28

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表