PCI总线目标接口状态机设计
module state_machine (devsel_l, trdy_l, stop_l, pci_ad_oe,
dts_oe, par_oe, bk_oe, pci_ad_en, hit_ba0_l, hit_ba1_l,
pci_frame_l, pci_idsel, pci_irdy_l, pci_ad, pci_cbe_l,
pci_clk, pci_rst_l, abort_sig, data_stop_l, com,
data_write_l, ready_l, bkend_abort_l, count_rst_l, count_en_l,
retry_l, base_region0_l, base_region1_l, r_w_l, data_read_l,
be_oe);
output devsel_l;
output trdy_l;
output stop_l;
output pci_ad_oe; // OE for PCI address bus
output dts_oe; // OE control for the devsel, trdy_l, stop_l (dts)
output par_oe; // OE control for pci_par
output bk_oe; // OE control for bkend_dat bus
output pci_ad_en; // clock enable for the PCI address latch register
output abort_sig; // sets the status register bit for abort
output data_write_l; // used as a clock enable for the pci_clk
// to the bkend device
output count_rst_l; // async reset to the retry counter
output count_en_l; // the clock enable for the retry counter
output base_region0_l; // chip selects to the backend
output base_region1_l; // chip selects to the backend
output r_w_l; // read == 1 & write == 0
output data_read_l; // the read strobe for the backend device
output be_oe; // enables the byte enables for the backend
input hit_ba0_l; // The pci address is in base address 0
input hit_ba1_l; // The pci address is in base address 1
input pci_frame_l; // The pci_frame_l signal
input pci_idsel; // The pci idsel signal
input pci_irdy_l; // The pci irdy signal
input [31:0] pci_ad; // raw pci address data bus
input [3:0] pci_cbe_l; // The command or byte enables
input pci_clk;
input pci_rst_l;
input bkend_abort_l; // bkend has had a fatal error
input data_stop_l; // bkend requesting transaction to stop
input [1:0] com;
input ready_l; // bkend is ready to start a transaction cycle
input retry_l; // when active retry counter has timed out
reg devsel_l;
reg trdy_l, stop_l, pci_ad_oe;
reg dts_oe, par_oe, bk_oe;
reg pci_ad_en;
reg be_oe;
reg abort_sig;
reg count_rst_l, count_en_l;
reg base_region0_l, base_region1_l;
reg r_w_l;
reg read_flag, single_read_flag;
reg [11:0] cstate;
parameter [11:0]
idle = 12'b0000_0000_0001,
con_wait = 12'b0000_0000_0010,
con_wait2 = 12'b0000_0000_0100,
con = 12'b0000_0000_1000,
read_wait = 12'b0000_0001_0000,
rw = 12'b0000_0010_0000,
rw_wait = 12'b0000_0100_0000,
rw_wait2 = 12'b0000_1000_0000,
last_rw = 12'b0001_0000_0000,
backoff = 12'b0010_0000_0000,
retry = 12'b0100_0000_0000,
abort = 12'b1000_0000_0000;
`define config_read (pci_cbe_l == 4'b1010)
`define config_write (pci_cbe_l == 4'b1011)
`define func_zero_type_zero (pci_ad[10:8] == 3'b000) && (pci_ad[1:0] == 2'b00)
`define write_ba0 pci_addr[7:2] == 6'h10
`define write_ba1 pci_addr[7:2] == 6'h14
`define no_config (!pci_idsel && !pci_frame_l)
`define io_read ((pci_cbe_l == 4'b0010) && com[0])
`define io_write ((pci_cbe_l == 4'b0011) && com[0])
`define mem_read ((pci_cbe_l == 4'b0110) && com[1])
`define mem_write ((pci_cbe_l == 4'b0111) && com[1])
// mealy state machine
always @ (posedge pci_clk or negedge pci_rst_l)
begin
if (!pci_rst_l) begin
cstate <= #1 idle;
devsel_l <= #1 1;
trdy_l <= #1 1;
stop_l <= #1 1;
pci_ad_oe <= #13 0;
dts_oe <= #13 0;
par_oe <= #13 0;
bk_oe <= #13 0;
abort_sig <= #1 0;
count_rst_l <= #1 1;
count_en_l <= #1 1;
base_region0_l <= #1 1;
base_region1_l <= #1 1;
r_w_l <= #1 1;
read_flag <= #1 0;
single_read_flag <= #1 0;
end
else begin
case (cstate)
idle:
begin
if ((`config_read || `config_write) && `func_zero_type_zero
&& !pci_frame_l && pci_idsel) begin
cstate <= #1 con_wait;
dts_oe <= #13 1;
if (`config_read) begin
pci_ad_oe <= #13 1;
end
else begin
pci_ad_oe <= #13 0;
end
par_oe <= #13 0;
devsel_l <= #1 1;
trdy_l <= #1 1;
stop_l <= #1 1;
count_rst_l <= #1 1;
count_en_l <= #1 1;
abort_sig <= #1 0;
base_region0_l <= #1 1;
base_region1_l <= #1 1;
r_w_l <= #1 1;
end
else if ((`io_read || `mem_read) && `no_config ) begin
cstate <= #1 rw_wait;
read_flag <= #1 1;
dts_oe <= #13 1;
devsel_l <= #1 1;
trdy_l <= #1 1;
stop_l <= #1 1;
count_rst_l <= #1 0;
count_en_l <= #1 1;
abort_sig <= #1 0;
base_region0_l <= #1 1;
base_region1_l <= #1 1;
r_w_l <= #1 1;
end
else if ((`io_write || `mem_write) && `no_config )begin
cstate <= #1 rw_wait;
read_flag <= #1 0;
dts_oe <= #13 1;
devsel_l <= #1 1;
trdy_l <= #1 1;
stop_l <= #1 1;
count_rst_l <= #1 0;
count_en_l <= #1 1;
abort_sig <= #1 0;
base_region0_l <= #1 1;
base_region1_l <= #1 1;
r_w_l <= #1 1;
end
else begin
cstate <= #1 idle;
devsel_l <= #1 1;
trdy_l <= #1 1;
stop_l <= #1 1;
pci_ad_oe <= #13 0;
dts_oe <= #13 0;
par_oe <= #13 0;
bk_oe <= #13 0;
abort_sig <= #1 0;
count_rst_l <= #1 1;
count_en_l <= #1 1;
abort_sig <= #1 0;
base_region0_l <= #1 1;
base_region1_l <= #1 1;
r_w_l <= #1 1;
end
end
con_wait:
begin
cstate <= con_wait2;
devsel_l <= #1 0;
end
con_wait2:
begin
cstate <= con;
par_oe <= #13 1;
trdy_l <= #1 0;
if (!pci_frame_l)
stop_l <= #1 0;
else
stop_l <= #1 1;
end
con:
begin
if (!pci_irdy_l) begin
cstate <= backoff;
devsel_l <= #1 1;
trdy_l <= #1 1;
stop_l <= #1 1;
pci_ad_oe <= #13 0;
end
else begin
cstate <= con;
devsel_l <= #1 0;
trdy_l <= #1 0;
if (!pci_frame_l)
stop_l <= #1 0;
else
stop_l <= #1 1;
end
end
rw_wait:
begin
if (pci_frame_l && read_flag) begin
single_read_flag <= #1 1;
end
else begin
single_read_flag <= #1 0;
end
if (!hit_ba0_l) begin
cstate <= #1 rw_wait2;
count_rst_l <= #1 1;
count_en_l <= #1 0;
base_region0_l <= #1 0;
base_region1_l <= #1 1;
dts_oe <= #13 1;
devsel_l <= #1 1;
trdy_l <= #1 1;
stop_l <= #1 1;
if (read_flag) begin
bk_oe <= #13 0;
r_w_l <= #1 1;
end
else begin
bk_oe <= #13 1;
r_w_l <= #1 0;
end
end
else if (!hit_ba1_l) begin
cstate <= #1 rw_wait2;
count_rst_l <= #1 1;
count_en_l <= #1 0;
base_region0_l <= #1 1;
base_region1_l <= #1 0;
dts_oe <= #13 1;
devsel_l <= #1 1;
trdy_l <= #1 1;
stop_l <= #1 1;
if (read_flag) begin
bk_oe <= #13 0;
r_w_l <= #1 1;
end
else begin
bk_oe <= #13 1;
r_w_l <= #1 0;
end
end
else begin
cstate <= #1 idle;
bk_oe <= #13 0;
count_rst_l <= #1 1;
count_en_l <= #1 1;
r_w_l <= #1 1;
base_region0_l <= #1 1;
base_region1_l <= #1 1;
dts_oe <= #13 0;
devsel_l <= #1 1;
trdy_l <= #1 1;
stop_l <= #1 1;
end
end
rw_wait2: // don't monitor abort here
begin
if (read_flag) begin
pci_ad_oe <= #13 1;
par_oe <= #13 1;
end
else begin
pci_ad_oe <= #13 0;
end
if (!retry_l) begin
// retry timeout
cstate <= #1 retry;
devsel_l <= #1 0;
trdy_l <= #1 1;
stop_l <= #1 0;
end
else if (retry_l && !ready_l && !pci_frame_l && data_stop_l) begin
// normal burst write or read with no timeout or stop
devsel_l <= #1 0;
stop_l <= #1 1;
if (read_flag) begin
cstate <= read_wait;
trdy_l <= #1 1;
end
else begin
cstate <= rw;
trdy_l <= #1 0;
end
end
else if (retry_l && !ready_l && pci_frame_l) begin
// single read or write with no timeout & stop is don't care
devsel_l <= #1 0;
stop_l <= #1 1;
if (read_flag) begin
cstate <= read_wait;
trdy_l <= #1 1;
end
else begin
cstate <= last_rw;
trdy_l <= #1 0;
end
end
else if (retry_l && !ready_l && !data_stop_l) begin
// single read or write & backend only wants one cycle
if (read_flag ) begin
cstate <= read_wait;
devsel_l <= #1 0;
trdy_l <= #1 1;
stop_l <= #1 1;
end
else begin
cstate <= last_rw;
devsel_l <= #1 0;
trdy_l <= #1 0;
stop_l <= #1 0;
end
end
else if (retry_l && ready_l) begin
// enable retry counter
cstate <= #1 rw_wait2;
count_en_l <= #1 0;
devsel_l <= #1 0;
trdy_l <= #1 1;
stop_l <= #1 1;
end
else if (!bkend_abort_l) begin
cstate <= #1 abort;
devsel_l <= #1 1;
trdy_l <= #1 1;
stop_l <= #1 0;
abort_sig <= #1 1;
end
else begin
cstate <= rw_wait2;
end
end
read_wait:
//This state is used to READ the first piece of data
begin
if ( !bkend_abort_l) begin
cstate <= #1 abort;
devsel_l <= #1 1;
trdy_l <= #1 1;
stop_l <= #1 0;
bk_oe <= #13 0;
base_region0_l <= #1 1;
base_region1_l <= #1 1;
abort_sig <= #1 1;
end
else if (!pci_frame_l && bkend_abort_l && data_stop_l) begin
cstate <= #1 rw;
devsel_l <= #1 0;
trdy_l <= #1 0;
stop_l <= #1 1;
end
else if (pci_frame_l && bkend_abort_l && data_stop_l) begin
cstate <= #1 last_rw;
devsel_l <= #1 0;
trdy_l <= #1 0;
stop_l <= #1 1;
end
else if (!data_stop_l) begin
cstate <= last_rw;
devsel_l <= #1 0;
trdy_l <= #1 0;
stop_l <= #1 0;
bk_oe <= #13 0;
end
else begin
cstate <= idle;
end
end
rw:
begin
if ( !bkend_abort_l) begin
cstate <= #1 abort;
devsel_l <= #1 1;
trdy_l <= #1 1;
stop_l <= #1 0;
bk_oe <= #13 0;
base_region0_l <= #1 1;
base_region1_l <= #1 1;
abort_sig <= #1 1;
end
else if (!pci_frame_l && bkend_abort_l && data_stop_l) begin
cstate <= #1 rw;
devsel_l <= #1 0;
trdy_l <= #1 0;
stop_l <= #1 1;
end
else if (pci_frame_l && bkend_abort_l && data_stop_l) begin
cstate <= #1 backoff;
devsel_l <= #1 1;
trdy_l <= #1 1;
stop_l <= #1 1;
pci_ad_oe <= #13 0;
bk_oe <= #13 0;
base_region0_l <= #1 1;
base_region1_l <= #1 1;
end
else if (pci_frame_l && !data_stop_l) begin
cstate <= backoff;
devsel_l <= #1 1;
trdy_l <= #1 1;
stop_l <= #1 1;
bk_oe <= #13 0;
base_region0_l <= #1 1;
base_region1_l <= #1 1;
end
else if (!data_stop_l) begin
cstate <= last_rw;
devsel_l <= #1 0;
trdy_l <= #1 0;
stop_l <= #1 0;
end
else begin
cstate <= idle;
end
end
last_rw:
begin
if (pci_frame_l) begin
// pci_frame_l end gracefully
cstate <= backoff;
devsel_l <= #1 1;
trdy_l <= #1 1;
stop_l <= #1 1;
bk_oe <= #13 0;
pci_ad_oe <= #13 0;
base_region0_l <= #1 1;
base_region1_l <= #1 1;
end
else if (!pci_frame_l) begin
cstate <= last_rw;
devsel_l <= #1 0;
trdy_l <= #1 1;
stop_l <= #1 0;
end
else begin
cstate <= idle;
end
end
retry:
begin
if (!pci_frame_l) begin
cstate <= retry;
dts_oe <= #13 1;
devsel_l <= #1 0;
trdy_l <= #1 1;
stop_l <= #1 0;
bk_oe <= #13 0;
base_region0_l <= #1 1;
base_region1_l <= #1 1;
end
else if (pci_frame_l) begin
cstate <= backoff;
devsel_l <= #1 1;
trdy_l <= #1 1;
stop_l <= #1 1;
bk_oe <= #13 0;
pci_ad_oe <= #13 0;
base_region0_l <= #1 1;
base_region1_l <= #1 1;
end
end
abort:
begin
if (!pci_frame_l) begin
cstate <= abort;
devsel_l <= #1 1;
trdy_l <= #1 1;
stop_l <= #1 0;
abort_sig <= #1 0;
end
else if (pci_frame_l) begin
cstate <= backoff;
devsel_l <= #1 1;
trdy_l <= #1 1;
stop_l <= #1 1;
bk_oe <= #13 0;
pci_ad_oe <= #13 0;
abort_sig <= #1 0;
end
end
backoff:
begin
cstate <= idle;
pci_ad_oe <= #13 0;
dts_oe <= #13 0;
par_oe <= #13 0;
bk_oe <=#13 0;
end
default:
begin
cstate <= #1 idle;
devsel_l <= #1 1;
trdy_l <= #1 1;
stop_l <= #1 1;
pci_ad_oe <= #13 0;
dts_oe <= #13 0;
par_oe <= #13 0;
bk_oe <= #13 0;
abort_sig <= #1 0;
end
endcase
end
end
always @ (cstate)
begin
if (cstate == idle || cstate == backoff) begin
be_oe <= #1 0;
end
else begin
be_oe <= #1 1;
end
end
always @ (pci_frame_l or cstate)
begin
if (cstate == idle && !pci_frame_l) begin
pci_ad_en <= #1 1;
end
else begin
pci_ad_en <= #1 0;
end
end
assign #1 data_write_l = (!trdy_l && !pci_irdy_l && !read_flag && !ready_l) ? 0 : 1;
assign #1 data_read_l = ( (single_read_flag && (cstate == rw_wait2) && !ready_l ) || (!single_read_flag && read_flag && !pci_frame_l && !pci_irdy_l && !ready_l && (cstate == rw_wait2 || cstate == rw || cstate == last_rw || cstate == abort)) ) ? 0 : 1;
endmodule
PCI总线目标接口状态机设计的更多相关文章
- 【Linux开发】【DSP开发】Linux设备驱动之——PCI 总线
PCI总线概述 随着通用处理器和嵌入式技术的迅猛发展,越来越多的电子设备需要由处理器控制.目前大多数CPU和外部设备都会提供PCI总线的接口,PCI总线已成为计算机系统中一种应用广泛.通用的总线标准 ...
- 利用FPGA实现PCI总线接口及Windows驱动实现
利用FPGA实现PCI总线接口及Windows驱动实现 关于PCI总线协议,资料网上.书本都是.这里我们仅仅对重点对利用FPGA实现PCI总线接口问题进行简单分析.下图是PCI总线接口信号: 配置空间 ...
- 007 PCI总线的桥与配置(二)
一.PCI桥与PCI设备的配置空间 PCI设备都有独立的配置空间,HOST主桥通过配置读写总线事务访问这段空间.PCI总线规定了三种类型的PCI配置空间,分别是PCI Agent设备使用的配置空间,P ...
- 实验七 状态机设计ADC0809采样控制电路
一.实验目的 学习用状态机实现A/D转换器ADC0809的采样控制电路. 二.实验内容 利用QuartusⅡ实现A/D转换器ADC0809的采样控制电路状态机设计:给出仿真波形.最后进行引脚锁定并进行 ...
- 1.2 PCI总线的信号定义
PCI总线是一条共享总线,在一条PCI总线上可以挂接多个PCI设备.这些PCI设备通过一系列信号与PCI总线相连,这些信号由地址/数据信号.控制信号.仲裁信号.中断信号等多种信号组成. PCI总线是一 ...
- 3.3 与Cache相关的PCI总线事务
PCI总线规范定义了一系列与Cache相关的总线事务,以提高PCI设备与主存储器进行数据交换的效率,即DMA读写的效率.当PCI设备使用DMA方式向存储器进行读写操作时,一定需要经过HOST主桥,而H ...
- PCI总线 DMA burst 基本概念
转载地址:http://blog.csdn.net/sunjiajiang/article/details/7945057 DMA和burst不是一个概念. DMA传送不经过CPU的控制,假如硬盘的数 ...
- 006 PCI总线的桥与配置(一)
在PCI体系结构中,含有两类桥片,一个是HOST主桥,另一个是PCI桥.在每一个PCI设备中(包括PCI桥)都含有一个配置空间.这个配置空间由HOST主桥管理,而PCI桥可以转发来自HOST主桥的配置 ...
- PCI总线基本概念与历史
PCI总线历史 这里必须说下 PCI-SIG,1991 年下半年,Intel 公司,并联合IBM.Compaq.AST.HP.DEC 等100 多家公司成立了PCI 集团 并且Intel公司首先提出了 ...
随机推荐
- hdu 5692(dfs+线段树) Snacks
题目http://acm.hdu.edu.cn/showproblem.php?pid=5692 题目说每个点至多经过一次,那么就是只能一条路线走到底的意思,看到这题的格式, 多个询问多个更新, 自然 ...
- iOS 3D Touch功能
新的触摸体验——iOS9的3D Touch 一.引言 在iphone6s问世之后,很多果粉都争先要体验3D Touch给用户带来的额外维度上的交互,这个设计之所以叫做3D Touch,其原理上是增加了 ...
- git的命令详解
# git三个区 + 工作区: 写代码的地方 + 暂存区: 暂时存储代码 + 仓库区: 代码提交到了仓库区,就生成一条历史记录(版本) 工作区===> 暂存区 ===> 仓库区 # git ...
- mysql 优化之一
提升速度 show variables like 'innodb_flush_log_at_trx_commit'; 会显示为1 set global innodb_flush_log_at_trx ...
- 11. pt-heartbeat
pt-heartbeat [OPTIONS] [DSN] --update|--monitor|--check|--stop ------------------------------------- ...
- MySQL学习笔记-锁相关话题
在事务相关话题中,已经提到事务隔离性依靠锁机制实现的.在本篇中围绕着InnoDB与MyISAM锁机制的不同展开,进而描述锁的实现方式,多种锁的概念,以及死锁产生的原因. Mysql常用存储引擎的锁 ...
- TI and RI
https://blog.csdn.net/qq_27977257/article/details/70677661 51单片机的串口,是个全双工的串口,发送数据的同时,还可以接收数据.当串行发送完毕 ...
- java面试感悟【一】
我最终选择不包装工作经验,或许是因为我怂,或许是因为一些莫名其妙的坚持…… 然而结果就是在boss上沟通了20多家,只有7家让我投了简历,1家跟我说要我发个时间段给他稍后告诉我面试时间,然后就没有然后 ...
- 再读c++primer plus 004
第九章 内存模型和名称空间 1.如果文件名包含在尖括号中,则c++编译器将在存储标准头文件的主机系统的文件系统中查找,但如果文件名包含在双引号中,则编译器将首先查找当前的工作目录或源代码目录(或其他 ...
- 42.OC中instancetype与id的区别
区别: 在ARC(Auto Reference Count)环境下: instancetype用来在编译期确定实例的类型,而使用id的话,编译器不检查类型,运行时检查类型 在MRC(Manual Re ...