新闻  |   论坛  |   博客  |   在线研讨会
EEPROM接口的FPGA实现_fpga资料_明德扬至简设计法
billow兔 | 2017-08-02 17:57:45    阅读:914   发布文章

AT93C46的MIX功能

1 功能概述

AT93C46在DI接收到读指令时,地址被解码,数据在DO引脚上串行输出。写周期是完全自主调时的,在写入之前不需要单独的擦除周期。只有当器件处于擦除/写使能状态时,写周期才有效。当写入周期开始后,CS被置为高电平时,DO引脚输出处于就绪/忙状态。本项目要求AT93C46在前两个单独案例的基础上完成读和写功能的混合功能。

2 设计思路

读(READ)指令包含要读取的存储器位置的地址代码。在接收到指令后,地址被解码,来自存储器的所选数据在串行输出引脚DO处可用。输出数据的变化与SK时钟上升沿同步。需要注意的是,在8或16位数据输出的字符串之前会有1比特的虚拟位(逻辑“0”)。

写(WRITE)指令包含要写入指定存储器的8位或16位数据。自定义编程周期twp始于最后一位数据在输入引脚DI接收的完成。如果CS在保持低电平至少250 ns(tcs)后拉高,则DO引脚输出读/忙状态。DO处的逻辑“0”表示编程仍在进行中,而逻辑“1”表示存储位置指定的地址已经写入指令中包含的数据模式,并且准备好下一步的指令。如果CS在自定义编程周期twp结束后拉高,则无法获得就绪/忙状态。

本案例要求实现一个AT93C46的接口能够根据命令,实现EWEN、WRITE和READ功能,具体思路如下:

1.          上游模块在rdy=1时,给出start命令,开始进行EWEN、WRITE或者READ操作;在rdy=0期间,start命令无效。

2.          当start有效时,如果mode=0表示进行EWEN操作;mode=1表示进行WRITE操作;mode=2表示进行READ操作。

3.          当start有效时,addr和wdata有效。

4.          当进行EWEN操作时,将addr写入at93c46。

5.          当进行WRITE操作时,将addr和wdata写入at93c46。

6.          当进行READ操作时,将addr写入at93c46,并从at93c46读到数据,通过rdata和rdata_vld返回给上游模块。

信号列表如下:

信号名

I/O

位宽

说明

clk

I

1

系统工作时钟100MHz。

rst_n

I

1

系统复位信号,低电平有效。

addr

I

7

地址信号,在start有效时,此值有效。

wdata

I

8

写数据信号,在start有效时,此值有效。

start

I

1

开始命令,仅在rdy=1时才有效。

mode

I

2

操作模式,start有效时,此值有效。

0:EWEN操作

1:WRITE操作

2:READ操作

其他:无变化

rdy

O

1

准备好信号。当rdy为1时,start才有效。在rdy为0时,不能使start有效。

rdata

O

8

从AT93C46读取的数据

rdata_vld

O

1

从AT93C46读到的数据有效指示信号

do

I

1

at93c46数据输出

di

O

1

at93c46数据输入

cs

O

1

at93c46片选

sk

O

1

at93c46时钟,1MHz

 

3 程序设计

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

module   at93c46_mix(

clk             ,

rst_n           ,

                  start            ,

                  mode           ,

addr            ,

wdata          ,

rdata           ,

rdata_vld        ,

rdy             ,

                  do             ,

                  di              ,

cs              ,

sk

    );

 

    parameter   DATA_W    =   8     ;

    parameter   EWEN      =  2'b00   ;

    parameter   WRITE      =  2'b01   ;

    parameter   READ       =  2'b10   ;

 

    input               clk          ;

    input               rst_n        ;

    input [6:0]           addr        ;

    input [1:0]           mode       ;

    input               start        ;

    input               do          ;

 

    input [DATA_W-1:0]   wdata         ;

    output              rdy         ;

    output              di          ;

    output              cs          ;

    output              sk          ;

    output[DATA_W-1:0]  rdata          ;

    output              rdata_vld    ;

 

reg   [DATA_W-1:0]  rdata          ;

reg                 rdata_vld    ;

reg                 rdy         ;

reg                 di          ;

reg                 cs          ;

reg                 sk          ;

 

reg   [17:0]         data        ;

reg   [1:0]          flag           ;

reg   [16:0]         cnt0        ;

reg   [4:0]          cnt1        ;

reg                 cnt2        ;

reg   [16:0]          x          ;

reg   [4:0]           y          ;

reg   [1:0]           m         ;

reg   [1:0]          work_flag    ;

 

    wire                add_cnt0    ;

    wire                end_cnt0    ;

    wire                add_cnt1    ;

    wire                end_cnt1    ;

    wire                add_cnt2    ;

    wire                end_cnt2    ;

    wire                mid_cnt0    ;

    wire                fir_cnt0     ;

 

    always @(posedgeclk or negedgerst_n)begin

        if(!rst_n)begin

            cnt0 <= 0;

        end

        else if(add_cnt0)begin

            if(end_cnt0)

                cnt0 <= 0;

            else

                cnt0 <= cnt0 + 1;

        end

    end

    assign add_cnt0 = work_flag;

    assign end_cnt0 = add_cnt0 &&   cnt0==x-1 ;

 

    always @(posedgeclk or negedgerst_n)begin  

        if(!rst_n)begin

            cnt1 <= 0;

        end

        else if(add_cnt1)begin

            if(end_cnt1)

                cnt1 <= 0;

            else

                cnt1 <= cnt1 + 1;

        end

    end

    assign add_cnt1 = end_cnt0;

    assign end_cnt1 = add_cnt1 &&   cnt1==y-1 ;

 

    always @(posedgeclk or negedgerst_n)begin

        if(!rst_n)begin

            cnt2 <= 0;

        end

        else if(add_cnt2)begin

            if(end_cnt2)

                cnt2 <= 0;

            else

                cnt2 <= cnt2 + 1;

        end

    end

    assign add_cnt2 = end_cnt1;

    assign end_cnt2 = add_cnt2 &&   cnt2==m-1 ;

 

    always    @(posedgeclk or negedgerst_n)begin

        if(rst_n==1'b0)begin

            flag <= 0;

        end

        else if(start &&   mode==EWEN)begin

            flag <= 0;

        end

        else if(start &&   mode==WRITE)begin

            flag <= 1;

        end

        else if(start &&   mode==READ)begin

            flag <= 2;

        end

    end

 

    always    @(posedgeclk or negedgerst_n)begin

        if(rst_n==1'b0)begin

            data <= 0;

        end

        else if(start &&   mode==EWEN)begin

            data <= {3'b100,addr,wdata};

        end

        else if(start &&   mode==WRITE)begin

            data <= {3'b101,addr,wdata};

        end

          else if(start && mode==READ)begin

            data <= {3'b110,addr,wdata};

        end

    end

 

    always    @(posedgeclk or negedgerst_n)begin

        if(rst_n==1'b0)begin

work_flag<=   0;

        end

        else if(start)begin 

work_flag<=   1;

        end

        else if(end_cnt2)begin

work_flag<=   0;

        end

    end

 

    assign mid_cnt0 = add_cnt0 &&   cnt0==50-1 && cnt2==1-1;

    assign fir_cnt0 = add_cnt0 &&   cnt0== 1-1 && cnt2==1-1;

 

    always    @(posedgeclk or negedgerst_n)begin

        if(rst_n==1'b0)begin

sk<= 0;

        end

        else if(mid_cnt0) begin

sk<= 1;

        end

        else if(end_cnt0) begin

sk<= 0;

        end

    end

 

    always    @(posedgeclk or negedgerst_n)begin

        if(rst_n==1'b0)begin

            di <= 1'b0;

        end

        else if(fir_cnt0)begin

            di <= data[17-cnt1];

        end

    end

 

    always    @(posedgeclk or negedgerst_n)begin

        if(rst_n==1'b0)begin

cs<= 1'b0;

        end

        else if(mode==WRITE || (end_cnt1   && cnt2==2-1 && flag==1))begin  

cs<= 1'b1;

        end

        else if(end_cnt1 &&   (cnt2==1-1 || cnt2==3-1))begin

cs<= 1'b0;

        end

    end

 

    always    @(*)begin

        if(mode==WRITE || work_flag) 

rdy = 1'b0;

        else

rdy = 1'b1;

    end

 

    always    @(*)begin

        if(cnt2==1-1 && flag==0)begin

            x = 100;

            y =  10;

        end

        else if(cnt2==1-1 &&   (flag==2-1 || flag==3-1))begin

            x = 100;

            y =  18;

        end

        else if(cnt2==2-1)begin

            x = 100;

            y =   1;

        end

        else begin

            x = 100000;

            y =   1     ;

        end

end

 

always @(*)begin

    if(flag==1)begin

       z = 3;

    else

       z = 2;

end

 

    always    @(posedgeclk or negedgerst_n)begin

        if(rst_n==1'b0)begin

rdata<= 0;

        end

        else if(end_cnt0 && cnt1   >= 11 && flag==2) begin

rdata<=   {rdata[6:0],do};

        end

    end

 

    always    @(posedgeclk or negedgerst_n)begin

        if(rst_n==1'b0)begin

rdata_vld<=   1'b0;

        end

        else if(end_cnt2 && flag==2)   begin

rdata_vld<=   1'b1;

        end

        else begin

rdata_vld<=   1'b0;

        end

    end

endmodule

 

 


*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客