//希望高手可以指导下 特别是下面的数据和地址采集的方式对不对 同时希望给一些建议
module Selector_Driver_verilog(
CLK, //外部的时钟 频率为63KHz
AD_BUS, //外部的地址数据总线 CLK上升沿发送地址 CLK下降沿发送数据(分时复用) 上升沿50ns 下降沿50ns
CS_AD, //拨码开关的地址 用来与CLK的上升沿发来的地址作比较
CTL_A, //CLK下降沿数据接收
);
wire clk_in;//调用出来的内部时钟 用来对外部的地址数据进行多次采集频率可调 我现在用为28MHz 觉得足以
input wire CLK;
input wire [7:0]AD_BUS;
input wire [7:0]CS_AD;
output reg [8:1]CTL_A;
//状态参数
/***********************************************************/
parameter state1 = 5'd1;//地址状态量
parameter state2 = 5'd2;
parameter state3 = 5'd3;
parameter state4 = 5'd4;
parameter state5 = 5'd5;
parameter state6 = 5'd6;
parameter state7 = 5'd7;
parameter state8 = 5'd8;
parameter state10 = 5'd10;//数据状态量
parameter state11 = 5'd11;
parameter state12 = 5'd12;
parameter state13 = 5'd13;
parameter state14 = 5'd14;
parameter state15 = 5'd15;
parameter state16 = 5'd16;
parameter state17 = 5'd17;
parameter state18 = 5'd18;
parameter state19 = 5'd19;
/***********************************************************/
wire [7:1]CS_AD0_BUFFER;//地址
assign CS_AD0_BUFFER = CS_AD;
//采集外部时钟边沿
/***********************************************************/
wire CLK_NEG;//上升沿
wire CLK_POS;//下降沿
reg CLK_0;
reg CLK_1;
reg CLK_2;
reg CLK_3;
reg CLK_4;
always @(posedge clk_in)
begin
CLK_0 <= CLK;
CLK_1 <= CLK_0;
CLK_2 <= CLK_1;
CLK_3 <= CLK_2;
CLK_4 <= CLK_3;
end
assign CLK_POS = CLK_0 &(~CLK_4);
assign CLK_NEG = CLK_4 &(~CLK_0);
//采集地址进程
/***********************************************************/
reg [7:0]A0;//地址采集寄存器
reg [7:0]A1;
reg [7:0]A2;
reg [7:0]A3;
reg [7:0]A4;
reg [7:0]A5;
reg [7:0]A6;
reg [4:0]A_STATE;//地址状态量
reg [7:0]Addr_BUFFER; //保存采样正确的地址值
always @(posedge clk_in)
begin
if(CLK_POS) //CLK上升沿
begin
case(A_STATE)
state1: begin
A0 <= AD_BUS;
A_STATE <= state2;
end
state2: begin
A1 <= AD_BUS;//这样采集地址和下面采集数据的方法对吗?????
A_STATE <= state3;
end
state3: begin
A2 <= AD_BUS;
A_STATE <= state4;
end
state4: begin
A3 <= AD_BUS;
A_STATE <= state5;
end
state5: begin
A4 <= AD_BUS;
A_STATE <= state6;
end
state6: begin
A5 <= AD_BUS;
A_STATE <= state7;
end
state7: begin
A6 <= AD_BUS;
A_STATE <= state8;
end
state8: if((A0 == AD_BUS) && (A1 == AD_BUS) && (A3 == AD_BUS) && (A4 == AD_BUS) && (A5 == AD_BUS) && (A6 == AD_BUS))//判断是否相等
Addr_BUFFER <= AD_BUS ;//得到正确的地址值
else A_STATE <= state1;
default: A_STATE <= state1;
endcase
end
end
//采集数据进程
/***********************************************************/
reg [7:0]D0;//数据采集寄存器
reg [7:0]D1;
reg [7:0]D2;
reg [7:0]D3;
reg [7:0]D4;
reg [7:0]D5;
reg [7:0]D6;
reg [7:0]Data_BUFFER;//采集到的正确数据寄存器
reg [4:0]D_STATE;//数据状态量
always @(posedge clk_in)
begin
if(CLK_NEG) //CLK下降沿
begin
case(D_STATE)
state10: begin
D0 <= AD_BUS;
D_STATE <= state11;
end
state11: begin
D1 <= AD_BUS;
D_STATE <= state12;
end
state12: begin
D2 <= AD_BUS;
D_STATE <= state13;
end
state13: begin
D3 <= AD_BUS;
D_STATE <= state14;
end
state14: begin
D4 <= AD_BUS;
D_STATE <= state15;
end
state15: begin
D_STATE <= (D2 == D3) ? state16 : state14;
D5 <= AD_BUS;
end
state16: begin
D6 <= AD_BUS;
D_STATE <= state17;
end
state11: if((D0 == AD_BUS)) && (D1 == AD_BUS) && (D2 == AD_BUS) && (D3 == AD_BUS) && (D4 == AD_BUS) && (D5 == AD_BUS) && (D6 == AD_BUS))
Data_BUFFER <= AD_BUS ;//得到正确的数据
else D_STATE <= state10;
default: D_STATE <= state10;
endcase
end
end
//最终采集到的正确地址和拨码开关的地址作比较 符合要求并在下降沿将正确的数据输出
/***********************************************************/
always @(posedge clk_in)
begin
if((CLK_NEG) && (Addr_BUFFER == CS_AD0_BUFFER))
CTL_A <= Data_BUFFER;
end
//调用内部晶振 时钟clk_in经PLL输出 //已调用出 已验证 无需理会
/***********************************************************/
wire osc;
myOscillator myOscillator (
.clkout(osc)
);
myPll Pll (
.clkin(osc), // Reference clock input.
.clkcpu(),
.clkout0(clk_in), // Main clock output.
.clkout1(), // clock output 1.
.clkout2() // clock output 2.
);
endmodule
文章评论(0条评论)
登录后参与讨论