📄 spi_tx_rx.v
字号:
module spi_tx_rx(
nreset, //asynchronous system reset
clk, //clock (only use rising edge)
nrestart_bitcnt, //synchronous reset for bit counter
field, //indicate what is to be send/received op/addr/data
opcode_length, //number of valid bit in opcode field
opcode_field, //opcode to send
address_length, //number of valid bit in address field
addr_field, //address to be sent
data_field, //data to be sent.
lcd_a, //parralel value for spi_a pin
shift, //makes shift register shift
load, //makes the shift register load parralell value
spi_si, //serial input
spi_so, //serial output
end_transmit, //active high when number_of_bit have been tx/rx
data_received, //serialy received data
nrestart_bytecnt, //restart byte counter
number_of_byte, //number of data byte to send/receive
end_data_txrx, //active high when number_of_byte have been tx/rx
spi_a, //indicate to lcd if data is control/raw data
n_opcode_addr_busy //
);
input nreset;
input clk;
input nrestart_bitcnt;
input [1:0] field;
input [5:0] opcode_length;
input [31:0] opcode_field;
input [5:0] address_length;
input [31:0] addr_field;
input [7:0] data_field;
input [1:0] lcd_a;
input shift;
input load;
input spi_si;
output spi_so ;
output end_transmit;
output [7:0] data_received; // data received is only 8 bit wide because
//the only place where receicved data are
//going is fifo and the fifo is 8 bit wide
input nrestart_bytecnt;
input [7:0] number_of_byte;
output end_data_txrx;
output spi_a;
output n_opcode_addr_busy;
//-----------------------------------------------------------------------------
// Parameters and constants
//-----------------------------------------------------------------------------
// All flip-flops are modeled (in RTL) with a (cp->q) delay: tcQ.
// This is to prevent potential problems with gated clocks.
parameter tcQ=1;
// wires definition
reg [5:0] number_of_bit; //number of bit to transmit
reg [31:0] data_to_send; //data to be sent serialy
wire spi_so; //serial output
wire end_transmit; //active high, activate when number_of_bit have been sent
wire [7:0] data_received; //received data from the SPI device
wire end_data_txrx;
wire byte_count;
reg n_opcode_addr_busy;
reg spi_a,spi_a_c;
reg end_transmit_r;
// shift register instanciation
reg [31:0] shift_reg;
spi_bitcounter bitcnt (.clk(clk), // Clock Input
.cdn(nreset), // Clear Direct Not Input
.csn(nrestart_bitcnt),
.cen(shift), // Count Enable Input
.maxval(number_of_bit), // Programmable Maximum Count Value
.q(), // 3 bit Result
.tci(end_transmit)); // Terminal Count Indicator
spi_bytecounter bytecnt (.clk(clk), // Clock Input
.cdn(nreset), // Clear Direct Not Input
.csn(nrestart_bytecnt),
.cen(byte_count), // Count Enable Input
.maxval({number_of_byte}), // Programmable Maximum Count Value
.q(), // 3 bit Result
.tci(end_data_txrx)); // Terminal Count Indicator
always @(posedge clk or negedge nreset)
if(!nreset)
end_transmit_r<=0;
else
end_transmit_r<=end_transmit;
assign data_received=shift_reg[7:0];
assign byte_count=end_transmit&(~end_transmit_r);
// shift register to shift out/in the dat to/from the SPI device
// the length of the shift register is 24 bits. This is due to the
// size of the address field. It is possible to reduce it to
// 8 bit however this will introduce extra complexity in the
// control part for a limited gain in term of gate
// this shift register shifts MSB first;
assign spi_so=shift_reg[31];
always @(posedge clk)
begin
if(load)
shift_reg <= #tcQ data_to_send;
else
if (shift)
begin
shift_reg[31:1] <= #tcQ shift_reg[30:0]; //shift out msb first
shift_reg[0] <= #tcQ spi_si;
end
else
shift_reg <= #tcQ shift_reg; //shift out msb first
end // always @ (negedge nreset or negedge clk)
//select the appropriate data to be sent to the shift register
//and the number of bit that are to be sent
//according to the control state machine field instruction
//This introduce only combinational logic
always @(field or opcode_field or addr_field or data_field
or opcode_length or address_length or lcd_a)
begin
case(field)
2'b01 :
begin
data_to_send = opcode_field;
number_of_bit = opcode_length;
spi_a_c=lcd_a[0];
n_opcode_addr_busy=0;
end
2'b10 :
begin
data_to_send = addr_field;
number_of_bit = address_length;
spi_a_c=lcd_a[0];
n_opcode_addr_busy=0;
end
2'b11 :
begin
data_to_send[31:24] = data_field;
data_to_send[23:0] = 24'hxx_xx_xx;
number_of_bit={2'b00,3'b111};
spi_a_c=lcd_a[1];
n_opcode_addr_busy=1;
end
default :
begin
data_to_send = 32'hxx_xx_xx_xx;
number_of_bit=5'b11111;
spi_a_c=lcd_a[1];
n_opcode_addr_busy=0;
end
endcase
end // always @ (field or opcode_field or addr_field)
always @(posedge clk)
spi_a<=spi_a_c;
endmodule // spi_rx_tx
/*
spi_rx_tx{
.nreset(), //asynchronous system reset
.clk(), //clock (only use rising edge)
.nrestart_bitcnt(), //synchronous reset for bit counter
.field_selector(), //indicate what is to be send/received op/addr/data
.opcode_length(), //number of valid bit in opcode field
.opcode(), //opcode to send
.address_length(), //number of valid bit in address field
.addr_field(), //address to be sent
.data_field(), //data to be sent.
.lcd_a(), //parralel value for spi_a pin
.shift(), //makes shift register shift
.load(), //makes the shift register load parralell value
.spi_si(), //serial input
.spi_so(), //serial output
.end_transmit(), //active high when number_of bit have been sent
.data_received(), //serialy received data
.nrestart_bytecnt(), //restart byte counter
.number_of_byte(), //number of data byte to send/receive
.end_data_txrx(), //active high when number_of_byte have been tx/rx
.spi_a(), //indicate to lcd if data is control/raw data
.n_opcode_addr_busy() //
);
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -