当前位置:网站首页>SD_ DATA_ SEND_ SHIFT_ REGISTER
SD_ DATA_ SEND_ SHIFT_ REGISTER
2022-07-07 18:57:00 【Eight four one one】
Catalog
1. Interface
- Clock reset soft reset
- sd Data from card data line in_sd_data
- Data transmission width in_data_width
- from fifo The data read out in sd_fifo_rdata、 Can make sd_fifo_re
- state in_current_state、in_next_state
- Sent crc, need in_send_crc_counter、out_crc_status_wrong
- Data signals sent in_has_send_bit、in_interval_counter、out_serial_data
- Output data out_data_half_delay、out_data_dir
- High speed clock mode in_high_speed_clk
input in_sd_clk; //clock for sd card
input hrst_n; //ahb signal
input in_soft_reset; //software reset
input [3:0] in_sd_data; //data input drom sd card
input [31:0] sd_fifo_rdata; //parallel data from tx fifo
input [3:0] in_current_state; //current state of data fsm
input [3:0] in_next_state; //next state of data fsm
input in_data_width; //data width 1:4bit 0:1bit
input [3:0] in_send_crc_counter; //has sent crc bits
input [13:0] in_has_send_bit; //has sent data bits
input [1:0] in_interval_counter; //time interval Count opposite crc
input in_high_speed_clk;
output [3:0] out_serial_data; //original serial output data
output sd_fifo_re; //tx fifo read enable
output out_crc_status_wrong; //crc status wrong flag
output [3:0] out_data_dir; //data direction 1:send
output [3:0] out_data_half_delay; //serial output data to sd card
2. Internal signals
reg [3:0] out_serial_data;
reg [31:0] shift_reg0;
reg [15:0] crc_reg0;
reg [15:0] crc_reg1;
reg [15:0] crc_reg2;
reg [15:0] crc_reg3;
reg [15:0] crc_shift_reg0;
reg [15:0] crc_shift_reg1;
reg [15:0] crc_shift_reg2;
reg [15:0] crc_shift_reg3;
reg [0:31] data_for_send;
reg [3:0] crc_status_reg;
reg sd_fifo_re;
reg out_crc_status_wrong;
reg [3:0] out_data_half_delay_tp;
reg [3:0] data_dir_nes;
wire [31:0] sd_fifo_rdata_tp;
wire [3:0] data_dir_pos;
3. High speed clock mode
- from in_high_speed_clk The input of out Which data to use
assign out_data_half_delay = in_high_speed_clk ? out_serial_data : out_data_half_delay_tp;
assign out_data_dir = in_high_speed_clk ? data_dir_pos :data_dir_nes;
//-------------------------------------------------------
always @(negedge in_sd_clk or negedge hrst_n) begin
if (!hrst_n) begin
out_data_half_delay_tp <= 4'b1111;
end
else begin
out_data_half_delay_tp <= out_serial_data;
// use clk Beat on the falling edge , Delay half a cycle
end
end
//-------------------------------------------------
always @(negedge in_sd_clk or negedge hrst_n) begin
if (!hrst_n) begin
data_dir_nes <= 4'b0
end
else begin
data_dir_nes <= {
data_dir_pos[3],data_dir_pos[2],data_dir_pos[1],data_dir_pos[0]};
end
end
assign data_dir_pos[0] = ( (in_current_state == `DATA_STATE_SEND_P) ||
(in_current_state == `DATA_STATE_SEND_START_BIT) ||
(in_current_state == `DATA_STATE_SEND) ||
(in_current_state == `DATA_STATE_SEND_CRC) ||
((in_current_state == `DATA_STATE_SEND_END_BIT) &&
((in_interval_counter == 0) || (in_interval_counter == 1)))
);
assign data_dir_pos[1] = in_data_width && data_dir_pos[0];
assign data_dir_pos[2] = data_dir_pos[1];
assign data_dir_pos[3] = data_dir_pos[1];
4. Shift performs parallel to serial conversion of data
- The data to be shifted is out_serial_data、crc_status_reg、crc_shift_reg
- In each different state , Shift different data
always @(posedge in_sd_clk or negedge hrst_n) begin
if (!hrst_n) begin
shift_reg0 <= 32'b0;
out_serial_data <= 4'b1111;
crc_status_reg <= 4'b0;
crc_shift_reg0 <= 16'b0;
crc_shift_reg1 <= 16'b0;
crc_shift_reg2 <= 16'b0;
crc_shift_reg3 <= 16'b0;
end
else if (!in_soft_reset)
begin
shift_reg0 <= 32'b0;
out_serial_data <= 4'b1111;
crc_status_reg <= 4'b0;
crc_shift_reg0 <= 16'b0;
crc_shift_reg1 <= 16'b0;
crc_shift_reg2 <= 16'b0;
crc_shift_reg3 <= 16'b0;
end
else
begin
if(!in_data_width)
begin
if (in_current_state == `DATA_STATE_SEND_START_BIT)
//send start bit
out_serial_data[0] <= 1'b0;
else if (in_current_state == `DATA_STATE_SEND)
begin
// Every time 32 individual bit, Assign a new value ( from fifo Read out )
if (in_has_send_bit[4:0] == 5'b0)
{
out_serial_data[0],shift_reg0} <= {
sd_fifo_rdata_tp,1'b0};
else
{
out_serial_data[0],shift_reg0} <= {
shift_reg0,1'b0};
// Shift output left , Parallel to serial
end
else if (in_current_state == `DATA_STATE_SEND_CRC)
begin
if (in_send_crc_counter == 0)
{
out_serial_data[0],crc_shift_reg0} <= {
crc_reg0,1'b0};
else
{
out_serial_data[0],crc_shift_reg0} <= {
crc_shift_reg0,1'b0};
end
else if (in_current_state == `DATA_STATE_SEND_END_BIT)
begin
out_serial_data[0] <= 1'b1;
end
//DATA_STATE_RECEIVE_CRC_STATUS here sd The direction of the data line changes , Change to receive crc_status
else if (in_current_state == `DATA_STATE_RECEIVE_CRC_STATUS)
begin
crc_status_reg <= {
crc_status_reg[2:0], in_sd_data[0]};
end
else if (in_current_state == `DATA_STATE_WAIT_SEND)
begin
crc_status_reg <= 4'b0;
end
end
else
begin
if (in_current_state == `DATA_STATE_SEND_START_BIT)
out_serial_data <= 4'b0;
else if (in_current_state == `DATA_STATE_SEND)
begin
if (in_has_send_bit[2:0] == 3'b0)
{
out_serial_data,shift_reg0} <= {
sd_fifo_rdata_tp,4'b0};
else
{
out_serial_data,shift_reg0} <= {
shift_reg0,4'b0};
end
else if (in_current_state == `DATA_STATE_SEND_CRC)
begin
if(in_send_crc_counter == 0)
begin
{
out_serial_data[3],crc_shift_reg3} <= {
crc_reg3,1'b0};
{
out_serial_data[2],crc_shift_reg2} <= {
crc_reg2,1'b0};
{
out_serial_data[1],crc_shift_reg1} <= {
crc_reg1,1'b0};
{
out_serial_data[0],crc_shift_reg0} <= {
crc_reg0,1'b0};
end
else
begin
{
out_serial_data[3],crc_shift_reg3} <= {
crc_shift_reg3,1'b0};
{
out_serial_data[2],crc_shift_reg2} <= {
crc_shift_reg2,1'b0};
{
out_serial_data[1],crc_shift_reg1} <= {
crc_shift_reg1,1'b0};
{
out_serial_data[0],crc_shift_reg0} <= {
crc_shift_reg0,1'b0};
end
end
else if (in_current_state == `DATA_STATE_RECEIVE_CRC_STATUS)
begin
crc_status_reg <= {
crc_status_reg[2:0],in_sd_data[0]};
end
else if (in_current_state ==`DATA_STATE_WAIT_SEND)
crc_status_reg <= 4'b0
end
end
end
5.data_for_send The birth of , The latter is used to calculate crc
- The same for from fifo Read the data for high-order low-order transformation , Write it down as sd_fifo_rdata_tp
- When the state of DATA_STATE_SEND when , take sd_fifo_rdata_tp Give to the data_for_send
assign sd_fifo_rdata_tp ={
sd_fifo_rdata[7:0],sd_fifo_rdata[15:8],sd_fifo_rdata[23:16],sd_fifo_rdata[31:24]};
always @(*) begin
data_for_send = 32'b0;
if (in_current_state == `DATA_STATE_SEND)
data_for_send = sd_fifo_rdata_tp;
end
6. Calculation crc16
- When sending status , Send it over and over again while calculating
always @(posedge in_sd_clk or negedge hrst_n) begin
if (!hrst_n) begin
crc_reg3 <= 16'b0;
crc_reg2 <= 16'b0;
crc_reg1 <= 16'b0;
crc_reg0 <= 16'b0;
end
else if (!in_soft_reset) begin
crc_reg3 <= 16'b0;
crc_reg2 <= 16'b0;
crc_reg1 <= 16'b0;
crc_reg0 <= 16'b0;
end
else if (in_current_state == `DATA_STATE_WAIT_SEND)
begin
crc_reg3 <= 16'b0;
crc_reg2 <= 16'b0;
crc_reg1 <= 16'b0;
crc_reg0 <= 16'b0;
end
else if (in_current_state == `DATA_STATE_SEND)
begin
if (!in_data_width)
begin
crc_reg0[0] <= data_for_send[in_has_send_bit[4:0]] ^ crc_reg0[15];
crc_reg0[1] <= crc_reg0[0];
crc_reg0[2] <= crc_reg0[1];
crc_reg0[3] <= crc_reg0[2];
crc_reg0[4] <= crc_reg0[3];
crc_reg0[5] <= crc_reg0[4] ^ data_for_send[in_has_send_bit[4:0]] ^ crc_reg0[15];
crc_reg0[6] <= crc_reg0[5];
crc_reg0[7] <= crc_reg0[6];
crc_reg0[8] <= crc_reg0[7];
crc_reg0[9] <= crc_reg0[8];
crc_reg0[10] <= crc_reg0[9];
crc_reg0[11] <= crc_reg0[10];
crc_reg0[12] <= crc_reg0[11] ^ data_for_send[in_has_send_bit[4:0] ^ crc_reg0[15]];
crc_reg0[13] <= crc_reg0[12];
crc_reg0[14] <= crc_reg0[13];
crc_reg0[15] <= crc_reg0[14];
end
else
begin
crc_reg3[0] <= data_for_send[{
in_has_send_bit[2:0],2'b0}] ^ crc_reg3[15];
crc_reg3[1] <= crc_reg3[0];
crc_reg3[2] <= crc_reg3[1];
crc_reg3[3] <= crc_reg3[2];
crc_reg3[4] <= crc_reg3[3];
crc_reg3[5] <= crc_reg3[4] ^ data_for_send[{
in_has_send_bit[2:0],2'b0}] ^ crc_reg3[15];
crc_reg3[6] <= crc_reg3[5];
crc_reg3[7] <= crc_reg3[6];
crc_reg3[8] <= crc_reg3[7];
crc_reg3[9] <= crc_reg3[8];
crc_reg3[10] <= crc_reg3[9];
crc_reg3[11] <= crc_reg3[10];
crc_reg3[12] <= crc_reg3[11] ^ data_for_send[{
in_has_send_bit[2:0],2'b0}] ^ crc_reg3[15];
crc_reg3[13] <= crc_reg3[12];
crc_reg3[14] <= crc_reg3[13];
crc_reg3[15] <= crc_reg3[14];
crc_reg2[0] <= data_for_send[{
in_has_send_bit[2:0],2'b0}+1] ^ crc_reg2[15];
crc_reg2[1] <= crc_reg2[0];
crc_reg2[2] <= crc_reg2[1];
crc_reg2[3] <= crc_reg2[2];
crc_reg2[4] <= crc_reg2[3];
crc_reg2[5] <= crc_reg2[4] ^ data_for_send[{
in_has_send_bit[2:0],2'b0}+1] ^ crc_reg2[15];
crc_reg2[6] <= crc_reg2[5];
crc_reg2[7] <= crc_reg2[6];
crc_reg2[8] <= crc_reg2[7];
crc_reg2[9] <= crc_reg2[8];
crc_reg2[10] <= crc_reg2[9];
crc_reg2[11] <= crc_reg2[10];
crc_reg2[12] <= crc_reg2[11] ^ data_for_send[{
in_has_send_bit[2:0],2'b0}+1] ^ crc_reg2[15];
crc_reg2[13] <= crc_reg2[12];
crc_reg2[14] <= crc_reg2[13];
crc_reg2[15] <= crc_reg2[14];
crc_reg1[0] <= data_for_send[{
in_has_send_bit[2:0],2'b0}+2] ^ crc_reg1[15];
crc_reg1[1] <= crc_reg1[0];
crc_reg1[2] <= crc_reg1[1];
crc_reg1[3] <= crc_reg1[2];
crc_reg1[4] <= crc_reg1[3];
crc_reg1[5] <= crc_reg1[4] ^ data_for_send[{
in_has_send_bit[2:0],2'b0}+2] ^ crc_reg1[15];
crc_reg1[6] <= crc_reg1[5];
crc_reg1[7] <= crc_reg1[6];
crc_reg1[8] <= crc_reg1[7];
crc_reg1[9] <= crc_reg1[8];
crc_reg1[10] <= crc_reg1[9];
crc_reg1[11] <= crc_reg1[10];
crc_reg1[12] <= crc_reg1[11] ^ data_for_send[{
in_has_send_bit[2:0],2'b0}+2] ^ crc_reg1[15];
crc_reg1[13] <= crc_reg1[12];
crc_reg1[14] <= crc_reg1[13];
crc_reg1[15] <= crc_reg1[14];
crc_reg0[0] <= data_for_send[{
in_has_send_bit[2:0],2'b0}+3] ^ crc_reg0[15];
crc_reg0[1] <= crc_reg0[0];
crc_reg0[2] <= crc_reg0[1];
crc_reg0[3] <= crc_reg0[2];
crc_reg0[4] <= crc_reg0[3];
crc_reg0[5] <= crc_reg0[4] ^ data_for_send[{
in_has_send_bit[2:0],2'b0}+3] ^ crc_reg0[15];
crc_reg0[6] <= crc_reg0[5];
crc_reg0[7] <= crc_reg0[6];
crc_reg0[8] <= crc_reg0[7];
crc_reg0[9] <= crc_reg0[8];
crc_reg0[10] <= crc_reg0[9];
crc_reg0[11] <= crc_reg0[10];
crc_reg0[12] <= crc_reg0[11] ^ data_for_send[{
in_has_send_bit[2:0],2'b0}+3] ^ crc_reg0[15];
crc_reg0[13] <= crc_reg0[12];
crc_reg0[14] <= crc_reg0[13];
crc_reg0[15] <= crc_reg0[14];
end
end
end
7.fifo Reading enable
- It is divided into 1 Line and 4 The situation of the line
- When the data is sent out fifo Reading enables , It means that this time it's over , Need to read the next data
always @(*) begin
sd_fifo_re = 1'b0;
if (!in_data_width)
begin
if(((in_current_state == `DATA_STATE_SEND_START_BIT) && (in_has_send_bit[4:0] == 5'b0)) ||
((in_current_state == `DATA_STATE_SEND) && (in_next_state == `DATA_STATE_SEND) && (in_has_send_bit[4:0] == 5'b11111)))
sd_fifo_re = 1'b1;
end
else begin
if(((in_current_state == `DATA_STATE_SEND_START_BIT) && (in_has_send_bit[2:0] == 3'b0)) ||
((in_current_state == `DATA_STATE_SEND) && (in_next_state == `DATA_STATE_SEND) && (in_has_send_bit[2:0] == 3'b111)))
sd_fifo_re = 1'b1;
end
end
8.crc16 The state of
- crc16 The status of is 3bit Count , from crc_status_reg decision ,010 Is normal
always @(*) begin
out_crc_status_wrong =1'b0;
if((in_current_state == `DATA_STATE_SEND_BUSY) && !(crc_status_reg == 4'b0010))
out_crc_status_wrong =1'b1;
end
边栏推荐
- 你真的理解粘包与半包吗?3分钟搞懂它
- Hash, bitmap and bloom filter for mass data De duplication
- 【C语言】字符串函数
- CVPR 2022 - learning non target knowledge for semantic segmentation of small samples
- 抢占周杰伦
- 【剑指 Offer】59 - I. 滑动窗口的最大值
- nest.js入门之 database
- 持续测试(CT)实战经验分享
- 基于图像和激光的多模态点云融合与视觉定位
- I feel cheated. Wechat tests the function of "size number" internally, and two wechat can be registered with the same mobile number
猜你喜欢
能同时做三个分割任务的模型,性能和效率优于MaskFormer!Meta&UIUC提出通用分割模型,性能优于任务特定模型!开源!...
Kubernetes DevOps CD工具对比选型
行业案例|数字化经营底座助力寿险行业转型
伺服力矩控制模式下的力矩目标值(fTorque)计算
Tsinghua, Cambridge and UIC jointly launched the first Chinese fact verification data set: evidence-based, covering many fields such as medical society
Classification of regression tests
Comparison and selection of kubernetes Devops CD Tools
Wireshark分析抓包数据*.cap
[unity shader] insert pass to realize the X-ray perspective effect of model occlusion
你真的理解粘包与半包吗?3分钟搞懂它
随机推荐
Thread pool and singleton mode and file operation
PTA 1101 B是A的多少倍
[demo] circular queue and conditional lock realize the communication between goroutines
CVPR 2022丨学习用于小样本语义分割的非目标知识
行业案例|数字化经营底座助力寿险行业转型
回归问题的评价指标和重要知识点总结
Comparison and selection of kubernetes Devops CD Tools
ip netns 命令(备忘)
nest.js入门之 database
6.关于jwt
体总:安全有序恢复线下体育赛事,力争做到国内赛事应办尽办
国内的软件测试会受到偏见吗
Do you really understand sticky bag and half bag? 3 minutes to understand it
持续测试(CT)实战经验分享
Antisamy: a solution against XSS attack tutorial
SQLite SQL exception near "with": syntax error
Continuous test (CT) practical experience sharing
简单几步教你如何看k线图图解
将模型的记忆保存下来!Meta&UC Berkeley提出MeMViT,建模时间支持比现有模型长30倍,计算量仅增加4.5%...
How many times is PTA 1101 B than a