?? serial_segment.v
字號:
module serial_segment(clk,rst_n,cs_n,rd_n,wr_n,addr,rdata,wdata,s_clk,s_dat);
// parameters
parameter PRESCALE = 16'd5; // asynchronous reset level
parameter HOLDCOUNT = 32'd125000;// hold count
input clk; // master clk
input rst_n; // reset
input cs_n; // chip select
input rd_n; // read signal
input wr_n; // write signal
input [2:0]addr;// address
output [7:0]rdata; // out data
input [7:0]wdata; // in data
reg [7:0] rdata;
output s_clk; // serial clock
output s_dat; // serial data
//
// variable declarations
//
// state machine
parameter IDLE = 2'b00;
parameter START = 2'b01;
parameter STOP = 2'b10;
parameter HOLD = 2'b11;
// registers
reg [7:0] data[3:0]; // segment data
// generate write signals
wire wacc = ~cs_n & ~wr_n;
// generate read signals
wire racc = ~cs_n & ~rd_n;
reg [7:0] trans_data;
// generate registers
always @(posedge clk or negedge rst_n)
if (!rst_n)
begin
data[0] <= #1 8'h00;
data[1] <= #1 8'h00;
data[2] <= #1 8'h00;
data[3] <= #1 8'h00;
end
else
if ( wacc )
begin
case (wdata)
8'h0:trans_data = 8'hc0;
8'h1:trans_data = 8'hf6;
8'h2:trans_data = 8'h4a;
8'h3:trans_data = 8'h52;
8'h4:trans_data = 8'h74;
8'h5:trans_data = 8'h51;
8'h6:trans_data = 8'h41;
8'h7:trans_data = 8'hf0;
8'h8:trans_data = 8'h40;
8'h9:trans_data = 8'h50;
8'ha:trans_data = 8'h60;
8'hb:trans_data = 8'h45;
8'hc:trans_data = 8'hc9;
8'hd:trans_data = 8'h46;
8'he:trans_data = 8'h49;
8'hf:trans_data = 8'h69;
default: trans_data = wdata;
endcase
case ( addr ) // synopsis parallel_case
3'b000 : data[0] <= #1 trans_data;
3'b001 : data[1] <= #1 trans_data;
3'b010 : data[2] <= #1 trans_data;
3'b011 : data[3] <= #1 trans_data;
default: ;
endcase
end
always @(posedge clk)
begin
if( racc )
case (addr) // synopsis parallel_case
3'b000: rdata <= #1 data[0];
3'b001: rdata <= #1 data[1];
3'b010: rdata <= #1 data[2];
3'b011: rdata <= #1 data[3];
3'b100: rdata <= #1 8'h4; // reserved
3'b101: rdata <= #1 8'h5; // reserved
3'b110: rdata <= #1 8'h6; // reserved
3'b111: rdata <= #1 8'h7; // reserved
endcase
end
reg [3:0] state; // machine state
reg [15:0]prescale; // prescale
reg [1:0] index; // memory index
wire busy; // busy
reg shift_start; // shift start
reg [3:0] sig_num; //
reg [31:0]hold_count; // hold count
always @(posedge clk)
if(~rst_n)
begin
state <= #1 START;
prescale <= #1 PRESCALE;
hold_count <=#1 HOLDCOUNT;
shift_start <= #1 1'b0;
index <= #1 2'b00;
sig_num <= #1 4'b0111;
end
else
begin
if(~busy)
begin
case(state)
START:
begin
state <= #1 STOP;
shift_start <= #1 1'b1;
index <= #1 index + 2'b01;
case (index)
2'b00: sig_num <= #1 4'b1011;
2'b01: sig_num <= #1 4'b1101;
2'b10: sig_num <= #1 4'b1110;
2'b11: sig_num <= #1 4'b0111;
endcase
end
STOP:
begin
state <= #1 HOLD;
hold_count <= #1 HOLDCOUNT;
shift_start <= #1 1'b0;
end
HOLD:
begin
if(~(|hold_count))
begin
state <= #1 START;
hold_count <= #1 HOLDCOUNT;
end
else
hold_count <= #1 hold_count - 32'h1;
end
endcase
end
end
wire [15:0]shift_data ={ 4'b1111,sig_num[3:0],data[index]};
shift_bit the_shift_bit(clk,rst_n,prescale,shift_data,shift_start,busy,s_clk,s_dat);
endmodule
// 移位發(fā)送模塊
// shift_start上升沿觸發(fā)一次16bit的數(shù)據(jù)發(fā)送
// busy 模塊忙信號輸出
module shift_bit(clk,rst_n,prescale,data,start,busy,s_clk,s_dat);
input clk; // master clk
input rst_n; // reset
input [15:0]prescale;// prescale
input [15:0]data; // shift data
input start; // rising edge
output busy; // busy status
output s_clk; // serial clock
output s_dat; // serial data
reg busy;
reg s_clk;
reg s_dat;
parameter IDLE = 5'b00001,
PREPARE_DATA = 5'b00010,
RISE_CLK = 5'b00100,
FALL_CLK = 5'b01000,
END = 5'b10000;
reg [4:0]state; // state machine
reg [3:0]send_count;// send count
reg [15:0]wait_count;//wait count
reg [15:0]shift_data; // shift data
reg s_start,d_start;// asynchronous start,delay start
always @(posedge clk)
if(~rst_n)
begin
s_start <= #1 1'b0;
d_start <= #1 1'b0;
end
else
begin
d_start <= #1 s_start;
s_start <= #1 start;
end
wire shift_start = ~d_start & s_start;
wire switch = |wait_count; //wait_count ==0 ?
always @(posedge clk)
if(!rst_n)
begin
state <=#1 IDLE;
s_clk <=#1 1'b0;
s_dat <=#1 1'b0;
send_count <= #1 4'b0000;
busy <=#1 1'b0;
wait_count <= #1 prescale;
end
else
begin
if(shift_start)
busy <= #1 1'b1;
if(~switch)
begin
wait_count <= #1 prescale;
case (state)
IDLE:
begin
if(busy) begin
state <= #1 PREPARE_DATA;
shift_data <= #1 data;
send_count <= #1 4'b0000;
end
else
state <= #1 IDLE;
end
PREPARE_DATA:
begin
s_dat <= #1 shift_data[0];
state <= #1 RISE_CLK;
shift_data <= #1 {1'b0,shift_data[15:1]};
end
RISE_CLK:
begin
s_clk <= #1 1'b1;
state <= #1 FALL_CLK;
end
FALL_CLK:
begin
s_clk <= #1 1'b0;
state <= #1 END;
end
END:
begin
send_count <= send_count + 4'b0001;
if ( send_count == 4'b1111)
begin
state <= #1 IDLE;
busy <= #1 1'b0;
end
else
state <= #1 PREPARE_DATA;
end
endcase
end
else
wait_count <= wait_count - 16'h0001;
end
endmodule
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -