转载 一个SRAM控制器verilog格式
最近写的一个SRAM控制器verilog格式 不对的地方高人多指点
控制外部SRAM需要注意什么?
在代码风格上如何描述更稳定可靠呢?
module SRAM_TEST(
i_Reset_n,
i_Clock,
i_EN,
i_StepByStep,
i_WR_Control,
o_W_FullSign,
/* SRAM Interface */
o_Sram_add,
io_Sram_data,
o_Sram_CE_n,
o_Sram_WE_n,
o_Sram_OE_n,
o_Sram_UB_n,
o_Sram_LB_n,
/* Display */
o_HEX,
t_HEX);
input i_Reset_n;
input i_Clock;
input i_EN;
input i_StepByStep;
input i_WR_Control;
output o_W_FullSign;
/*SRAM Interface*/
output [17:0] o_Sram_add;
inout [15:0] io_Sram_data;
output o_Sram_CE_n;
output o_Sram_WE_n;
output o_Sram_OE_n;
output o_Sram_UB_n;
output o_Sram_LB_n;
/* Display */
output [6:0] o_HEX;
output [6:0] t_HEX;
reg [6:0] o_HEX;
reg [6:0] t_HEX;
reg [17:0] o_Sram_add;
reg [3:0] t_counter;
reg o_Sram_CE_n;
reg o_Sram_WE_n;
reg o_Sram_OE_n;
reg o_Sram_UB_n;
reg o_Sram_LB_n;
reg [15:0] Sram_data_in;
reg [15:0] Sram_data_out;
reg Counter_EN;
reg [17:0] WADD_Counter;
reg [17:0] RADD_Counter;
reg [15:0] W_data;
reg o_W_FullSign;
reg [2:0] Sram_State;
reg i_StepByStep1;
reg i_StepByStep2;
reg i_StepByStep3;
reg i_StepByStep4;
reg i_WR_Control1;
reg i_WR_Control2;
reg i_WR_Control3;
always @(posedge i_Clock or negedge i_Reset_n)
if(~i_Reset_n)
Counter_EN<=0;
else begin
if(i_EN)
Counter_EN<=0;
else
Counter_EN<=~Counter_EN;
end
always @(posedge i_Clock or negedge i_Reset_n)begin
if(~i_Reset_n)begin
i_StepByStep1<=1;
i_StepByStep2<=1;
i_StepByStep3<=1;
i_StepByStep4<=0;
i_WR_Control1<=1;
i_WR_Control2<=1;
i_WR_Control3<=1;
end
else begin
i_StepByStep1<=i_StepByStep;
i_StepByStep2<=i_StepByStep1;
i_StepByStep3<=i_StepByStep2;
i_StepByStep4<=(i_StepByStep2 ^ i_StepByStep3) & i_StepByStep3;
i_WR_Control1<=i_WR_Control;
i_WR_Control2<=i_WR_Control1;
i_WR_Control3<=i_WR_Control2;
end
end
always @(posedge i_Clock or negedge i_Reset_n)
if(~i_Reset_n)begin
WADD_Counter<=0;
o_W_FullSign<=1;
end
else begin
if(i_WR_Control3 &i_StepByStep4==1)
if(WADD_Counter==15)begin
WADD_Counter<=WADD_Counter;
o_W_FullSign<=0;
end
else begin
WADD_Counter<=WADD_Counter+1;
o_W_FullSign<=o_W_FullSign;
end
else begin
WADD_Counter<=WADD_Counter;
o_W_FullSign<=o_W_FullSign;
end
end
always @(posedge i_Clock or negedge i_Reset_n)
if(~i_Reset_n)begin
W_data<=0;
end
else begin
if(i_WR_Control3 &i_StepByStep4==1)
if(W_data==15)
W_data<=W_data;
else
W_data<=W_data+1;
else
W_data<=W_data;
end
always @(posedge i_Clock or negedge i_Reset_n)
if(~i_Reset_n)
RADD_Counter<=15;
else begin
if(i_StepByStep4==1 & ~i_WR_Control3)
if(RADD_Counter==0)
RADD_Counter<=15;
else
RADD_Counter<=RADD_Counter-1;
else
RADD_Counter<=RADD_Counter;
end
parameter IDLE =3'b000;
parameter READ =3'b001;
parameter WRITE =3'b010;
always @(posedge i_Clock or negedge i_Reset_n)
if(~i_Reset_n)begin
Sram_State<=IDLE;
o_Sram_add<={16{1'b0}};
Sram_data_in<={16{1'b0}};
Sram_data_out<={16{1'b0}};
o_Sram_CE_n<=1;
o_Sram_WE_n<=1;
o_Sram_OE_n<=1;
o_Sram_UB_n<=1;
o_Sram_LB_n<=1;
end
else begin
case(Sram_State)
IDLE:begin
if(~i_EN)begin
if(i_WR_Control3)begin
Sram_State<=WRITE;
o_Sram_add<=WADD_Counter;
Sram_data_in<={16{1'bz}};
Sram_data_out<=Sram_data_out;
o_Sram_CE_n<=0;
o_Sram_WE_n<=0;
o_Sram_OE_n<=1;
o_Sram_UB_n<=0;
o_Sram_LB_n<=0;
end
else begin
Sram_State<=READ;
o_Sram_add<=RADD_Counter;
Sram_data_in<=Sram_data_in;
Sram_data_out<={16{1'bz}};
o_Sram_CE_n<=0;
o_Sram_WE_n<=1;
o_Sram_OE_n<=0;
o_Sram_UB_n<=0;
o_Sram_LB_n<=0;
end
end
else begin
Sram_State<=IDLE;
o_Sram_add<=0;
Sram_data_in<={16{1'b0}};
Sram_data_out<={16{1'b0}};
o_Sram_CE_n<=1;
o_Sram_WE_n<=1;
o_Sram_OE_n<=1;
o_Sram_UB_n<=1;
o_Sram_LB_n<=1;
end
end
READ:begin
Sram_State<=IDLE;
o_Sram_add<=RADD_Counter;
Sram_data_in<=io_Sram_data;
Sram_data_out<={16{1'bz}};
o_Sram_CE_n<=0;
o_Sram_WE_n<=1;
o_Sram_OE_n<=0;
o_Sram_UB_n<=0;
o_Sram_LB_n<=0;
end
WRITE:begin
Sram_State<=IDLE;
o_Sram_add<=WADD_Counter;
Sram_data_in<={16{1'bz}};
Sram_data_out<=W_data;
o_Sram_CE_n<=0;
o_Sram_WE_n<=0;
o_Sram_OE_n<=1;
o_Sram_UB_n<=0;
o_Sram_LB_n<=0;
end
default:begin
Sram_State<=IDLE;
o_Sram_add<=0;
Sram_data_in<={16{1'bz}};
Sram_data_out<={16{1'bz}};
o_Sram_CE_n<=1;
o_Sram_WE_n<=1;
o_Sram_OE_n<=1;
o_Sram_UB_n<=1;
o_Sram_LB_n<=1;
end
endcase
end
assign io_Sram_data=(i_WR_Control3)? Sram_data_out:{16{1'bz}};
always @(posedge i_Clock or negedge i_Reset_n)
if(~i_Reset_n)
o_HEX<=7'b1000000;
else begin
if(i_WR_Control3)
case(Sram_data_out[3:0])
4'b0000_HEX<=7'b1000000;
4'b0001_HEX<=7'b1111001;
4'b0010_HEX<=7'b0100100;
4'b0011:o_HEX<=7'b0110000;
4'b0100:o_HEX<=7'b0011001;
4'b0101:o_HEX<=7'b0010010;
4'b0110:o_HEX<=7'b0000010;
4'b0111:o_HEX<=7'b1111000;
4'b1000:o_HEX<=7'b0000000;
4'b1001:o_HEX<=7'b0010000;
4'b1010:o_HEX<=7'b0001000;
4'b1011:o_HEX<=7'b0000011;
4'b1100:o_HEX<=7'b1000110;
4'b1101:o_HEX<=7'b0100001;
4'b1110:o_HEX<=7'b0000110;
4'b1111:o_HEX<=7'b0001110;
default:o_HEX<=7'b1000000;
endcase
else
o_HEX<=7'b1000000;
end
always @(posedge i_Clock or negedge i_Reset_n)
if(~i_Reset_n)
t_HEX<=7'b1000000;
else begin
case(Sram_data_in[3:0])
4'b0000:t_HEX<=7'b1000000;
4'b0001:t_HEX<=7'b1111001;
4'b0010:t_HEX<=7'b0100100;
4'b0011:t_HEX<=7'b0110000;
4'b0100:t_HEX<=7'b0011001;
4'b0101:t_HEX<=7'b0010010;
4'b0110:t_HEX<=7'b0000010;
4'b0111:t_HEX<=7'b1111000;
4'b1000:t_HEX<=7'b0000000;
4'b1001:t_HEX<=7'b0010000;
4'b1010:t_HEX<=7'b0001000;
4'b1011:t_HEX<=7'b0000011;
4'b1100:t_HEX<=7'b1000110;
4'b1101:t_HEX<=7'b0100001;
4'b1110:t_HEX<=7'b0000110;
4'b1111:t_HEX<=7'b0001110;
default:t_HEX<=7'b1000000;
endcase
end
endmodule
Library IEEE;
Use IEEE.Std_logic_1164.all;
USe IEEE.Std_logic_unsigned.all;
ENTITY sram IS
GENERIC
(
k: integer:=8; --8位数据宽度
w: integer:=4 --4位宽度地址,共16个地址
);
PORT
(
rd,wr,cs: IN STD_LOGIC; --定义写,读,片选控制信号
adr: IN STD_LOGIC_VECTOR(w-1 DOWNTO 0); --4位地址信号
din: IN STD_LOGIC_VECTOR(k-1 DOWNTO 0); --8位输入信号
dout: OUT STD_LOGIC_VECTOR(k-1 DOWNTO 0) --8位输出信号
);
END sram ;
ARCHITECTURE behave OF sram IS
subtype word is STD_LOGIC_VECTOR(k-1 DOWNTO 0);
type memory is array(0 to 2**w-1) of word;
signal sram:memory; --定义中间缓存空间
signal adr_in:Integer; --定义地址指向标志
BEGIN
adr_in<=conv_integer(adr); --将输入地址转换为地址指向标志
Write: process(wr,cs,adr_in,din,rd) --数据写入进程:Write
begin
if wr='0' then
if cs='0' and rd='1' then
sram(adr_in)<=din;
end if;
end if;
end process;
Read: process(rd,cs,adr_in,wr) --数据读入进程:Read
begin
if(rd='0' and cs='0' and wr='1') then
dout<=sram(adr_in);
else dout<=(others=>'Z');
end if;
end process;
end behave;