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公司首先提出了 ...
随机推荐
- Linux内核哈希表分析与应用
目录(?)[+] Linux内核哈希表分析与应用 Author:tiger-johnTime:2012-12-20mail:jibo.tiger@gmail.comBlog:http:// ...
- Android.Study.Question
1. NullPointerException 1.1 发生该异常的原因. 1.2 解决方法有哪几种? try-catch 2. Eclipse 中 debug/run 两个模式,run 是relea ...
- 错误:在非结构或联合中请求成员‘next’
#include <stdio.h> #include <stdlib.h> #define ElemType int #define Status int #define O ...
- BZOJ1935或洛谷2163 [SHOI2007]园丁的烦恼
BZOJ原题链接 洛谷原题链接 很容易想到二维前缀和. 设\(S[i][j]\)表示矩阵\((0, 0)(i, j)\)内树木的棵数,则询问的矩形为\((x, y)(xx, yy)\)时,答案为\(S ...
- cent 7 安装VNC
1. yum install tigervnc-server; 2.cp /lib/systemd/system/vncserver@.service /etc/systemd/system/vncs ...
- Linux中处理字符串
获取字符串长度: ${#字符串变量名} 截取子串: 1. expr substr 字符串 起始位置 截取长度 2. 命令输出 | cut -c 起始位置-结束位置 命令输出 | cut -c &quo ...
- Laravel Many to Many Polymorphic Relationship
Many to many Polymorphic relationship is also a little bit complicated to understand. For example, i ...
- Python编程笔记(第二篇)二进制、字符编码、数据类型
一.二进制 bin() 在python中可以用bin()内置函数获取一个十进制的数的二进制 计算机容量单位 8bit = 1 bytes 字节,最小的存储单位,1bytes缩写为1B 1KB = 10 ...
- rap2与postman自动化测试
rap2的接口数据可以全部导入postman: 在collections集合里面点击run;
- 2017/2/12:springMVC的简单文件上传跟拦截器
1.写文件上传的界面jsp代码如下重点为文件上传标签的类型 2.写登录成功跟失败的界面:成功自己写 3.写springMVC的文件上传的controller的方法 4.最后一步配置spring-ser ...