remove lsp
This commit is contained in:
commit
35d0886e6f
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,9 +1,15 @@
|
||||
<<<<<<< HEAD
|
||||
library
|
||||
node_modules
|
||||
out
|
||||
./*.log
|
||||
./*.str
|
||||
dist
|
||||
=======
|
||||
out
|
||||
dist
|
||||
node_modules
|
||||
>>>>>>> 199b7a8af3ea01baea4b20c89273a490dc0dc9d2
|
||||
script/__pycache__
|
||||
.vscode-test/
|
||||
*.vsix
|
||||
|
@ -42,8 +42,12 @@
|
||||
|
||||
```bash
|
||||
python script/command/make_package.py
|
||||
<<<<<<< HEAD
|
||||
```
|
||||
|
||||
## library更新
|
||||
|
||||
library的更新不会随着Digital-IDE的git一起保存,是专门去拉取更新的,但是打包要一起打包进插件之中。
|
||||
library的更新不会随着Digital-IDE的git一起保存,是专门去拉取更新的,但是打包要一起打包进插件之中。
|
||||
=======
|
||||
```
|
||||
>>>>>>> 199b7a8af3ea01baea4b20c89273a490dc0dc9d2
|
||||
|
519
lib/bd/xilinx/MicroBlaze_default.bd
Normal file
519
lib/bd/xilinx/MicroBlaze_default.bd
Normal file
@ -0,0 +1,519 @@
|
||||
{
|
||||
"design": {
|
||||
"design_info": {
|
||||
"boundary_crc": "0xA1D73E4ECA8CEDF5",
|
||||
"name": "MicroBlaze_default",
|
||||
"synth_flow_mode": "Hierarchical",
|
||||
"validated": "true"
|
||||
},
|
||||
"design_tree": {
|
||||
"microblaze_0": "",
|
||||
"microblaze_0_local_memory": {
|
||||
"dlmb_v10": "",
|
||||
"ilmb_v10": "",
|
||||
"dlmb_bram_if_cntlr": "",
|
||||
"ilmb_bram_if_cntlr": "",
|
||||
"lmb_bram": ""
|
||||
},
|
||||
"mdm_1": "",
|
||||
"rst_clk_wiz_1_100M": "",
|
||||
"axi_gpio_0": "",
|
||||
"microblaze_0_axi_periph": {
|
||||
"s00_couplers": {}
|
||||
}
|
||||
},
|
||||
"interface_ports": {
|
||||
"gpio_rtl_0": {
|
||||
"mode": "Master",
|
||||
"vlnv": "xilinx.com:interface:gpio_rtl:1.0"
|
||||
}
|
||||
},
|
||||
"ports": {
|
||||
"cpu_clk": {
|
||||
"type": "clk",
|
||||
"direction": "I",
|
||||
"parameters": {
|
||||
"ASSOCIATED_RESET": {
|
||||
"value": "cpu_rst_n"
|
||||
},
|
||||
"CLK_DOMAIN": {
|
||||
"value": "MicroBlaze_default_Clk_0",
|
||||
"value_src": "default"
|
||||
},
|
||||
"FREQ_HZ": {
|
||||
"value": "100000000",
|
||||
"value_src": "default"
|
||||
},
|
||||
"INSERT_VIP": {
|
||||
"value": "0",
|
||||
"value_src": "default"
|
||||
},
|
||||
"PHASE": {
|
||||
"value": "0.000",
|
||||
"value_src": "default"
|
||||
}
|
||||
}
|
||||
},
|
||||
"cpu_rst_n": {
|
||||
"type": "rst",
|
||||
"direction": "I",
|
||||
"parameters": {
|
||||
"INSERT_VIP": {
|
||||
"value": "0",
|
||||
"value_src": "default"
|
||||
},
|
||||
"POLARITY": {
|
||||
"value": "ACTIVE_LOW"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"microblaze_0": {
|
||||
"vlnv": "xilinx.com:ip:microblaze:11.0",
|
||||
"xci_name": "MicroBlaze_default_microblaze_0_0",
|
||||
"parameters": {
|
||||
"C_DEBUG_ENABLED": {
|
||||
"value": "1"
|
||||
},
|
||||
"C_D_AXI": {
|
||||
"value": "1"
|
||||
},
|
||||
"C_D_LMB": {
|
||||
"value": "1"
|
||||
},
|
||||
"C_I_LMB": {
|
||||
"value": "1"
|
||||
}
|
||||
},
|
||||
"hdl_attributes": {
|
||||
"BMM_INFO_PROCESSOR": {
|
||||
"value": "microblaze-le > MicroBlaze_default microblaze_0_local_memory/dlmb_bram_if_cntlr",
|
||||
"value_src": "default"
|
||||
},
|
||||
"KEEP_HIERARCHY": {
|
||||
"value": "yes",
|
||||
"value_src": "default"
|
||||
}
|
||||
}
|
||||
},
|
||||
"microblaze_0_local_memory": {
|
||||
"interface_ports": {
|
||||
"DLMB": {
|
||||
"mode": "MirroredMaster",
|
||||
"vlnv": "xilinx.com:interface:lmb_rtl:1.0"
|
||||
},
|
||||
"ILMB": {
|
||||
"mode": "MirroredMaster",
|
||||
"vlnv": "xilinx.com:interface:lmb_rtl:1.0"
|
||||
}
|
||||
},
|
||||
"ports": {
|
||||
"LMB_Clk": {
|
||||
"type": "clk",
|
||||
"direction": "I"
|
||||
},
|
||||
"SYS_Rst": {
|
||||
"type": "rst",
|
||||
"direction": "I"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"dlmb_v10": {
|
||||
"vlnv": "xilinx.com:ip:lmb_v10:3.0",
|
||||
"xci_name": "MicroBlaze_default_dlmb_v10_0"
|
||||
},
|
||||
"ilmb_v10": {
|
||||
"vlnv": "xilinx.com:ip:lmb_v10:3.0",
|
||||
"xci_name": "MicroBlaze_default_ilmb_v10_0"
|
||||
},
|
||||
"dlmb_bram_if_cntlr": {
|
||||
"vlnv": "xilinx.com:ip:lmb_bram_if_cntlr:4.0",
|
||||
"xci_name": "MicroBlaze_default_dlmb_bram_if_cntlr_0",
|
||||
"parameters": {
|
||||
"C_ECC": {
|
||||
"value": "0"
|
||||
}
|
||||
},
|
||||
"hdl_attributes": {
|
||||
"BMM_INFO_ADDRESS_SPACE": {
|
||||
"value": "byte 0x00000000 32 > MicroBlaze_default microblaze_0_local_memory/lmb_bram",
|
||||
"value_src": "default"
|
||||
},
|
||||
"KEEP_HIERARCHY": {
|
||||
"value": "yes",
|
||||
"value_src": "default"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ilmb_bram_if_cntlr": {
|
||||
"vlnv": "xilinx.com:ip:lmb_bram_if_cntlr:4.0",
|
||||
"xci_name": "MicroBlaze_default_ilmb_bram_if_cntlr_0",
|
||||
"parameters": {
|
||||
"C_ECC": {
|
||||
"value": "0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lmb_bram": {
|
||||
"vlnv": "xilinx.com:ip:blk_mem_gen:8.4",
|
||||
"xci_name": "MicroBlaze_default_lmb_bram_0",
|
||||
"parameters": {
|
||||
"Memory_Type": {
|
||||
"value": "True_Dual_Port_RAM"
|
||||
},
|
||||
"use_bram_block": {
|
||||
"value": "BRAM_Controller"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"interface_nets": {
|
||||
"microblaze_0_ilmb_bus": {
|
||||
"interface_ports": [
|
||||
"ilmb_v10/LMB_Sl_0",
|
||||
"ilmb_bram_if_cntlr/SLMB"
|
||||
]
|
||||
},
|
||||
"microblaze_0_dlmb_bus": {
|
||||
"interface_ports": [
|
||||
"dlmb_v10/LMB_Sl_0",
|
||||
"dlmb_bram_if_cntlr/SLMB"
|
||||
]
|
||||
},
|
||||
"microblaze_0_ilmb_cntlr": {
|
||||
"interface_ports": [
|
||||
"ilmb_bram_if_cntlr/BRAM_PORT",
|
||||
"lmb_bram/BRAM_PORTB"
|
||||
]
|
||||
},
|
||||
"microblaze_0_dlmb_cntlr": {
|
||||
"interface_ports": [
|
||||
"dlmb_bram_if_cntlr/BRAM_PORT",
|
||||
"lmb_bram/BRAM_PORTA"
|
||||
]
|
||||
},
|
||||
"microblaze_0_dlmb": {
|
||||
"interface_ports": [
|
||||
"DLMB",
|
||||
"dlmb_v10/LMB_M"
|
||||
]
|
||||
},
|
||||
"microblaze_0_ilmb": {
|
||||
"interface_ports": [
|
||||
"ILMB",
|
||||
"ilmb_v10/LMB_M"
|
||||
]
|
||||
}
|
||||
},
|
||||
"nets": {
|
||||
"microblaze_0_Clk": {
|
||||
"ports": [
|
||||
"LMB_Clk",
|
||||
"dlmb_v10/LMB_Clk",
|
||||
"dlmb_bram_if_cntlr/LMB_Clk",
|
||||
"ilmb_v10/LMB_Clk",
|
||||
"ilmb_bram_if_cntlr/LMB_Clk"
|
||||
]
|
||||
},
|
||||
"SYS_Rst_1": {
|
||||
"ports": [
|
||||
"SYS_Rst",
|
||||
"dlmb_v10/SYS_Rst",
|
||||
"dlmb_bram_if_cntlr/LMB_Rst",
|
||||
"ilmb_v10/SYS_Rst",
|
||||
"ilmb_bram_if_cntlr/LMB_Rst"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"mdm_1": {
|
||||
"vlnv": "xilinx.com:ip:mdm:3.2",
|
||||
"xci_name": "MicroBlaze_default_mdm_1_0"
|
||||
},
|
||||
"rst_clk_wiz_1_100M": {
|
||||
"vlnv": "xilinx.com:ip:proc_sys_reset:5.0",
|
||||
"xci_name": "MicroBlaze_default_rst_clk_wiz_1_100M_0"
|
||||
},
|
||||
"axi_gpio_0": {
|
||||
"vlnv": "xilinx.com:ip:axi_gpio:2.0",
|
||||
"xci_name": "MicroBlaze_default_axi_gpio_0_0"
|
||||
},
|
||||
"microblaze_0_axi_periph": {
|
||||
"vlnv": "xilinx.com:ip:axi_interconnect:2.1",
|
||||
"xci_name": "MicroBlaze_default_microblaze_0_axi_periph_0",
|
||||
"parameters": {
|
||||
"NUM_MI": {
|
||||
"value": "1"
|
||||
}
|
||||
},
|
||||
"interface_ports": {
|
||||
"S00_AXI": {
|
||||
"mode": "Slave",
|
||||
"vlnv": "xilinx.com:interface:aximm_rtl:1.0"
|
||||
},
|
||||
"M00_AXI": {
|
||||
"mode": "Master",
|
||||
"vlnv": "xilinx.com:interface:aximm_rtl:1.0"
|
||||
}
|
||||
},
|
||||
"ports": {
|
||||
"ACLK": {
|
||||
"type": "clk",
|
||||
"direction": "I",
|
||||
"parameters": {
|
||||
"ASSOCIATED_RESET": {
|
||||
"value": "ARESETN"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ARESETN": {
|
||||
"type": "rst",
|
||||
"direction": "I"
|
||||
},
|
||||
"S00_ACLK": {
|
||||
"type": "clk",
|
||||
"direction": "I",
|
||||
"parameters": {
|
||||
"ASSOCIATED_BUSIF": {
|
||||
"value": "S00_AXI"
|
||||
},
|
||||
"ASSOCIATED_RESET": {
|
||||
"value": "S00_ARESETN"
|
||||
}
|
||||
}
|
||||
},
|
||||
"S00_ARESETN": {
|
||||
"type": "rst",
|
||||
"direction": "I"
|
||||
},
|
||||
"M00_ACLK": {
|
||||
"type": "clk",
|
||||
"direction": "I",
|
||||
"parameters": {
|
||||
"ASSOCIATED_BUSIF": {
|
||||
"value": "M00_AXI"
|
||||
},
|
||||
"ASSOCIATED_RESET": {
|
||||
"value": "M00_ARESETN"
|
||||
}
|
||||
}
|
||||
},
|
||||
"M00_ARESETN": {
|
||||
"type": "rst",
|
||||
"direction": "I"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"s00_couplers": {
|
||||
"interface_ports": {
|
||||
"M_AXI": {
|
||||
"mode": "Master",
|
||||
"vlnv": "xilinx.com:interface:aximm_rtl:1.0"
|
||||
},
|
||||
"S_AXI": {
|
||||
"mode": "Slave",
|
||||
"vlnv": "xilinx.com:interface:aximm_rtl:1.0"
|
||||
}
|
||||
},
|
||||
"ports": {
|
||||
"M_ACLK": {
|
||||
"type": "clk",
|
||||
"direction": "I",
|
||||
"parameters": {
|
||||
"ASSOCIATED_BUSIF": {
|
||||
"value": "M_AXI"
|
||||
},
|
||||
"ASSOCIATED_RESET": {
|
||||
"value": "M_ARESETN"
|
||||
}
|
||||
}
|
||||
},
|
||||
"M_ARESETN": {
|
||||
"type": "rst",
|
||||
"direction": "I"
|
||||
},
|
||||
"S_ACLK": {
|
||||
"type": "clk",
|
||||
"direction": "I",
|
||||
"parameters": {
|
||||
"ASSOCIATED_BUSIF": {
|
||||
"value": "S_AXI"
|
||||
},
|
||||
"ASSOCIATED_RESET": {
|
||||
"value": "S_ARESETN"
|
||||
}
|
||||
}
|
||||
},
|
||||
"S_ARESETN": {
|
||||
"type": "rst",
|
||||
"direction": "I"
|
||||
}
|
||||
},
|
||||
"interface_nets": {
|
||||
"s00_couplers_to_s00_couplers": {
|
||||
"interface_ports": [
|
||||
"S_AXI",
|
||||
"M_AXI"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"interface_nets": {
|
||||
"microblaze_0_axi_periph_to_s00_couplers": {
|
||||
"interface_ports": [
|
||||
"S00_AXI",
|
||||
"s00_couplers/S_AXI"
|
||||
]
|
||||
},
|
||||
"s00_couplers_to_microblaze_0_axi_periph": {
|
||||
"interface_ports": [
|
||||
"M00_AXI",
|
||||
"s00_couplers/M_AXI"
|
||||
]
|
||||
}
|
||||
},
|
||||
"nets": {
|
||||
"microblaze_0_axi_periph_ACLK_net": {
|
||||
"ports": [
|
||||
"M00_ACLK",
|
||||
"s00_couplers/M_ACLK"
|
||||
]
|
||||
},
|
||||
"microblaze_0_axi_periph_ARESETN_net": {
|
||||
"ports": [
|
||||
"M00_ARESETN",
|
||||
"s00_couplers/M_ARESETN"
|
||||
]
|
||||
},
|
||||
"S00_ACLK_1": {
|
||||
"ports": [
|
||||
"S00_ACLK",
|
||||
"s00_couplers/S_ACLK"
|
||||
]
|
||||
},
|
||||
"S00_ARESETN_1": {
|
||||
"ports": [
|
||||
"S00_ARESETN",
|
||||
"s00_couplers/S_ARESETN"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"interface_nets": {
|
||||
"microblaze_0_M_AXI_DP": {
|
||||
"interface_ports": [
|
||||
"microblaze_0/M_AXI_DP",
|
||||
"microblaze_0_axi_periph/S00_AXI"
|
||||
]
|
||||
},
|
||||
"microblaze_0_ilmb_1": {
|
||||
"interface_ports": [
|
||||
"microblaze_0/ILMB",
|
||||
"microblaze_0_local_memory/ILMB"
|
||||
]
|
||||
},
|
||||
"microblaze_0_dlmb_1": {
|
||||
"interface_ports": [
|
||||
"microblaze_0/DLMB",
|
||||
"microblaze_0_local_memory/DLMB"
|
||||
]
|
||||
},
|
||||
"microblaze_0_debug": {
|
||||
"interface_ports": [
|
||||
"mdm_1/MBDEBUG_0",
|
||||
"microblaze_0/DEBUG"
|
||||
]
|
||||
},
|
||||
"microblaze_0_axi_periph_M00_AXI": {
|
||||
"interface_ports": [
|
||||
"microblaze_0_axi_periph/M00_AXI",
|
||||
"axi_gpio_0/S_AXI"
|
||||
]
|
||||
},
|
||||
"axi_gpio_0_GPIO": {
|
||||
"interface_ports": [
|
||||
"gpio_rtl_0",
|
||||
"axi_gpio_0/GPIO"
|
||||
]
|
||||
}
|
||||
},
|
||||
"nets": {
|
||||
"rst_clk_wiz_1_100M_mb_reset": {
|
||||
"ports": [
|
||||
"rst_clk_wiz_1_100M/mb_reset",
|
||||
"microblaze_0/Reset"
|
||||
]
|
||||
},
|
||||
"rst_clk_wiz_1_100M_bus_struct_reset": {
|
||||
"ports": [
|
||||
"rst_clk_wiz_1_100M/bus_struct_reset",
|
||||
"microblaze_0_local_memory/SYS_Rst"
|
||||
]
|
||||
},
|
||||
"mdm_1_debug_sys_rst": {
|
||||
"ports": [
|
||||
"mdm_1/Debug_SYS_Rst",
|
||||
"rst_clk_wiz_1_100M/mb_debug_sys_rst"
|
||||
]
|
||||
},
|
||||
"cpu_clk": {
|
||||
"ports": [
|
||||
"cpu_clk",
|
||||
"microblaze_0/Clk",
|
||||
"rst_clk_wiz_1_100M/slowest_sync_clk",
|
||||
"microblaze_0_local_memory/LMB_Clk",
|
||||
"microblaze_0_axi_periph/S00_ACLK",
|
||||
"axi_gpio_0/s_axi_aclk",
|
||||
"microblaze_0_axi_periph/M00_ACLK",
|
||||
"microblaze_0_axi_periph/ACLK"
|
||||
]
|
||||
},
|
||||
"cpu_rst_n": {
|
||||
"ports": [
|
||||
"cpu_rst_n",
|
||||
"rst_clk_wiz_1_100M/ext_reset_in",
|
||||
"microblaze_0_axi_periph/S00_ARESETN",
|
||||
"axi_gpio_0/s_axi_aresetn",
|
||||
"microblaze_0_axi_periph/M00_ARESETN",
|
||||
"microblaze_0_axi_periph/ARESETN"
|
||||
]
|
||||
}
|
||||
},
|
||||
"addressing": {
|
||||
"/microblaze_0": {
|
||||
"address_spaces": {
|
||||
"Data": {
|
||||
"range": "4G",
|
||||
"width": "32",
|
||||
"segments": {
|
||||
"SEG_axi_gpio_0_Reg": {
|
||||
"address_block": "/axi_gpio_0/S_AXI/Reg",
|
||||
"offset": "0x40000000",
|
||||
"range": "64K"
|
||||
},
|
||||
"SEG_dlmb_bram_if_cntlr_Mem": {
|
||||
"address_block": "/microblaze_0_local_memory/dlmb_bram_if_cntlr/SLMB/Mem",
|
||||
"offset": "0x00000000",
|
||||
"range": "16K"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Instruction": {
|
||||
"range": "4G",
|
||||
"width": "32",
|
||||
"segments": {
|
||||
"SEG_ilmb_bram_if_cntlr_Mem": {
|
||||
"address_block": "/microblaze_0_local_memory/ilmb_bram_if_cntlr/SLMB/Mem",
|
||||
"offset": "0x00000000",
|
||||
"range": "16K"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2261
lib/bd/xilinx/PCIe_Test.bd
Normal file
2261
lib/bd/xilinx/PCIe_Test.bd
Normal file
File diff suppressed because it is too large
Load Diff
2235
lib/bd/xilinx/m3_xIP_default.bd
Normal file
2235
lib/bd/xilinx/m3_xIP_default.bd
Normal file
File diff suppressed because it is too large
Load Diff
832
lib/bd/xilinx/zynq_default.bd
Normal file
832
lib/bd/xilinx/zynq_default.bd
Normal file
@ -0,0 +1,832 @@
|
||||
{
|
||||
"design": {
|
||||
"design_info": {
|
||||
"boundary_crc": "0xCC6CFA5306BD3ECB",
|
||||
"device": "xc7z020clg400-2",
|
||||
"name": "zynq_default",
|
||||
"synth_flow_mode": "Hierarchical",
|
||||
"tool_version": "2018.3",
|
||||
"validated": "true"
|
||||
},
|
||||
"design_tree": {
|
||||
"processing_system7_0": ""
|
||||
},
|
||||
"interface_ports": {
|
||||
"DDR": {
|
||||
"mode": "Master",
|
||||
"vlnv": "xilinx.com:interface:ddrx_rtl:1.0",
|
||||
"parameters": {
|
||||
"AXI_ARBITRATION_SCHEME": {
|
||||
"value": "TDM",
|
||||
"value_src": "default"
|
||||
},
|
||||
"BURST_LENGTH": {
|
||||
"value": "8",
|
||||
"value_src": "default"
|
||||
},
|
||||
"CAN_DEBUG": {
|
||||
"value": "false",
|
||||
"value_src": "default"
|
||||
},
|
||||
"CAS_LATENCY": {
|
||||
"value": "11",
|
||||
"value_src": "default"
|
||||
},
|
||||
"CAS_WRITE_LATENCY": {
|
||||
"value": "11",
|
||||
"value_src": "default"
|
||||
},
|
||||
"CS_ENABLED": {
|
||||
"value": "true",
|
||||
"value_src": "default"
|
||||
},
|
||||
"DATA_MASK_ENABLED": {
|
||||
"value": "true",
|
||||
"value_src": "default"
|
||||
},
|
||||
"DATA_WIDTH": {
|
||||
"value": "8",
|
||||
"value_src": "default"
|
||||
},
|
||||
"MEMORY_TYPE": {
|
||||
"value": "COMPONENTS",
|
||||
"value_src": "default"
|
||||
},
|
||||
"MEM_ADDR_MAP": {
|
||||
"value": "ROW_COLUMN_BANK",
|
||||
"value_src": "default"
|
||||
},
|
||||
"SLOT": {
|
||||
"value": "Single",
|
||||
"value_src": "default"
|
||||
},
|
||||
"TIMEPERIOD_PS": {
|
||||
"value": "1250",
|
||||
"value_src": "default"
|
||||
}
|
||||
}
|
||||
},
|
||||
"FIXED_IO": {
|
||||
"mode": "Master",
|
||||
"vlnv": "xilinx.com:display_processing_system7:fixedio_rtl:1.0",
|
||||
"parameters": {
|
||||
"CAN_DEBUG": {
|
||||
"value": "false",
|
||||
"value_src": "default"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"processing_system7_0": {
|
||||
"vlnv": "xilinx.com:ip:processing_system7:5.5",
|
||||
"xci_name": "zynq_default_processing_system7_0_1",
|
||||
"parameters": {
|
||||
"PCW_ACT_APU_PERIPHERAL_FREQMHZ": {
|
||||
"value": "666.666687"
|
||||
},
|
||||
"PCW_ACT_CAN_PERIPHERAL_FREQMHZ": {
|
||||
"value": "10.000000"
|
||||
},
|
||||
"PCW_ACT_DCI_PERIPHERAL_FREQMHZ": {
|
||||
"value": "10.158730"
|
||||
},
|
||||
"PCW_ACT_ENET0_PERIPHERAL_FREQMHZ": {
|
||||
"value": "125.000000"
|
||||
},
|
||||
"PCW_ACT_ENET1_PERIPHERAL_FREQMHZ": {
|
||||
"value": "10.000000"
|
||||
},
|
||||
"PCW_ACT_FPGA0_PERIPHERAL_FREQMHZ": {
|
||||
"value": "10.000000"
|
||||
},
|
||||
"PCW_ACT_FPGA1_PERIPHERAL_FREQMHZ": {
|
||||
"value": "10.000000"
|
||||
},
|
||||
"PCW_ACT_FPGA2_PERIPHERAL_FREQMHZ": {
|
||||
"value": "10.000000"
|
||||
},
|
||||
"PCW_ACT_FPGA3_PERIPHERAL_FREQMHZ": {
|
||||
"value": "10.000000"
|
||||
},
|
||||
"PCW_ACT_PCAP_PERIPHERAL_FREQMHZ": {
|
||||
"value": "200.000000"
|
||||
},
|
||||
"PCW_ACT_QSPI_PERIPHERAL_FREQMHZ": {
|
||||
"value": "200.000000"
|
||||
},
|
||||
"PCW_ACT_SDIO_PERIPHERAL_FREQMHZ": {
|
||||
"value": "100.000000"
|
||||
},
|
||||
"PCW_ACT_SMC_PERIPHERAL_FREQMHZ": {
|
||||
"value": "10.000000"
|
||||
},
|
||||
"PCW_ACT_SPI_PERIPHERAL_FREQMHZ": {
|
||||
"value": "10.000000"
|
||||
},
|
||||
"PCW_ACT_TPIU_PERIPHERAL_FREQMHZ": {
|
||||
"value": "200.000000"
|
||||
},
|
||||
"PCW_ACT_TTC0_CLK0_PERIPHERAL_FREQMHZ": {
|
||||
"value": "111.111115"
|
||||
},
|
||||
"PCW_ACT_TTC0_CLK1_PERIPHERAL_FREQMHZ": {
|
||||
"value": "111.111115"
|
||||
},
|
||||
"PCW_ACT_TTC0_CLK2_PERIPHERAL_FREQMHZ": {
|
||||
"value": "111.111115"
|
||||
},
|
||||
"PCW_ACT_TTC1_CLK0_PERIPHERAL_FREQMHZ": {
|
||||
"value": "111.111115"
|
||||
},
|
||||
"PCW_ACT_TTC1_CLK1_PERIPHERAL_FREQMHZ": {
|
||||
"value": "111.111115"
|
||||
},
|
||||
"PCW_ACT_TTC1_CLK2_PERIPHERAL_FREQMHZ": {
|
||||
"value": "111.111115"
|
||||
},
|
||||
"PCW_ACT_UART_PERIPHERAL_FREQMHZ": {
|
||||
"value": "100.000000"
|
||||
},
|
||||
"PCW_ACT_WDT_PERIPHERAL_FREQMHZ": {
|
||||
"value": "111.111115"
|
||||
},
|
||||
"PCW_CLK0_FREQ": {
|
||||
"value": "10000000"
|
||||
},
|
||||
"PCW_CLK1_FREQ": {
|
||||
"value": "10000000"
|
||||
},
|
||||
"PCW_CLK2_FREQ": {
|
||||
"value": "10000000"
|
||||
},
|
||||
"PCW_CLK3_FREQ": {
|
||||
"value": "10000000"
|
||||
},
|
||||
"PCW_DDR_RAM_HIGHADDR": {
|
||||
"value": "0x3FFFFFFF"
|
||||
},
|
||||
"PCW_ENET0_ENET0_IO": {
|
||||
"value": "MIO 16 .. 27"
|
||||
},
|
||||
"PCW_ENET0_GRP_MDIO_ENABLE": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_ENET0_GRP_MDIO_IO": {
|
||||
"value": "MIO 52 .. 53"
|
||||
},
|
||||
"PCW_ENET0_PERIPHERAL_CLKSRC": {
|
||||
"value": "IO PLL"
|
||||
},
|
||||
"PCW_ENET0_PERIPHERAL_ENABLE": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_ENET0_PERIPHERAL_FREQMHZ": {
|
||||
"value": "1000 Mbps"
|
||||
},
|
||||
"PCW_ENET0_RESET_ENABLE": {
|
||||
"value": "0"
|
||||
},
|
||||
"PCW_ENET_RESET_ENABLE": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_ENET_RESET_SELECT": {
|
||||
"value": "Share reset pin"
|
||||
},
|
||||
"PCW_EN_CLK0_PORT": {
|
||||
"value": "0"
|
||||
},
|
||||
"PCW_EN_CLKTRIG0_PORT": {
|
||||
"value": "0"
|
||||
},
|
||||
"PCW_EN_EMIO_ENET0": {
|
||||
"value": "0"
|
||||
},
|
||||
"PCW_EN_EMIO_GPIO": {
|
||||
"value": "0"
|
||||
},
|
||||
"PCW_EN_EMIO_UART0": {
|
||||
"value": "0"
|
||||
},
|
||||
"PCW_EN_ENET0": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_EN_GPIO": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_EN_QSPI": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_EN_RST0_PORT": {
|
||||
"value": "0"
|
||||
},
|
||||
"PCW_EN_SDIO0": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_EN_UART0": {
|
||||
"value": "0"
|
||||
},
|
||||
"PCW_EN_UART1": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_EN_USB0": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_GPIO_EMIO_GPIO_ENABLE": {
|
||||
"value": "0"
|
||||
},
|
||||
"PCW_GPIO_MIO_GPIO_ENABLE": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_GPIO_MIO_GPIO_IO": {
|
||||
"value": "MIO"
|
||||
},
|
||||
"PCW_I2C_RESET_ENABLE": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_MIO_0_IOTYPE": {
|
||||
"value": "LVCMOS 3.3V"
|
||||
},
|
||||
"PCW_MIO_0_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_0_SLEW": {
|
||||
"value": "slow"
|
||||
},
|
||||
"PCW_MIO_10_IOTYPE": {
|
||||
"value": "LVCMOS 3.3V"
|
||||
},
|
||||
"PCW_MIO_10_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_10_SLEW": {
|
||||
"value": "slow"
|
||||
},
|
||||
"PCW_MIO_11_IOTYPE": {
|
||||
"value": "LVCMOS 3.3V"
|
||||
},
|
||||
"PCW_MIO_11_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_11_SLEW": {
|
||||
"value": "slow"
|
||||
},
|
||||
"PCW_MIO_12_IOTYPE": {
|
||||
"value": "LVCMOS 3.3V"
|
||||
},
|
||||
"PCW_MIO_12_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_12_SLEW": {
|
||||
"value": "slow"
|
||||
},
|
||||
"PCW_MIO_13_IOTYPE": {
|
||||
"value": "LVCMOS 3.3V"
|
||||
},
|
||||
"PCW_MIO_13_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_13_SLEW": {
|
||||
"value": "slow"
|
||||
},
|
||||
"PCW_MIO_14_IOTYPE": {
|
||||
"value": "LVCMOS 3.3V"
|
||||
},
|
||||
"PCW_MIO_14_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_14_SLEW": {
|
||||
"value": "slow"
|
||||
},
|
||||
"PCW_MIO_15_IOTYPE": {
|
||||
"value": "LVCMOS 3.3V"
|
||||
},
|
||||
"PCW_MIO_15_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_15_SLEW": {
|
||||
"value": "slow"
|
||||
},
|
||||
"PCW_MIO_16_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_16_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_16_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_17_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_17_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_17_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_18_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_18_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_18_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_19_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_19_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_19_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_1_IOTYPE": {
|
||||
"value": "LVCMOS 3.3V"
|
||||
},
|
||||
"PCW_MIO_1_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_1_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_20_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_20_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_20_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_21_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_21_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_21_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_22_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_22_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_22_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_23_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_23_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_23_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_24_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_24_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_24_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_25_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_25_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_25_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_26_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_26_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_26_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_27_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_27_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_27_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_28_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_28_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_28_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_29_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_29_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_29_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_2_IOTYPE": {
|
||||
"value": "LVCMOS 3.3V"
|
||||
},
|
||||
"PCW_MIO_2_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_30_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_30_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_30_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_31_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_31_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_31_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_32_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_32_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_32_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_33_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_33_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_33_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_34_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_34_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_34_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_35_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_35_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_35_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_36_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_36_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_36_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_37_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_37_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_37_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_38_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_38_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_38_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_39_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_39_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_39_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_3_IOTYPE": {
|
||||
"value": "LVCMOS 3.3V"
|
||||
},
|
||||
"PCW_MIO_3_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_40_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_40_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_40_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_41_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_41_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_41_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_42_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_42_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_42_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_43_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_43_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_43_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_44_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_44_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_44_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_45_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_45_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_45_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_46_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_46_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_46_SLEW": {
|
||||
"value": "slow"
|
||||
},
|
||||
"PCW_MIO_47_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_47_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_47_SLEW": {
|
||||
"value": "slow"
|
||||
},
|
||||
"PCW_MIO_48_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_48_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_48_SLEW": {
|
||||
"value": "slow"
|
||||
},
|
||||
"PCW_MIO_49_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_49_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_49_SLEW": {
|
||||
"value": "slow"
|
||||
},
|
||||
"PCW_MIO_4_IOTYPE": {
|
||||
"value": "LVCMOS 3.3V"
|
||||
},
|
||||
"PCW_MIO_4_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_50_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_50_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_50_SLEW": {
|
||||
"value": "slow"
|
||||
},
|
||||
"PCW_MIO_51_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_51_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_51_SLEW": {
|
||||
"value": "slow"
|
||||
},
|
||||
"PCW_MIO_52_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_52_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_52_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_53_IOTYPE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_MIO_53_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_53_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_5_IOTYPE": {
|
||||
"value": "LVCMOS 3.3V"
|
||||
},
|
||||
"PCW_MIO_5_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_6_IOTYPE": {
|
||||
"value": "LVCMOS 3.3V"
|
||||
},
|
||||
"PCW_MIO_6_SLEW": {
|
||||
"value": "fast"
|
||||
},
|
||||
"PCW_MIO_7_IOTYPE": {
|
||||
"value": "LVCMOS 3.3V"
|
||||
},
|
||||
"PCW_MIO_7_SLEW": {
|
||||
"value": "slow"
|
||||
},
|
||||
"PCW_MIO_8_IOTYPE": {
|
||||
"value": "LVCMOS 3.3V"
|
||||
},
|
||||
"PCW_MIO_8_SLEW": {
|
||||
"value": "slow"
|
||||
},
|
||||
"PCW_MIO_9_IOTYPE": {
|
||||
"value": "LVCMOS 3.3V"
|
||||
},
|
||||
"PCW_MIO_9_PULLUP": {
|
||||
"value": "enabled"
|
||||
},
|
||||
"PCW_MIO_9_SLEW": {
|
||||
"value": "slow"
|
||||
},
|
||||
"PCW_MIO_TREE_PERIPHERALS": {
|
||||
"value": "GPIO#Quad SPI Flash#Quad SPI Flash#Quad SPI Flash#GPIO#Quad SPI Flash#Quad SPI Flash#GPIO#GPIO#GPIO#GPIO#GPIO#GPIO#GPIO#GPIO#GPIO#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#Enet 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#USB 0#SD 0#SD 0#SD 0#SD 0#SD 0#SD 0#USB Reset#GPIO#UART 1#UART 1#GPIO#GPIO#Enet 0#Enet 0"
|
||||
},
|
||||
"PCW_MIO_TREE_SIGNALS": {
|
||||
"value": "gpio[0]#qspi0_ss_b#qspi0_io[0]#qspi0_io[1]#gpio[4]#qspi0_io[3]/HOLD_B#qspi0_sclk#gpio[7]#gpio[8]#gpio[9]#gpio[10]#gpio[11]#gpio[12]#gpio[13]#gpio[14]#gpio[15]#tx_clk#txd[0]#txd[1]#txd[2]#txd[3]#tx_ctl#rx_clk#rxd[0]#rxd[1]#rxd[2]#rxd[3]#rx_ctl#data[4]#dir#stp#nxt#data[0]#data[1]#data[2]#data[3]#clk#data[5]#data[6]#data[7]#clk#cmd#data[0]#data[1]#data[2]#data[3]#reset#gpio[47]#tx#rx#gpio[50]#gpio[51]#mdc#mdio"
|
||||
},
|
||||
"PCW_PRESET_BANK1_VOLTAGE": {
|
||||
"value": "LVCMOS 1.8V"
|
||||
},
|
||||
"PCW_QSPI_GRP_FBCLK_ENABLE": {
|
||||
"value": "0"
|
||||
},
|
||||
"PCW_QSPI_GRP_IO1_ENABLE": {
|
||||
"value": "0"
|
||||
},
|
||||
"PCW_QSPI_GRP_SINGLE_SS_ENABLE": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_QSPI_GRP_SINGLE_SS_IO": {
|
||||
"value": "MIO 1 .. 6"
|
||||
},
|
||||
"PCW_QSPI_GRP_SS1_ENABLE": {
|
||||
"value": "0"
|
||||
},
|
||||
"PCW_QSPI_PERIPHERAL_ENABLE": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_QSPI_PERIPHERAL_FREQMHZ": {
|
||||
"value": "200"
|
||||
},
|
||||
"PCW_QSPI_QSPI_IO": {
|
||||
"value": "MIO 1 .. 6"
|
||||
},
|
||||
"PCW_SD0_GRP_CD_ENABLE": {
|
||||
"value": "0"
|
||||
},
|
||||
"PCW_SD0_GRP_POW_ENABLE": {
|
||||
"value": "0"
|
||||
},
|
||||
"PCW_SD0_GRP_WP_ENABLE": {
|
||||
"value": "0"
|
||||
},
|
||||
"PCW_SD0_PERIPHERAL_ENABLE": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_SD0_SD0_IO": {
|
||||
"value": "MIO 40 .. 45"
|
||||
},
|
||||
"PCW_SDIO_PERIPHERAL_FREQMHZ": {
|
||||
"value": "100"
|
||||
},
|
||||
"PCW_SDIO_PERIPHERAL_VALID": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_SINGLE_QSPI_DATA_MODE": {
|
||||
"value": "x1"
|
||||
},
|
||||
"PCW_UART0_PERIPHERAL_ENABLE": {
|
||||
"value": "0"
|
||||
},
|
||||
"PCW_UART1_GRP_FULL_ENABLE": {
|
||||
"value": "0"
|
||||
},
|
||||
"PCW_UART1_PERIPHERAL_ENABLE": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_UART1_UART1_IO": {
|
||||
"value": "MIO 48 .. 49"
|
||||
},
|
||||
"PCW_UART_PERIPHERAL_FREQMHZ": {
|
||||
"value": "100"
|
||||
},
|
||||
"PCW_UART_PERIPHERAL_VALID": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_UIPARAM_ACT_DDR_FREQ_MHZ": {
|
||||
"value": "533.333374"
|
||||
},
|
||||
"PCW_UIPARAM_DDR_PARTNO": {
|
||||
"value": "MT41J256M16 RE-125"
|
||||
},
|
||||
"PCW_USB0_PERIPHERAL_ENABLE": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_USB0_RESET_ENABLE": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_USB0_RESET_IO": {
|
||||
"value": "MIO 46"
|
||||
},
|
||||
"PCW_USB0_USB0_IO": {
|
||||
"value": "MIO 28 .. 39"
|
||||
},
|
||||
"PCW_USB_RESET_ENABLE": {
|
||||
"value": "1"
|
||||
},
|
||||
"PCW_USB_RESET_SELECT": {
|
||||
"value": "Share reset pin"
|
||||
},
|
||||
"PCW_USE_M_AXI_GP0": {
|
||||
"value": "0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"interface_nets": {
|
||||
"processing_system7_0_FIXED_IO": {
|
||||
"interface_ports": [
|
||||
"FIXED_IO",
|
||||
"processing_system7_0/FIXED_IO"
|
||||
]
|
||||
},
|
||||
"processing_system7_0_DDR": {
|
||||
"interface_ports": [
|
||||
"DDR",
|
||||
"processing_system7_0/DDR"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
BIN
lib/common/Apply/DSP/Advance/AGC/AGC.PNG
Normal file
BIN
lib/common/Apply/DSP/Advance/AGC/AGC.PNG
Normal file
Binary file not shown.
After Width: | Height: | Size: 142 KiB |
33
lib/common/Apply/DSP/Advance/AGC/AGC.v
Normal file
33
lib/common/Apply/DSP/Advance/AGC/AGC.v
Normal file
@ -0,0 +1,33 @@
|
||||
module AGC(
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
input wire [7:0] a_coef,
|
||||
input wire [15:0] reference,
|
||||
input wire signed [15:0] x_in,
|
||||
output wire signed [15:0] y_out
|
||||
);
|
||||
|
||||
wire [31:0] x_mod;
|
||||
wire [31:0] ref_rms;
|
||||
wire signed [8:0] a_coef_s;
|
||||
wire signed [32:0] tmp_level;
|
||||
wire signed [32:0] feedback_level;
|
||||
reg signed [32:0] zreg;
|
||||
|
||||
assign ref_rms = (reference[15:1] * reference[15:1]);
|
||||
assign a_coef_s = { 1'b0, a_coef};
|
||||
|
||||
assign x_mod = (y_out * y_out);
|
||||
assign tmp_level = ($signed(ref_rms - x_mod))>>>18;
|
||||
assign feedback_level = (tmp_level * a_coef_s) >>> 8;
|
||||
|
||||
always @(posedge clk or negedge rst) begin
|
||||
if (!rst)
|
||||
zreg <= 'h0;
|
||||
else
|
||||
zreg <= zreg + feedback_level;
|
||||
end
|
||||
|
||||
assign y_out = (zreg * x_in) >>>16;
|
||||
|
||||
endmodule
|
@ -0,0 +1,72 @@
|
||||
module Demodulate #(
|
||||
parameter PHASE_WIDTH = 32,
|
||||
parameter Fiter_WIDTH = 38,
|
||||
parameter INPUT_WIDTH = 8,
|
||||
parameter OUTPUT_WIDTH = 12
|
||||
) (
|
||||
input clk,
|
||||
input RST,
|
||||
|
||||
input [15:0] FACTOR,
|
||||
input [PHASE_WIDTH-1:0] Fre_word,
|
||||
|
||||
input [INPUT_WIDTH-1:0] wave_in,
|
||||
|
||||
output [OUTPUT_WIDTH-1:0] FM_Demodule_OUT,
|
||||
output [OUTPUT_WIDTH-1:0] PM_Demodule_OUT,
|
||||
output [OUTPUT_WIDTH-1:0] AM_Demodule_OUT
|
||||
);
|
||||
|
||||
// IQ_MIXED Outputs
|
||||
wire clk_out;
|
||||
wire [OUTPUT_WIDTH - 1 : 0] I_OUT;
|
||||
wire [OUTPUT_WIDTH - 1 : 0] Q_OUT;
|
||||
|
||||
/*
|
||||
数字下变频处理模块
|
||||
*/
|
||||
IQ_MIXED #(
|
||||
.LO_WIDTH ( 12 ),
|
||||
.PHASE_WIDTH ( PHASE_WIDTH ),
|
||||
.Fiter_WIDTH ( Fiter_WIDTH ),
|
||||
.INPUT_WIDTH ( INPUT_WIDTH ),
|
||||
.OUTPUT_WIDTH ( OUTPUT_WIDTH ))
|
||||
u_IQ_MIXED (
|
||||
.clk ( clk ),
|
||||
.clk_out ( clk_out ),
|
||||
.RST ( RST ),
|
||||
|
||||
.FACTOR ( FACTOR ),
|
||||
.Fre_word ( Fre_word ),
|
||||
|
||||
.wave_in ( wave_in ),
|
||||
.I_OUT ( I_OUT ),
|
||||
.Q_OUT ( Q_OUT )
|
||||
);
|
||||
|
||||
wire [OUTPUT_WIDTH-1:0] Y_diff;
|
||||
Cordic # (
|
||||
.XY_BITS(OUTPUT_WIDTH),
|
||||
.PH_BITS(OUTPUT_WIDTH), //1~32
|
||||
.ITERATIONS(16), //1~32
|
||||
.CORDIC_STYLE("VECTOR")) //ROTATE //VECTOR
|
||||
Demodulate_Gen_u (
|
||||
.clk(clk_out),
|
||||
.RST(RST),
|
||||
.x_i(I_OUT),
|
||||
.y_i(Q_OUT),
|
||||
.phase_in(0),
|
||||
.valid_in(~RST),
|
||||
|
||||
.x_o(AM_Demodule_OUT),
|
||||
.y_o(Y_diff),
|
||||
.phase_out(PM_Demodule_OUT)
|
||||
);
|
||||
|
||||
reg [OUTPUT_WIDTH-1:0] PM_Demodule_OUT_r = 0;
|
||||
always @(posedge clk_out) begin
|
||||
PM_Demodule_OUT_r <= PM_Demodule_OUT;
|
||||
end
|
||||
assign FM_Demodule_OUT = $signed(PM_Demodule_OUT) - $signed(PM_Demodule_OUT_r);
|
||||
|
||||
endmodule
|
@ -0,0 +1,92 @@
|
||||
module IQ_MIXED #(
|
||||
//LO_OUTPUR_parameter
|
||||
parameter LO_WIDTH = 12,
|
||||
parameter PHASE_WIDTH = 32,
|
||||
//CIC_Filter_parameter
|
||||
parameter Fiter_WIDTH = 38,
|
||||
//IQ_MIXED_parameter
|
||||
parameter INPUT_WIDTH = 12,
|
||||
parameter OUTPUT_WIDTH = 12
|
||||
) (
|
||||
input clk,
|
||||
output clk_out,
|
||||
input RST,
|
||||
|
||||
input [15:0] FACTOR,
|
||||
input [PHASE_WIDTH - 1 : 0] Fre_word,
|
||||
|
||||
input [INPUT_WIDTH - 1 : 0] wave_in,
|
||||
output [OUTPUT_WIDTH - 1 : 0] I_OUT,
|
||||
output [OUTPUT_WIDTH - 1 : 0] Q_OUT
|
||||
);
|
||||
|
||||
wire [LO_WIDTH-1:0] cos_wave;
|
||||
wire [LO_WIDTH-1:0] sin_wave;
|
||||
wire [PHASE_WIDTH-1:0] pha_diff;
|
||||
Cordic # (
|
||||
.XY_BITS(LO_WIDTH),
|
||||
.PH_BITS(PHASE_WIDTH), //1~32
|
||||
.ITERATIONS(16), //1~32
|
||||
.CORDIC_STYLE("ROTATE"), //ROTATE //VECTOR
|
||||
.PHASE_ACC("ON") //ON //OFF
|
||||
) IQ_Gen_u (
|
||||
.clk(clk),
|
||||
.RST(RST),
|
||||
.x_i(0),
|
||||
.y_i(0),
|
||||
.phase_in(Fre_word),
|
||||
.valid_in(~RST),
|
||||
|
||||
.x_o(cos_wave),
|
||||
.y_o(sin_wave),
|
||||
.phase_out(pha_diff)
|
||||
);
|
||||
|
||||
wire signed [Fiter_WIDTH - 1 : 0] I_SIG;
|
||||
wire signed [Fiter_WIDTH - 1 : 0] Q_SIG;
|
||||
reg signed [INPUT_WIDTH + LO_WIDTH - 1 : 0] I_SIG_r = 0;
|
||||
reg signed [INPUT_WIDTH + LO_WIDTH - 1 : 0] Q_SIG_r = 0;
|
||||
always @(posedge clk) begin
|
||||
if (RST) begin
|
||||
I_SIG_r <= 24'd0;
|
||||
Q_SIG_r <= 24'd0;
|
||||
end
|
||||
else begin
|
||||
I_SIG_r <= $signed(wave_in) * $signed(cos_wave);
|
||||
Q_SIG_r <= $signed(wave_in) * $signed(sin_wave);
|
||||
end
|
||||
end
|
||||
assign I_SIG = I_SIG_r[INPUT_WIDTH + LO_WIDTH - 1 : INPUT_WIDTH + LO_WIDTH - 12];
|
||||
assign Q_SIG = Q_SIG_r[INPUT_WIDTH + LO_WIDTH - 1 : INPUT_WIDTH + LO_WIDTH - 12];
|
||||
|
||||
|
||||
wire [Fiter_WIDTH-1:0] Fiter_wave_I;
|
||||
CIC_DOWN_S3#(
|
||||
.INPUT_WIDTH(12),
|
||||
.OUTPUT_WIDTH(Fiter_WIDTH))
|
||||
Fiter_I (
|
||||
.clk(clk),
|
||||
.clk_enable(1'd1),
|
||||
.reset(RST),
|
||||
.FACTOR(FACTOR),
|
||||
.filter_in(I_SIG),
|
||||
.filter_out(Fiter_wave_I)
|
||||
);
|
||||
assign I_OUT = Fiter_wave_I[Fiter_WIDTH - 1 : Fiter_WIDTH - OUTPUT_WIDTH];
|
||||
|
||||
wire [Fiter_WIDTH-1:0] Fiter_wave_Q;
|
||||
CIC_DOWN_S3#(
|
||||
.INPUT_WIDTH(12),
|
||||
.OUTPUT_WIDTH(Fiter_WIDTH)
|
||||
) Fiter_Q(
|
||||
.clk(clk),
|
||||
.clk_enable(1'd1),
|
||||
.reset(RST),
|
||||
.FACTOR(FACTOR),
|
||||
.filter_in(Q_SIG),
|
||||
.filter_out(Fiter_wave_Q),
|
||||
.ce_out(clk_out)
|
||||
);
|
||||
assign Q_OUT = Fiter_wave_Q[Fiter_WIDTH - 1 : Fiter_WIDTH - OUTPUT_WIDTH];
|
||||
|
||||
endmodule
|
@ -0,0 +1,32 @@
|
||||
`timescale 1ns / 1ps
|
||||
module Loop_filter (
|
||||
input clk_sys,
|
||||
input rst_n,
|
||||
input signed [27:0] Xdin,
|
||||
output signed [27:0] Ydout
|
||||
);
|
||||
|
||||
parameter k1 = 12498;
|
||||
parameter k2 = 4430400;
|
||||
|
||||
reg [2:0] cnt;
|
||||
reg signed [27:0] Ydin_1;
|
||||
reg signed [27:0] Ydout_buf;
|
||||
always@(posedge clk_sys) begin
|
||||
if(!rst_n)
|
||||
cnt <= 3'd0;
|
||||
else
|
||||
cnt <= cnt + 3'd1;
|
||||
end
|
||||
always@(posedge clk_sys) begin
|
||||
if(!rst_n) begin
|
||||
Ydin_1 <= 28'd0;
|
||||
Ydout_buf <= 28'd0;
|
||||
end
|
||||
else if(cnt == 3'd3)
|
||||
Ydin_1 = Ydin_1 + Xdin/k1;
|
||||
else if(cnt == 3'd4)
|
||||
Ydout_buf <= Ydin_1 + Xdin/k2;
|
||||
end
|
||||
assign Ydout = Ydout_buf;
|
||||
endmodule
|
17
lib/common/Apply/DSP/Advance/Communicate/Encode/manchester.v
Normal file
17
lib/common/Apply/DSP/Advance/Communicate/Encode/manchester.v
Normal file
@ -0,0 +1,17 @@
|
||||
`timescale 1ns / 1ps
|
||||
module manchester (
|
||||
input clk,
|
||||
input sig_in,
|
||||
output man_sig_out
|
||||
);
|
||||
|
||||
reg ck = 0;
|
||||
reg ck_r = 0;
|
||||
always @(posedge clk) begin
|
||||
ck <= ck_r;
|
||||
ck <= ~ ck;
|
||||
end
|
||||
|
||||
assign man_sig_out = ck ^ sig_in;
|
||||
|
||||
endmodule
|
25
lib/common/Apply/DSP/Advance/Communicate/Encode/mseq.v
Normal file
25
lib/common/Apply/DSP/Advance/Communicate/Encode/mseq.v
Normal file
@ -0,0 +1,25 @@
|
||||
`timescale 1ns / 1ps
|
||||
module mseq #(
|
||||
parameter W = 4'd4,
|
||||
parameter POLY = 5'b10011
|
||||
) (
|
||||
input clk,
|
||||
input rst_n,
|
||||
output mseq_out
|
||||
);
|
||||
|
||||
reg [W-1:0] sreg = 8'b11111111;
|
||||
assign mseq_out = sreg[0];
|
||||
|
||||
always@(posedge clk or posedge rst_n) begin
|
||||
if(~rst_n)
|
||||
sreg <= 1'b1;
|
||||
else begin
|
||||
if(mseq_out)
|
||||
sreg <= (sreg >> 1) ^ (POLY >> 1);
|
||||
else
|
||||
sreg <= sreg >> 1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -0,0 +1,383 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module AM_Modulate #(
|
||||
parameter INPUT_WIDTH = 12,
|
||||
parameter PHASE_WIDTH = 32,
|
||||
parameter DEEP_WIDTH = 16,
|
||||
parameter OUTPUT_WIDTH = 12
|
||||
) (
|
||||
input clk,
|
||||
input RST,
|
||||
input [INPUT_WIDTH - 1 : 0] wave_in,
|
||||
input [PHASE_WIDTH - 1 : 0] center_fre, //(fre*2^PHASE_WIDTH)/Fc
|
||||
input [DEEP_WIDTH - 1 : 0] modulate_deep,//(2^DEEP_WIDTH-1)*percent
|
||||
output [OUTPUT_WIDTH - 1 : 0] AM_wave
|
||||
);
|
||||
|
||||
localparam [INPUT_WIDTH - 1 : 0] DC_Value = 2**(INPUT_WIDTH-1);
|
||||
|
||||
reg [INPUT_WIDTH - 1 : 0] wave_in_r = 0;
|
||||
always @(posedge clk) begin
|
||||
if (RST) begin
|
||||
wave_in_r <= 0;
|
||||
end
|
||||
else begin
|
||||
wave_in_r <= wave_in;
|
||||
end
|
||||
end
|
||||
|
||||
reg signed [INPUT_WIDTH + DEEP_WIDTH : 0] data_r0 = 0;
|
||||
always @(posedge clk) begin
|
||||
if (RST) begin
|
||||
data_r0 <= 0;
|
||||
end
|
||||
else begin
|
||||
data_r0 <= $signed(wave_in_r) * $signed({1'b0,modulate_deep});
|
||||
end
|
||||
end
|
||||
|
||||
reg signed [INPUT_WIDTH - 1 : 0] data_r1 = 0;
|
||||
always @(posedge clk) begin
|
||||
if (RST) begin
|
||||
data_r1 <= 0;
|
||||
end
|
||||
else begin
|
||||
data_r1 <= data_r0[INPUT_WIDTH + DEEP_WIDTH - 1 : DEEP_WIDTH];
|
||||
end
|
||||
end
|
||||
|
||||
reg [INPUT_WIDTH : 0] data_r2 = 0;
|
||||
always @(posedge clk) begin
|
||||
if (RST) begin
|
||||
data_r2 <= 0;
|
||||
end
|
||||
else begin
|
||||
data_r2 <= $signed(data_r1) + $signed({1'b0,DC_Value});
|
||||
end
|
||||
end
|
||||
|
||||
reg [PHASE_WIDTH - 1 : 0] addr_r0 = 0;
|
||||
always @(posedge clk) begin
|
||||
addr_r0 <= addr_r0 + center_fre;
|
||||
end
|
||||
|
||||
reg [9:0] addr_r1 = 0;
|
||||
always @(posedge clk) begin
|
||||
addr_r1 <= addr_r0[PHASE_WIDTH - 1 : PHASE_WIDTH - 10];
|
||||
end
|
||||
|
||||
reg [7:0] addr = 0;
|
||||
always @(*) begin
|
||||
case (addr_r1[9:8])
|
||||
2'b00 : begin addr <= addr_r1[7:0]; end
|
||||
2'b01 : begin addr <= addr_r1[7:0] ^ 8'b1111_1111; end
|
||||
2'b10 : begin addr <= addr_r1[7:0]; end
|
||||
2'b11 : begin addr <= addr_r1[7:0] ^ 8'b1111_1111; end
|
||||
default : begin addr <= 8'd0; end
|
||||
endcase
|
||||
end
|
||||
|
||||
reg signed [13:0] wave_out_r = 0;
|
||||
always @(*) begin
|
||||
case (addr)
|
||||
8'd0 : begin wave_out_r <= 0; end
|
||||
8'd1 : begin wave_out_r <= 50; end
|
||||
8'd2 : begin wave_out_r <= 101; end
|
||||
8'd3 : begin wave_out_r <= 151; end
|
||||
8'd4 : begin wave_out_r <= 201; end
|
||||
8'd5 : begin wave_out_r <= 252; end
|
||||
8'd6 : begin wave_out_r <= 302; end
|
||||
8'd7 : begin wave_out_r <= 352; end
|
||||
8'd8 : begin wave_out_r <= 402; end
|
||||
8'd9 : begin wave_out_r <= 453; end
|
||||
8'd10 : begin wave_out_r <= 503; end
|
||||
8'd11 : begin wave_out_r <= 553; end
|
||||
8'd12 : begin wave_out_r <= 603; end
|
||||
8'd13 : begin wave_out_r <= 653; end
|
||||
8'd14 : begin wave_out_r <= 703; end
|
||||
8'd15 : begin wave_out_r <= 754; end
|
||||
8'd16 : begin wave_out_r <= 804; end
|
||||
8'd17 : begin wave_out_r <= 854; end
|
||||
8'd18 : begin wave_out_r <= 904; end
|
||||
8'd19 : begin wave_out_r <= 954; end
|
||||
8'd20 : begin wave_out_r <= 1004; end
|
||||
8'd21 : begin wave_out_r <= 1054; end
|
||||
8'd22 : begin wave_out_r <= 1103; end
|
||||
8'd23 : begin wave_out_r <= 1153; end
|
||||
8'd24 : begin wave_out_r <= 1203; end
|
||||
8'd25 : begin wave_out_r <= 1253; end
|
||||
8'd26 : begin wave_out_r <= 1302; end
|
||||
8'd27 : begin wave_out_r <= 1352; end
|
||||
8'd28 : begin wave_out_r <= 1402; end
|
||||
8'd29 : begin wave_out_r <= 1451; end
|
||||
8'd30 : begin wave_out_r <= 1501; end
|
||||
8'd31 : begin wave_out_r <= 1550; end
|
||||
8'd32 : begin wave_out_r <= 1600; end
|
||||
8'd33 : begin wave_out_r <= 1649; end
|
||||
8'd34 : begin wave_out_r <= 1698; end
|
||||
8'd35 : begin wave_out_r <= 1747; end
|
||||
8'd36 : begin wave_out_r <= 1796; end
|
||||
8'd37 : begin wave_out_r <= 1845; end
|
||||
8'd38 : begin wave_out_r <= 1894; end
|
||||
8'd39 : begin wave_out_r <= 1943; end
|
||||
8'd40 : begin wave_out_r <= 1992; end
|
||||
8'd41 : begin wave_out_r <= 2041; end
|
||||
8'd42 : begin wave_out_r <= 2090; end
|
||||
8'd43 : begin wave_out_r <= 2138; end
|
||||
8'd44 : begin wave_out_r <= 2187; end
|
||||
8'd45 : begin wave_out_r <= 2235; end
|
||||
8'd46 : begin wave_out_r <= 2284; end
|
||||
8'd47 : begin wave_out_r <= 2332; end
|
||||
8'd48 : begin wave_out_r <= 2380; end
|
||||
8'd49 : begin wave_out_r <= 2428; end
|
||||
8'd50 : begin wave_out_r <= 2476; end
|
||||
8'd51 : begin wave_out_r <= 2524; end
|
||||
8'd52 : begin wave_out_r <= 2572; end
|
||||
8'd53 : begin wave_out_r <= 2620; end
|
||||
8'd54 : begin wave_out_r <= 2667; end
|
||||
8'd55 : begin wave_out_r <= 2715; end
|
||||
8'd56 : begin wave_out_r <= 2762; end
|
||||
8'd57 : begin wave_out_r <= 2809; end
|
||||
8'd58 : begin wave_out_r <= 2857; end
|
||||
8'd59 : begin wave_out_r <= 2904; end
|
||||
8'd60 : begin wave_out_r <= 2951; end
|
||||
8'd61 : begin wave_out_r <= 2998; end
|
||||
8'd62 : begin wave_out_r <= 3044; end
|
||||
8'd63 : begin wave_out_r <= 3091; end
|
||||
8'd64 : begin wave_out_r <= 3137; end
|
||||
8'd65 : begin wave_out_r <= 3184; end
|
||||
8'd66 : begin wave_out_r <= 3230; end
|
||||
8'd67 : begin wave_out_r <= 3276; end
|
||||
8'd68 : begin wave_out_r <= 3322; end
|
||||
8'd69 : begin wave_out_r <= 3368; end
|
||||
8'd70 : begin wave_out_r <= 3414; end
|
||||
8'd71 : begin wave_out_r <= 3460; end
|
||||
8'd72 : begin wave_out_r <= 3505; end
|
||||
8'd73 : begin wave_out_r <= 3551; end
|
||||
8'd74 : begin wave_out_r <= 3596; end
|
||||
8'd75 : begin wave_out_r <= 3641; end
|
||||
8'd76 : begin wave_out_r <= 3686; end
|
||||
8'd77 : begin wave_out_r <= 3731; end
|
||||
8'd78 : begin wave_out_r <= 3776; end
|
||||
8'd79 : begin wave_out_r <= 3820; end
|
||||
8'd80 : begin wave_out_r <= 3865; end
|
||||
8'd81 : begin wave_out_r <= 3909; end
|
||||
8'd82 : begin wave_out_r <= 3953; end
|
||||
8'd83 : begin wave_out_r <= 3997; end
|
||||
8'd84 : begin wave_out_r <= 4041; end
|
||||
8'd85 : begin wave_out_r <= 4085; end
|
||||
8'd86 : begin wave_out_r <= 4128; end
|
||||
8'd87 : begin wave_out_r <= 4172; end
|
||||
8'd88 : begin wave_out_r <= 4215; end
|
||||
8'd89 : begin wave_out_r <= 4258; end
|
||||
8'd90 : begin wave_out_r <= 4301; end
|
||||
8'd91 : begin wave_out_r <= 4343; end
|
||||
8'd92 : begin wave_out_r <= 4386; end
|
||||
8'd93 : begin wave_out_r <= 4428; end
|
||||
8'd94 : begin wave_out_r <= 4471; end
|
||||
8'd95 : begin wave_out_r <= 4513; end
|
||||
8'd96 : begin wave_out_r <= 4555; end
|
||||
8'd97 : begin wave_out_r <= 4596; end
|
||||
8'd98 : begin wave_out_r <= 4638; end
|
||||
8'd99 : begin wave_out_r <= 4679; end
|
||||
8'd100 : begin wave_out_r <= 4720; end
|
||||
8'd101 : begin wave_out_r <= 4761; end
|
||||
8'd102 : begin wave_out_r <= 4802; end
|
||||
8'd103 : begin wave_out_r <= 4843; end
|
||||
8'd104 : begin wave_out_r <= 4883; end
|
||||
8'd105 : begin wave_out_r <= 4924; end
|
||||
8'd106 : begin wave_out_r <= 4964; end
|
||||
8'd107 : begin wave_out_r <= 5004; end
|
||||
8'd108 : begin wave_out_r <= 5044; end
|
||||
8'd109 : begin wave_out_r <= 5083; end
|
||||
8'd110 : begin wave_out_r <= 5122; end
|
||||
8'd111 : begin wave_out_r <= 5162; end
|
||||
8'd112 : begin wave_out_r <= 5201; end
|
||||
8'd113 : begin wave_out_r <= 5239; end
|
||||
8'd114 : begin wave_out_r <= 5278; end
|
||||
8'd115 : begin wave_out_r <= 5316; end
|
||||
8'd116 : begin wave_out_r <= 5354; end
|
||||
8'd117 : begin wave_out_r <= 5392; end
|
||||
8'd118 : begin wave_out_r <= 5430; end
|
||||
8'd119 : begin wave_out_r <= 5468; end
|
||||
8'd120 : begin wave_out_r <= 5505; end
|
||||
8'd121 : begin wave_out_r <= 5542; end
|
||||
8'd122 : begin wave_out_r <= 5579; end
|
||||
8'd123 : begin wave_out_r <= 5616; end
|
||||
8'd124 : begin wave_out_r <= 5652; end
|
||||
8'd125 : begin wave_out_r <= 5689; end
|
||||
8'd126 : begin wave_out_r <= 5725; end
|
||||
8'd127 : begin wave_out_r <= 5761; end
|
||||
8'd128 : begin wave_out_r <= 5796; end
|
||||
8'd129 : begin wave_out_r <= 5832; end
|
||||
8'd130 : begin wave_out_r <= 5867; end
|
||||
8'd131 : begin wave_out_r <= 5902; end
|
||||
8'd132 : begin wave_out_r <= 5937; end
|
||||
8'd133 : begin wave_out_r <= 5971; end
|
||||
8'd134 : begin wave_out_r <= 6006; end
|
||||
8'd135 : begin wave_out_r <= 6040; end
|
||||
8'd136 : begin wave_out_r <= 6074; end
|
||||
8'd137 : begin wave_out_r <= 6107; end
|
||||
8'd138 : begin wave_out_r <= 6141; end
|
||||
8'd139 : begin wave_out_r <= 6174; end
|
||||
8'd140 : begin wave_out_r <= 6207; end
|
||||
8'd141 : begin wave_out_r <= 6239; end
|
||||
8'd142 : begin wave_out_r <= 6272; end
|
||||
8'd143 : begin wave_out_r <= 6304; end
|
||||
8'd144 : begin wave_out_r <= 6336; end
|
||||
8'd145 : begin wave_out_r <= 6368; end
|
||||
8'd146 : begin wave_out_r <= 6399; end
|
||||
8'd147 : begin wave_out_r <= 6431; end
|
||||
8'd148 : begin wave_out_r <= 6462; end
|
||||
8'd149 : begin wave_out_r <= 6493; end
|
||||
8'd150 : begin wave_out_r <= 6523; end
|
||||
8'd151 : begin wave_out_r <= 6553; end
|
||||
8'd152 : begin wave_out_r <= 6584; end
|
||||
8'd153 : begin wave_out_r <= 6613; end
|
||||
8'd154 : begin wave_out_r <= 6643; end
|
||||
8'd155 : begin wave_out_r <= 6672; end
|
||||
8'd156 : begin wave_out_r <= 6701; end
|
||||
8'd157 : begin wave_out_r <= 6730; end
|
||||
8'd158 : begin wave_out_r <= 6759; end
|
||||
8'd159 : begin wave_out_r <= 6787; end
|
||||
8'd160 : begin wave_out_r <= 6815; end
|
||||
8'd161 : begin wave_out_r <= 6843; end
|
||||
8'd162 : begin wave_out_r <= 6870; end
|
||||
8'd163 : begin wave_out_r <= 6897; end
|
||||
8'd164 : begin wave_out_r <= 6925; end
|
||||
8'd165 : begin wave_out_r <= 6951; end
|
||||
8'd166 : begin wave_out_r <= 6978; end
|
||||
8'd167 : begin wave_out_r <= 7004; end
|
||||
8'd168 : begin wave_out_r <= 7030; end
|
||||
8'd169 : begin wave_out_r <= 7056; end
|
||||
8'd170 : begin wave_out_r <= 7081; end
|
||||
8'd171 : begin wave_out_r <= 7106; end
|
||||
8'd172 : begin wave_out_r <= 7131; end
|
||||
8'd173 : begin wave_out_r <= 7156; end
|
||||
8'd174 : begin wave_out_r <= 7180; end
|
||||
8'd175 : begin wave_out_r <= 7204; end
|
||||
8'd176 : begin wave_out_r <= 7228; end
|
||||
8'd177 : begin wave_out_r <= 7251; end
|
||||
8'd178 : begin wave_out_r <= 7275; end
|
||||
8'd179 : begin wave_out_r <= 7298; end
|
||||
8'd180 : begin wave_out_r <= 7320; end
|
||||
8'd181 : begin wave_out_r <= 7343; end
|
||||
8'd182 : begin wave_out_r <= 7365; end
|
||||
8'd183 : begin wave_out_r <= 7387; end
|
||||
8'd184 : begin wave_out_r <= 7408; end
|
||||
8'd185 : begin wave_out_r <= 7430; end
|
||||
8'd186 : begin wave_out_r <= 7451; end
|
||||
8'd187 : begin wave_out_r <= 7472; end
|
||||
8'd188 : begin wave_out_r <= 7492; end
|
||||
8'd189 : begin wave_out_r <= 7512; end
|
||||
8'd190 : begin wave_out_r <= 7532; end
|
||||
8'd191 : begin wave_out_r <= 7552; end
|
||||
8'd192 : begin wave_out_r <= 7571; end
|
||||
8'd193 : begin wave_out_r <= 7590; end
|
||||
8'd194 : begin wave_out_r <= 7609; end
|
||||
8'd195 : begin wave_out_r <= 7627; end
|
||||
8'd196 : begin wave_out_r <= 7646; end
|
||||
8'd197 : begin wave_out_r <= 7664; end
|
||||
8'd198 : begin wave_out_r <= 7681; end
|
||||
8'd199 : begin wave_out_r <= 7698; end
|
||||
8'd200 : begin wave_out_r <= 7715; end
|
||||
8'd201 : begin wave_out_r <= 7732; end
|
||||
8'd202 : begin wave_out_r <= 7749; end
|
||||
8'd203 : begin wave_out_r <= 7765; end
|
||||
8'd204 : begin wave_out_r <= 7781; end
|
||||
8'd205 : begin wave_out_r <= 7796; end
|
||||
8'd206 : begin wave_out_r <= 7812; end
|
||||
8'd207 : begin wave_out_r <= 7827; end
|
||||
8'd208 : begin wave_out_r <= 7841; end
|
||||
8'd209 : begin wave_out_r <= 7856; end
|
||||
8'd210 : begin wave_out_r <= 7870; end
|
||||
8'd211 : begin wave_out_r <= 7884; end
|
||||
8'd212 : begin wave_out_r <= 7897; end
|
||||
8'd213 : begin wave_out_r <= 7910; end
|
||||
8'd214 : begin wave_out_r <= 7923; end
|
||||
8'd215 : begin wave_out_r <= 7936; end
|
||||
8'd216 : begin wave_out_r <= 7948; end
|
||||
8'd217 : begin wave_out_r <= 7960; end
|
||||
8'd218 : begin wave_out_r <= 7972; end
|
||||
8'd219 : begin wave_out_r <= 7983; end
|
||||
8'd220 : begin wave_out_r <= 7994; end
|
||||
8'd221 : begin wave_out_r <= 8005; end
|
||||
8'd222 : begin wave_out_r <= 8016; end
|
||||
8'd223 : begin wave_out_r <= 8026; end
|
||||
8'd224 : begin wave_out_r <= 8036; end
|
||||
8'd225 : begin wave_out_r <= 8045; end
|
||||
8'd226 : begin wave_out_r <= 8055; end
|
||||
8'd227 : begin wave_out_r <= 8064; end
|
||||
8'd228 : begin wave_out_r <= 8072; end
|
||||
8'd229 : begin wave_out_r <= 8081; end
|
||||
8'd230 : begin wave_out_r <= 8089; end
|
||||
8'd231 : begin wave_out_r <= 8097; end
|
||||
8'd232 : begin wave_out_r <= 8104; end
|
||||
8'd233 : begin wave_out_r <= 8111; end
|
||||
8'd234 : begin wave_out_r <= 8118; end
|
||||
8'd235 : begin wave_out_r <= 8125; end
|
||||
8'd236 : begin wave_out_r <= 8131; end
|
||||
8'd237 : begin wave_out_r <= 8137; end
|
||||
8'd238 : begin wave_out_r <= 8142; end
|
||||
8'd239 : begin wave_out_r <= 8148; end
|
||||
8'd240 : begin wave_out_r <= 8153; end
|
||||
8'd241 : begin wave_out_r <= 8157; end
|
||||
8'd242 : begin wave_out_r <= 8162; end
|
||||
8'd243 : begin wave_out_r <= 8166; end
|
||||
8'd244 : begin wave_out_r <= 8170; end
|
||||
8'd245 : begin wave_out_r <= 8173; end
|
||||
8'd246 : begin wave_out_r <= 8176; end
|
||||
8'd247 : begin wave_out_r <= 8179; end
|
||||
8'd248 : begin wave_out_r <= 8182; end
|
||||
8'd249 : begin wave_out_r <= 8184; end
|
||||
8'd250 : begin wave_out_r <= 8186; end
|
||||
8'd251 : begin wave_out_r <= 8188; end
|
||||
8'd252 : begin wave_out_r <= 8189; end
|
||||
8'd253 : begin wave_out_r <= 8190; end
|
||||
8'd254 : begin wave_out_r <= 8191; end
|
||||
8'd255 : begin wave_out_r <= 8191; end
|
||||
default : begin wave_out_r <= 0; end
|
||||
endcase
|
||||
end
|
||||
|
||||
reg signed [13 : 0] AM_Carry_r0 = 0;
|
||||
always @(*) begin
|
||||
case (addr_r1[9])
|
||||
1'b0 : begin AM_Carry_r0 <= wave_out_r[13 : 0]; end
|
||||
1'b1 : begin AM_Carry_r0 <= - wave_out_r[13 : 0]; end
|
||||
default : begin AM_Carry_r0 <= 14'd0; end
|
||||
endcase
|
||||
end
|
||||
|
||||
reg signed [13 : 0] AM_Carry_r1 = 0;
|
||||
always @(posedge clk) begin
|
||||
if (RST) begin
|
||||
AM_Carry_r1 <= 0;
|
||||
end
|
||||
else begin
|
||||
AM_Carry_r1 <= AM_Carry_r0;
|
||||
end
|
||||
end
|
||||
|
||||
reg signed [INPUT_WIDTH + 14 : 0] AM_wave_r0 = 0;
|
||||
always @(posedge clk) begin
|
||||
if (RST) begin
|
||||
AM_wave_r0 <= 0;
|
||||
end
|
||||
else begin
|
||||
AM_wave_r0 <= $signed(AM_Carry_r1) * $signed({1'b0,data_r2});
|
||||
end
|
||||
end
|
||||
|
||||
reg signed [OUTPUT_WIDTH - 1 : 0] AM_wave_r1 = 0;
|
||||
always @(posedge clk) begin
|
||||
if (RST) begin
|
||||
AM_wave_r1 <= 0;
|
||||
end
|
||||
else begin
|
||||
AM_wave_r1 <= AM_wave_r0[INPUT_WIDTH + 13 : INPUT_WIDTH + 14 - OUTPUT_WIDTH];
|
||||
end
|
||||
end
|
||||
assign AM_wave = AM_wave_r1;
|
||||
|
||||
endmodule
|
@ -0,0 +1,370 @@
|
||||
`timescale 1ns / 1ps
|
||||
module FM_Modulate #(
|
||||
parameter INPUT_WIDTH = 12,
|
||||
parameter PHASE_WIDTH = 32,
|
||||
parameter OUTPUT_WIDTH = 12
|
||||
) (
|
||||
input clk,
|
||||
input RST,
|
||||
input [INPUT_WIDTH - 1 : 0] wave_in,
|
||||
input [PHASE_WIDTH - INPUT_WIDTH - 1 : 0] move_fre, //(fre*2^(PHASE_WIDTH-INPUT_WIDTH))/clk/1000000
|
||||
input [PHASE_WIDTH - 1 : 0] center_fre, //(fre*2^PHASE_WIDTH)/clk/1000000
|
||||
output [OUTPUT_WIDTH - 1 : 0] FM_wave
|
||||
);
|
||||
|
||||
reg [INPUT_WIDTH - 1 : 0] wave_in_r = 0;
|
||||
always @(posedge clk) begin
|
||||
if (RST) begin
|
||||
wave_in_r <= 0;
|
||||
end
|
||||
else begin
|
||||
wave_in_r <= wave_in;
|
||||
end
|
||||
end
|
||||
|
||||
reg signed [PHASE_WIDTH : 0] data_r0 = 0;
|
||||
always @(posedge clk) begin
|
||||
if (RST) begin
|
||||
data_r0 <= 0;
|
||||
end
|
||||
else begin
|
||||
data_r0 <= $signed(wave_in_r) * $signed({1'd0,move_fre});
|
||||
end
|
||||
end
|
||||
|
||||
reg signed [PHASE_WIDTH - 1 : 0] data_r1 = 0;
|
||||
always @(posedge clk) begin
|
||||
if (RST) begin
|
||||
data_r1 <= 0;
|
||||
end
|
||||
else begin
|
||||
data_r1 <= data_r0[PHASE_WIDTH - 1 : 0];
|
||||
end
|
||||
end
|
||||
|
||||
reg signed [PHASE_WIDTH : 0] data_r2 = 0;
|
||||
always @(posedge clk) begin
|
||||
if (RST) begin
|
||||
data_r2 <= 0;
|
||||
end
|
||||
else begin
|
||||
data_r2 <= $signed(data_r1) + $signed({1'd0,center_fre});
|
||||
end
|
||||
end
|
||||
|
||||
reg [PHASE_WIDTH - 1 : 0] Fre_word = 0;
|
||||
always @(posedge clk) begin
|
||||
if (RST) begin
|
||||
Fre_word <= 0;
|
||||
end
|
||||
else begin
|
||||
Fre_word <= data_r2[PHASE_WIDTH - 1 : 0];
|
||||
end
|
||||
end
|
||||
|
||||
reg [PHASE_WIDTH - 1 : 0] addr_r0 = 0;
|
||||
always @(posedge clk) begin
|
||||
addr_r0 <= addr_r0 + Fre_word;
|
||||
end
|
||||
|
||||
reg [9:0] addr_r1 = 0;
|
||||
always @(posedge clk) begin
|
||||
addr_r1 <= addr_r0[PHASE_WIDTH - 1 : PHASE_WIDTH - 10];
|
||||
end
|
||||
|
||||
reg [7:0] addr = 0;
|
||||
always @(*) begin
|
||||
case (addr_r1[9:8])
|
||||
2'b00 : begin addr <= addr_r1[7:0]; end
|
||||
2'b01 : begin addr <= addr_r1[7:0] ^ 8'b1111_1111; end
|
||||
2'b10 : begin addr <= addr_r1[7:0]; end
|
||||
2'b11 : begin addr <= addr_r1[7:0] ^ 8'b1111_1111; end
|
||||
default : begin addr <= 8'd0; end
|
||||
endcase
|
||||
end
|
||||
|
||||
reg signed [13:0] wave_out_r = 0;
|
||||
always @(*) begin
|
||||
case (addr)
|
||||
8'd0 : begin wave_out_r <= 0; end
|
||||
8'd1 : begin wave_out_r <= 50; end
|
||||
8'd2 : begin wave_out_r <= 101; end
|
||||
8'd3 : begin wave_out_r <= 151; end
|
||||
8'd4 : begin wave_out_r <= 201; end
|
||||
8'd5 : begin wave_out_r <= 252; end
|
||||
8'd6 : begin wave_out_r <= 302; end
|
||||
8'd7 : begin wave_out_r <= 352; end
|
||||
8'd8 : begin wave_out_r <= 402; end
|
||||
8'd9 : begin wave_out_r <= 453; end
|
||||
8'd10 : begin wave_out_r <= 503; end
|
||||
8'd11 : begin wave_out_r <= 553; end
|
||||
8'd12 : begin wave_out_r <= 603; end
|
||||
8'd13 : begin wave_out_r <= 653; end
|
||||
8'd14 : begin wave_out_r <= 703; end
|
||||
8'd15 : begin wave_out_r <= 754; end
|
||||
8'd16 : begin wave_out_r <= 804; end
|
||||
8'd17 : begin wave_out_r <= 854; end
|
||||
8'd18 : begin wave_out_r <= 904; end
|
||||
8'd19 : begin wave_out_r <= 954; end
|
||||
8'd20 : begin wave_out_r <= 1004; end
|
||||
8'd21 : begin wave_out_r <= 1054; end
|
||||
8'd22 : begin wave_out_r <= 1103; end
|
||||
8'd23 : begin wave_out_r <= 1153; end
|
||||
8'd24 : begin wave_out_r <= 1203; end
|
||||
8'd25 : begin wave_out_r <= 1253; end
|
||||
8'd26 : begin wave_out_r <= 1302; end
|
||||
8'd27 : begin wave_out_r <= 1352; end
|
||||
8'd28 : begin wave_out_r <= 1402; end
|
||||
8'd29 : begin wave_out_r <= 1451; end
|
||||
8'd30 : begin wave_out_r <= 1501; end
|
||||
8'd31 : begin wave_out_r <= 1550; end
|
||||
8'd32 : begin wave_out_r <= 1600; end
|
||||
8'd33 : begin wave_out_r <= 1649; end
|
||||
8'd34 : begin wave_out_r <= 1698; end
|
||||
8'd35 : begin wave_out_r <= 1747; end
|
||||
8'd36 : begin wave_out_r <= 1796; end
|
||||
8'd37 : begin wave_out_r <= 1845; end
|
||||
8'd38 : begin wave_out_r <= 1894; end
|
||||
8'd39 : begin wave_out_r <= 1943; end
|
||||
8'd40 : begin wave_out_r <= 1992; end
|
||||
8'd41 : begin wave_out_r <= 2041; end
|
||||
8'd42 : begin wave_out_r <= 2090; end
|
||||
8'd43 : begin wave_out_r <= 2138; end
|
||||
8'd44 : begin wave_out_r <= 2187; end
|
||||
8'd45 : begin wave_out_r <= 2235; end
|
||||
8'd46 : begin wave_out_r <= 2284; end
|
||||
8'd47 : begin wave_out_r <= 2332; end
|
||||
8'd48 : begin wave_out_r <= 2380; end
|
||||
8'd49 : begin wave_out_r <= 2428; end
|
||||
8'd50 : begin wave_out_r <= 2476; end
|
||||
8'd51 : begin wave_out_r <= 2524; end
|
||||
8'd52 : begin wave_out_r <= 2572; end
|
||||
8'd53 : begin wave_out_r <= 2620; end
|
||||
8'd54 : begin wave_out_r <= 2667; end
|
||||
8'd55 : begin wave_out_r <= 2715; end
|
||||
8'd56 : begin wave_out_r <= 2762; end
|
||||
8'd57 : begin wave_out_r <= 2809; end
|
||||
8'd58 : begin wave_out_r <= 2857; end
|
||||
8'd59 : begin wave_out_r <= 2904; end
|
||||
8'd60 : begin wave_out_r <= 2951; end
|
||||
8'd61 : begin wave_out_r <= 2998; end
|
||||
8'd62 : begin wave_out_r <= 3044; end
|
||||
8'd63 : begin wave_out_r <= 3091; end
|
||||
8'd64 : begin wave_out_r <= 3137; end
|
||||
8'd65 : begin wave_out_r <= 3184; end
|
||||
8'd66 : begin wave_out_r <= 3230; end
|
||||
8'd67 : begin wave_out_r <= 3276; end
|
||||
8'd68 : begin wave_out_r <= 3322; end
|
||||
8'd69 : begin wave_out_r <= 3368; end
|
||||
8'd70 : begin wave_out_r <= 3414; end
|
||||
8'd71 : begin wave_out_r <= 3460; end
|
||||
8'd72 : begin wave_out_r <= 3505; end
|
||||
8'd73 : begin wave_out_r <= 3551; end
|
||||
8'd74 : begin wave_out_r <= 3596; end
|
||||
8'd75 : begin wave_out_r <= 3641; end
|
||||
8'd76 : begin wave_out_r <= 3686; end
|
||||
8'd77 : begin wave_out_r <= 3731; end
|
||||
8'd78 : begin wave_out_r <= 3776; end
|
||||
8'd79 : begin wave_out_r <= 3820; end
|
||||
8'd80 : begin wave_out_r <= 3865; end
|
||||
8'd81 : begin wave_out_r <= 3909; end
|
||||
8'd82 : begin wave_out_r <= 3953; end
|
||||
8'd83 : begin wave_out_r <= 3997; end
|
||||
8'd84 : begin wave_out_r <= 4041; end
|
||||
8'd85 : begin wave_out_r <= 4085; end
|
||||
8'd86 : begin wave_out_r <= 4128; end
|
||||
8'd87 : begin wave_out_r <= 4172; end
|
||||
8'd88 : begin wave_out_r <= 4215; end
|
||||
8'd89 : begin wave_out_r <= 4258; end
|
||||
8'd90 : begin wave_out_r <= 4301; end
|
||||
8'd91 : begin wave_out_r <= 4343; end
|
||||
8'd92 : begin wave_out_r <= 4386; end
|
||||
8'd93 : begin wave_out_r <= 4428; end
|
||||
8'd94 : begin wave_out_r <= 4471; end
|
||||
8'd95 : begin wave_out_r <= 4513; end
|
||||
8'd96 : begin wave_out_r <= 4555; end
|
||||
8'd97 : begin wave_out_r <= 4596; end
|
||||
8'd98 : begin wave_out_r <= 4638; end
|
||||
8'd99 : begin wave_out_r <= 4679; end
|
||||
8'd100 : begin wave_out_r <= 4720; end
|
||||
8'd101 : begin wave_out_r <= 4761; end
|
||||
8'd102 : begin wave_out_r <= 4802; end
|
||||
8'd103 : begin wave_out_r <= 4843; end
|
||||
8'd104 : begin wave_out_r <= 4883; end
|
||||
8'd105 : begin wave_out_r <= 4924; end
|
||||
8'd106 : begin wave_out_r <= 4964; end
|
||||
8'd107 : begin wave_out_r <= 5004; end
|
||||
8'd108 : begin wave_out_r <= 5044; end
|
||||
8'd109 : begin wave_out_r <= 5083; end
|
||||
8'd110 : begin wave_out_r <= 5122; end
|
||||
8'd111 : begin wave_out_r <= 5162; end
|
||||
8'd112 : begin wave_out_r <= 5201; end
|
||||
8'd113 : begin wave_out_r <= 5239; end
|
||||
8'd114 : begin wave_out_r <= 5278; end
|
||||
8'd115 : begin wave_out_r <= 5316; end
|
||||
8'd116 : begin wave_out_r <= 5354; end
|
||||
8'd117 : begin wave_out_r <= 5392; end
|
||||
8'd118 : begin wave_out_r <= 5430; end
|
||||
8'd119 : begin wave_out_r <= 5468; end
|
||||
8'd120 : begin wave_out_r <= 5505; end
|
||||
8'd121 : begin wave_out_r <= 5542; end
|
||||
8'd122 : begin wave_out_r <= 5579; end
|
||||
8'd123 : begin wave_out_r <= 5616; end
|
||||
8'd124 : begin wave_out_r <= 5652; end
|
||||
8'd125 : begin wave_out_r <= 5689; end
|
||||
8'd126 : begin wave_out_r <= 5725; end
|
||||
8'd127 : begin wave_out_r <= 5761; end
|
||||
8'd128 : begin wave_out_r <= 5796; end
|
||||
8'd129 : begin wave_out_r <= 5832; end
|
||||
8'd130 : begin wave_out_r <= 5867; end
|
||||
8'd131 : begin wave_out_r <= 5902; end
|
||||
8'd132 : begin wave_out_r <= 5937; end
|
||||
8'd133 : begin wave_out_r <= 5971; end
|
||||
8'd134 : begin wave_out_r <= 6006; end
|
||||
8'd135 : begin wave_out_r <= 6040; end
|
||||
8'd136 : begin wave_out_r <= 6074; end
|
||||
8'd137 : begin wave_out_r <= 6107; end
|
||||
8'd138 : begin wave_out_r <= 6141; end
|
||||
8'd139 : begin wave_out_r <= 6174; end
|
||||
8'd140 : begin wave_out_r <= 6207; end
|
||||
8'd141 : begin wave_out_r <= 6239; end
|
||||
8'd142 : begin wave_out_r <= 6272; end
|
||||
8'd143 : begin wave_out_r <= 6304; end
|
||||
8'd144 : begin wave_out_r <= 6336; end
|
||||
8'd145 : begin wave_out_r <= 6368; end
|
||||
8'd146 : begin wave_out_r <= 6399; end
|
||||
8'd147 : begin wave_out_r <= 6431; end
|
||||
8'd148 : begin wave_out_r <= 6462; end
|
||||
8'd149 : begin wave_out_r <= 6493; end
|
||||
8'd150 : begin wave_out_r <= 6523; end
|
||||
8'd151 : begin wave_out_r <= 6553; end
|
||||
8'd152 : begin wave_out_r <= 6584; end
|
||||
8'd153 : begin wave_out_r <= 6613; end
|
||||
8'd154 : begin wave_out_r <= 6643; end
|
||||
8'd155 : begin wave_out_r <= 6672; end
|
||||
8'd156 : begin wave_out_r <= 6701; end
|
||||
8'd157 : begin wave_out_r <= 6730; end
|
||||
8'd158 : begin wave_out_r <= 6759; end
|
||||
8'd159 : begin wave_out_r <= 6787; end
|
||||
8'd160 : begin wave_out_r <= 6815; end
|
||||
8'd161 : begin wave_out_r <= 6843; end
|
||||
8'd162 : begin wave_out_r <= 6870; end
|
||||
8'd163 : begin wave_out_r <= 6897; end
|
||||
8'd164 : begin wave_out_r <= 6925; end
|
||||
8'd165 : begin wave_out_r <= 6951; end
|
||||
8'd166 : begin wave_out_r <= 6978; end
|
||||
8'd167 : begin wave_out_r <= 7004; end
|
||||
8'd168 : begin wave_out_r <= 7030; end
|
||||
8'd169 : begin wave_out_r <= 7056; end
|
||||
8'd170 : begin wave_out_r <= 7081; end
|
||||
8'd171 : begin wave_out_r <= 7106; end
|
||||
8'd172 : begin wave_out_r <= 7131; end
|
||||
8'd173 : begin wave_out_r <= 7156; end
|
||||
8'd174 : begin wave_out_r <= 7180; end
|
||||
8'd175 : begin wave_out_r <= 7204; end
|
||||
8'd176 : begin wave_out_r <= 7228; end
|
||||
8'd177 : begin wave_out_r <= 7251; end
|
||||
8'd178 : begin wave_out_r <= 7275; end
|
||||
8'd179 : begin wave_out_r <= 7298; end
|
||||
8'd180 : begin wave_out_r <= 7320; end
|
||||
8'd181 : begin wave_out_r <= 7343; end
|
||||
8'd182 : begin wave_out_r <= 7365; end
|
||||
8'd183 : begin wave_out_r <= 7387; end
|
||||
8'd184 : begin wave_out_r <= 7408; end
|
||||
8'd185 : begin wave_out_r <= 7430; end
|
||||
8'd186 : begin wave_out_r <= 7451; end
|
||||
8'd187 : begin wave_out_r <= 7472; end
|
||||
8'd188 : begin wave_out_r <= 7492; end
|
||||
8'd189 : begin wave_out_r <= 7512; end
|
||||
8'd190 : begin wave_out_r <= 7532; end
|
||||
8'd191 : begin wave_out_r <= 7552; end
|
||||
8'd192 : begin wave_out_r <= 7571; end
|
||||
8'd193 : begin wave_out_r <= 7590; end
|
||||
8'd194 : begin wave_out_r <= 7609; end
|
||||
8'd195 : begin wave_out_r <= 7627; end
|
||||
8'd196 : begin wave_out_r <= 7646; end
|
||||
8'd197 : begin wave_out_r <= 7664; end
|
||||
8'd198 : begin wave_out_r <= 7681; end
|
||||
8'd199 : begin wave_out_r <= 7698; end
|
||||
8'd200 : begin wave_out_r <= 7715; end
|
||||
8'd201 : begin wave_out_r <= 7732; end
|
||||
8'd202 : begin wave_out_r <= 7749; end
|
||||
8'd203 : begin wave_out_r <= 7765; end
|
||||
8'd204 : begin wave_out_r <= 7781; end
|
||||
8'd205 : begin wave_out_r <= 7796; end
|
||||
8'd206 : begin wave_out_r <= 7812; end
|
||||
8'd207 : begin wave_out_r <= 7827; end
|
||||
8'd208 : begin wave_out_r <= 7841; end
|
||||
8'd209 : begin wave_out_r <= 7856; end
|
||||
8'd210 : begin wave_out_r <= 7870; end
|
||||
8'd211 : begin wave_out_r <= 7884; end
|
||||
8'd212 : begin wave_out_r <= 7897; end
|
||||
8'd213 : begin wave_out_r <= 7910; end
|
||||
8'd214 : begin wave_out_r <= 7923; end
|
||||
8'd215 : begin wave_out_r <= 7936; end
|
||||
8'd216 : begin wave_out_r <= 7948; end
|
||||
8'd217 : begin wave_out_r <= 7960; end
|
||||
8'd218 : begin wave_out_r <= 7972; end
|
||||
8'd219 : begin wave_out_r <= 7983; end
|
||||
8'd220 : begin wave_out_r <= 7994; end
|
||||
8'd221 : begin wave_out_r <= 8005; end
|
||||
8'd222 : begin wave_out_r <= 8016; end
|
||||
8'd223 : begin wave_out_r <= 8026; end
|
||||
8'd224 : begin wave_out_r <= 8036; end
|
||||
8'd225 : begin wave_out_r <= 8045; end
|
||||
8'd226 : begin wave_out_r <= 8055; end
|
||||
8'd227 : begin wave_out_r <= 8064; end
|
||||
8'd228 : begin wave_out_r <= 8072; end
|
||||
8'd229 : begin wave_out_r <= 8081; end
|
||||
8'd230 : begin wave_out_r <= 8089; end
|
||||
8'd231 : begin wave_out_r <= 8097; end
|
||||
8'd232 : begin wave_out_r <= 8104; end
|
||||
8'd233 : begin wave_out_r <= 8111; end
|
||||
8'd234 : begin wave_out_r <= 8118; end
|
||||
8'd235 : begin wave_out_r <= 8125; end
|
||||
8'd236 : begin wave_out_r <= 8131; end
|
||||
8'd237 : begin wave_out_r <= 8137; end
|
||||
8'd238 : begin wave_out_r <= 8142; end
|
||||
8'd239 : begin wave_out_r <= 8148; end
|
||||
8'd240 : begin wave_out_r <= 8153; end
|
||||
8'd241 : begin wave_out_r <= 8157; end
|
||||
8'd242 : begin wave_out_r <= 8162; end
|
||||
8'd243 : begin wave_out_r <= 8166; end
|
||||
8'd244 : begin wave_out_r <= 8170; end
|
||||
8'd245 : begin wave_out_r <= 8173; end
|
||||
8'd246 : begin wave_out_r <= 8176; end
|
||||
8'd247 : begin wave_out_r <= 8179; end
|
||||
8'd248 : begin wave_out_r <= 8182; end
|
||||
8'd249 : begin wave_out_r <= 8184; end
|
||||
8'd250 : begin wave_out_r <= 8186; end
|
||||
8'd251 : begin wave_out_r <= 8188; end
|
||||
8'd252 : begin wave_out_r <= 8189; end
|
||||
8'd253 : begin wave_out_r <= 8190; end
|
||||
8'd254 : begin wave_out_r <= 8191; end
|
||||
8'd255 : begin wave_out_r <= 8191; end
|
||||
default : begin wave_out_r <= 0; end
|
||||
endcase
|
||||
end
|
||||
|
||||
reg signed [OUTPUT_WIDTH - 1 : 0] FM_out_r0 = 0;
|
||||
always @(*) begin
|
||||
case (addr_r1[9])
|
||||
1'b0 : begin FM_out_r0 <= wave_out_r[13 : 14 - OUTPUT_WIDTH]; end
|
||||
1'b1 : begin FM_out_r0 <= - wave_out_r[13 : 14 - OUTPUT_WIDTH]; end
|
||||
default : begin FM_out_r0 <= 14'd0; end
|
||||
endcase
|
||||
end
|
||||
|
||||
reg signed [OUTPUT_WIDTH - 1 : 0] FM_out_r1 = 0;
|
||||
always @(posedge clk) begin
|
||||
if (RST) begin
|
||||
FM_out_r1 <= 0;
|
||||
end
|
||||
else begin
|
||||
FM_out_r1 <= FM_out_r0;
|
||||
end
|
||||
end
|
||||
|
||||
assign FM_wave = FM_out_r1;
|
||||
|
||||
endmodule
|
20
lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/BF_op.v
Normal file
20
lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/BF_op.v
Normal file
@ -0,0 +1,20 @@
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module BF_op #(
|
||||
parameter REAL_WIDTH = 18,
|
||||
parameter IMGN_WIDTH = 18,
|
||||
localparam CPLX_WIDTH = REAL_WIDTH + IMGN_WIDTH
|
||||
) (
|
||||
input [CPLX_WIDTH - 1 : 0] ia,
|
||||
input [CPLX_WIDTH - 1 : 0] ib,
|
||||
output [CPLX_WIDTH - 1 : 0] oa,
|
||||
output [CPLX_WIDTH - 1 : 0] ob
|
||||
);
|
||||
|
||||
assign oa[CPLX_WIDTH-1:REAL_WIDTH] = $signed(ia[CPLX_WIDTH-1:REAL_WIDTH]) + $signed(ib[CPLX_WIDTH-1:REAL_WIDTH]);
|
||||
assign oa[IMGN_WIDTH-1:0] = $signed(ia[IMGN_WIDTH-1:0]) + $signed(ib[IMGN_WIDTH-1:0]);
|
||||
|
||||
assign ob[CPLX_WIDTH-1:REAL_WIDTH] = $signed(ia[CPLX_WIDTH-1:REAL_WIDTH]) - $signed(ib[CPLX_WIDTH-1:REAL_WIDTH]);
|
||||
assign ob[IMGN_WIDTH-1:0] = $signed(ia[IMGN_WIDTH-1:0]) - $signed(ib[IMGN_WIDTH-1:0]);
|
||||
|
||||
endmodule
|
104
lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/BF_stg1.v
Normal file
104
lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/BF_stg1.v
Normal file
@ -0,0 +1,104 @@
|
||||
`timescale 1ns/100ps
|
||||
module BF_stg1 #(
|
||||
parameter FFT_STG = 7,
|
||||
parameter REAL_WIDTH = 18,
|
||||
parameter IMGN_WIDTH = 18,
|
||||
parameter TOTAL_STAGE = 11,
|
||||
localparam CPLX_WIDTH = REAL_WIDTH + IMGN_WIDTH
|
||||
) (
|
||||
input iclk,
|
||||
input rst_n,
|
||||
|
||||
input ien,
|
||||
input [TOTAL_STAGE-1 : 0] iaddr,
|
||||
input [CPLX_WIDTH -1 : 0] idata,
|
||||
|
||||
output oen,
|
||||
output [TOTAL_STAGE-1 : 0] oaddr,
|
||||
output [CPLX_WIDTH -1 : 0] odata
|
||||
);
|
||||
|
||||
localparam TOTAL_ADDR_MAX = { TOTAL_STAGE { 1'b1 } };
|
||||
localparam STG_MAX = { FFT_STG { 1'b1 } };
|
||||
localparam STG_HALFMAX = ( STG_MAX >> 1 );
|
||||
|
||||
reg [CPLX_WIDTH - 1 : 0] r [STG_HALFMAX:0];
|
||||
integer i;
|
||||
initial begin
|
||||
for (i = 0; i<=STG_HALFMAX; i=i+1) begin
|
||||
r[i] = 0;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
reg dump = 0;
|
||||
reg [FFT_STG - 1 : 0] dump_cnt = 0;
|
||||
always @(posedge iclk) begin
|
||||
if(iaddr[FFT_STG-1:0] == STG_MAX && ien) begin
|
||||
dump <= 1'b1;
|
||||
dump_cnt <= 0;
|
||||
end
|
||||
else if(dump) begin
|
||||
if(dump_cnt == STG_HALFMAX) dump <= 1'b0;
|
||||
dump_cnt <= dump_cnt + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
wire with_dump;
|
||||
assign with_dump = dump;
|
||||
|
||||
wire [CPLX_WIDTH - 1 : 0] bf_ia;
|
||||
wire [CPLX_WIDTH - 1 : 0] bf_ib;
|
||||
wire [CPLX_WIDTH - 1 : 0] bf_oa;
|
||||
wire [CPLX_WIDTH - 1 : 0] bf_ob;
|
||||
assign bf_ia = r[STG_HALFMAX];
|
||||
assign bf_ib = idata;
|
||||
BF_op #(
|
||||
.REAL_WIDTH(REAL_WIDTH),
|
||||
.IMGN_WIDTH(IMGN_WIDTH)
|
||||
) bf0 (
|
||||
.ia(bf_ia),
|
||||
.ib(bf_ib),
|
||||
.oa(bf_oa),
|
||||
.ob(bf_ob)
|
||||
);
|
||||
|
||||
wire [CPLX_WIDTH - 1 : 0] wdata_in;
|
||||
integer index;
|
||||
always @(posedge iclk) begin
|
||||
if(ien) r[0] <= wdata_in;
|
||||
for(index = STG_HALFMAX; index > 0; index=index-1)
|
||||
r[index] <= r[index-1];
|
||||
end
|
||||
|
||||
reg oen_r = 0;
|
||||
reg [TOTAL_STAGE-1 : 0] oaddr_r = 0;
|
||||
reg [CPLX_WIDTH -1 : 0] odata_r = 0;
|
||||
wire is_load;
|
||||
wire is_calc;
|
||||
assign is_load = ~iaddr[FFT_STG-1];
|
||||
assign is_calc = iaddr[FFT_STG-1];
|
||||
assign wdata_in = is_load ? idata : bf_ob;
|
||||
always @(posedge iclk) begin
|
||||
if(is_calc & ien) begin
|
||||
odata_r <= bf_oa;
|
||||
oaddr_r <= oaddr_r + 1'b1;
|
||||
oen_r <= 1'b1;
|
||||
end
|
||||
else if((is_load | ~ien) & with_dump) begin
|
||||
odata_r <= r[STG_HALFMAX];
|
||||
oaddr_r <= oaddr_r + 1'b1;
|
||||
oen_r <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
odata_r <= 0;
|
||||
oaddr_r <= TOTAL_ADDR_MAX;
|
||||
oen_r <= 1'b0;
|
||||
end
|
||||
end
|
||||
assign odata = odata_r;
|
||||
assign oaddr = oaddr_r;
|
||||
assign oen = oen_r;
|
||||
|
||||
endmodule
|
110
lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/BF_stgX.v
Normal file
110
lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/BF_stgX.v
Normal file
@ -0,0 +1,110 @@
|
||||
`timescale 1ns/100ps
|
||||
module BF_stgX # (
|
||||
parameter FFT_STG = 7,
|
||||
parameter REAL_WIDTH = 18,
|
||||
parameter IMGN_WIDTH = 18,
|
||||
parameter TOTAL_STAGE = 11,
|
||||
localparam CPLX_WIDTH = REAL_WIDTH + IMGN_WIDTH
|
||||
) (
|
||||
input iclk,
|
||||
input rst_n,
|
||||
|
||||
input ien,
|
||||
input [TOTAL_STAGE-1 : 0] iaddr,
|
||||
input [CPLX_WIDTH -1 : 0] idata,
|
||||
|
||||
output oen,
|
||||
output [TOTAL_STAGE-1 : 0] oaddr,
|
||||
output [CPLX_WIDTH -1 : 0] odata
|
||||
);
|
||||
|
||||
localparam TOTAL_ADDR_MAX = { TOTAL_STAGE { 1'b1 } };
|
||||
localparam STG_MAX = { FFT_STG { 1'b1 } };
|
||||
localparam STG_HALFMAX = ( STG_MAX >> 1 );
|
||||
|
||||
reg [CPLX_WIDTH - 1 : 0] r [STG_HALFMAX:0];
|
||||
integer i;
|
||||
initial begin
|
||||
for (i = 0; i<=STG_HALFMAX; i=i+1) begin
|
||||
r[i] = 0;
|
||||
end
|
||||
end
|
||||
|
||||
reg [CPLX_WIDTH-1 : 0] rdata = 0;
|
||||
reg [CPLX_WIDTH-1 : 0] rdata_out = 0;
|
||||
|
||||
|
||||
reg dump = 0;
|
||||
reg [FFT_STG - 2 : 0] dump_cnt = 0;
|
||||
always @(posedge iclk) begin
|
||||
if(iaddr[FFT_STG-1:0] == STG_MAX && ien) begin
|
||||
dump <= 1'b1;
|
||||
dump_cnt <= 0;
|
||||
end
|
||||
else if(dump) begin
|
||||
if(dump_cnt == STG_HALFMAX) dump <= 1'b0;
|
||||
dump_cnt <= dump_cnt + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
wire with_dump;
|
||||
assign with_dump = dump;
|
||||
|
||||
wire [FFT_STG-2 : 0] waddr_in;
|
||||
wire [FFT_STG-2 : 0] raddr_in;
|
||||
assign raddr_in = (with_dump ? dump_cnt : iaddr[FFT_STG-2:0]) + 2'b10;
|
||||
assign waddr_in = iaddr[FFT_STG-2:0];
|
||||
|
||||
wire [CPLX_WIDTH - 1 : 0] bf_ia;
|
||||
wire [CPLX_WIDTH - 1 : 0] bf_ib;
|
||||
wire [CPLX_WIDTH - 1 : 0] bf_oa;
|
||||
wire [CPLX_WIDTH - 1 : 0] bf_ob;
|
||||
assign bf_ia = rdata;
|
||||
assign bf_ib = idata;
|
||||
BF_op #(
|
||||
.REAL_WIDTH(REAL_WIDTH),
|
||||
.IMGN_WIDTH(IMGN_WIDTH)
|
||||
) bf0 (
|
||||
.ia(bf_ia),
|
||||
.ib(bf_ib),
|
||||
.oa(bf_oa),
|
||||
.ob(bf_ob)
|
||||
);
|
||||
|
||||
wire [CPLX_WIDTH - 1 : 0] wdata_in;
|
||||
always @(posedge iclk) begin
|
||||
if(ien) r[waddr_in] <= wdata_in;
|
||||
rdata_out <= r[raddr_in];
|
||||
rdata <= rdata_out;
|
||||
end
|
||||
|
||||
reg oen_r = 0;
|
||||
reg [TOTAL_STAGE-1 : 0] oaddr_r = 0;
|
||||
reg [CPLX_WIDTH -1 : 0] odata_r = 0;
|
||||
wire is_load;
|
||||
wire is_calc;
|
||||
assign is_load = ~iaddr[FFT_STG-1];
|
||||
assign is_calc = iaddr[FFT_STG-1];
|
||||
assign wdata_in = is_load ? idata : bf_ob;
|
||||
always @(posedge iclk) begin
|
||||
if(is_calc & ien) begin
|
||||
odata_r <= bf_oa;
|
||||
oaddr_r <= oaddr_r + 1'b1;
|
||||
oen_r <= 1'b1;
|
||||
end
|
||||
else if((is_load | ~ien) & with_dump) begin
|
||||
odata_r <= rdata;
|
||||
oaddr_r <= oaddr_r + 1'b1;
|
||||
oen_r <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
odata_r <= 0;
|
||||
oaddr_r <= TOTAL_ADDR_MAX;
|
||||
oen_r <= 1'b0;
|
||||
end
|
||||
end
|
||||
assign odata = odata_r;
|
||||
assign oaddr = oaddr_r;
|
||||
assign oen = oen_r;
|
||||
|
||||
endmodule
|
27
lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/cmpl_mult.v
Normal file
27
lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/cmpl_mult.v
Normal file
@ -0,0 +1,27 @@
|
||||
`timescale 1 ps / 1 ps
|
||||
module cmpl_mult #(
|
||||
parameter REAL_WIDTH = 18,
|
||||
parameter IMGN_WIDTH = 18,
|
||||
localparam CPLX_WIDTH = REAL_WIDTH + IMGN_WIDTH
|
||||
) (
|
||||
input clock,
|
||||
input [REAL_WIDTH-1:0] dataa_real,
|
||||
input [IMGN_WIDTH-1:0] dataa_imag,
|
||||
input [REAL_WIDTH-1:0] datab_real,
|
||||
input [IMGN_WIDTH-1:0] datab_imag,
|
||||
output [CPLX_WIDTH-1:0] result_real,
|
||||
output [CPLX_WIDTH-1:0] result_imag
|
||||
);
|
||||
|
||||
|
||||
reg signed [CPLX_WIDTH-1:0] outr = 0;
|
||||
reg signed [CPLX_WIDTH-1:0] outi = 0;
|
||||
always@(posedge clock) begin
|
||||
outr <= $signed(dataa_real) * $signed(datab_real) - $signed(dataa_imag) * $signed(datab_imag);
|
||||
outi <= $signed(dataa_real) * $signed(datab_imag) + $signed(dataa_imag) * $signed(datab_real);
|
||||
end
|
||||
|
||||
assign result_imag = outi;
|
||||
assign result_real = outr;
|
||||
|
||||
endmodule
|
83
lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/fft.v
Normal file
83
lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/fft.v
Normal file
@ -0,0 +1,83 @@
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module fft #(
|
||||
parameter REAL_WIDTH = 18,
|
||||
parameter IMGN_WIDTH = 18,
|
||||
parameter TOTAL_STAGE = 11
|
||||
) (
|
||||
input iclk,
|
||||
input rst_n,
|
||||
|
||||
input ien,
|
||||
input [TOTAL_STAGE-1:0] iaddr,
|
||||
input [REAL_WIDTH-1:0] iReal,
|
||||
input [IMGN_WIDTH-1:0] iImag,
|
||||
|
||||
output oen,
|
||||
output [TOTAL_STAGE-1:0] oaddr,
|
||||
output [REAL_WIDTH-1:0] oReal,
|
||||
output [IMGN_WIDTH-1:0] oImag
|
||||
);
|
||||
|
||||
localparam INTER_MODU_WIRE_NUM = ((TOTAL_STAGE-1)/2);
|
||||
localparam CPLX_WIDTH = REAL_WIDTH + IMGN_WIDTH;
|
||||
|
||||
wire [CPLX_WIDTH -1:0] data_end;
|
||||
wire [TOTAL_STAGE-1:0] addr_end;
|
||||
|
||||
wire en_w [INTER_MODU_WIRE_NUM:0];
|
||||
wire [CPLX_WIDTH -1:0] data_w [INTER_MODU_WIRE_NUM:0];
|
||||
wire [TOTAL_STAGE-1:0] addr_w [INTER_MODU_WIRE_NUM:0];
|
||||
|
||||
assign en_w [INTER_MODU_WIRE_NUM] = ien;
|
||||
assign addr_w[INTER_MODU_WIRE_NUM] = iaddr;
|
||||
assign data_w[INTER_MODU_WIRE_NUM] = {iReal, iImag};
|
||||
|
||||
generate
|
||||
genvar gv_stg;
|
||||
for(gv_stg=TOTAL_STAGE; gv_stg>=2; gv_stg=gv_stg-2) begin : stagX
|
||||
fft_stage #(
|
||||
.REAL_WIDTH(REAL_WIDTH),
|
||||
.IMGN_WIDTH(IMGN_WIDTH),
|
||||
.TOTAL_STAGE(TOTAL_STAGE),
|
||||
.FFT_STG(gv_stg)
|
||||
)stgX_inst (
|
||||
.iclk(iclk),
|
||||
.rst_n(rst_n),
|
||||
.iaddr(addr_w[((gv_stg-1)/2)]),
|
||||
.idata(data_w[((gv_stg-1)/2)]),
|
||||
.ien(en_w[((gv_stg-1)/2)]),
|
||||
.oaddr(addr_w[((gv_stg-1)/2)-1]),
|
||||
.odata(data_w[((gv_stg-1)/2)-1]),
|
||||
.oen(en_w[((gv_stg-1)/2)-1])
|
||||
);
|
||||
end
|
||||
if(TOTAL_STAGE[0]) begin : BF_stg1
|
||||
BF_stg1 #(
|
||||
.REAL_WIDTH(REAL_WIDTH),
|
||||
.IMGN_WIDTH(IMGN_WIDTH),
|
||||
.TOTAL_STAGE(TOTAL_STAGE),
|
||||
.FFT_STG(1)
|
||||
)stg1_inst (
|
||||
.iclk(iclk),
|
||||
.rst_n(rst_n),
|
||||
.ien(en_w[0]),
|
||||
.iaddr(addr_w[0]),
|
||||
.idata(data_w[0]),
|
||||
.oen(oen),
|
||||
.oaddr(addr_end),
|
||||
.odata(data_end)
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate // bit_reverse
|
||||
genvar index;
|
||||
for(index=0; index<TOTAL_STAGE; index=index+1) begin: bit_reverse
|
||||
assign oaddr[TOTAL_STAGE-index-1] = addr_end[index];
|
||||
end
|
||||
endgenerate
|
||||
assign oReal = data_end[CPLX_WIDTH:REAL_WIDTH];
|
||||
assign oImag = data_end[IMGN_WIDTH:0];
|
||||
|
||||
endmodule
|
175
lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/fft_stage.v
Normal file
175
lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/fft_stage.v
Normal file
@ -0,0 +1,175 @@
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module fft_stage #(
|
||||
parameter FFT_STG = 7,
|
||||
parameter REAL_WIDTH = 18,
|
||||
parameter IMGN_WIDTH = 18,
|
||||
parameter TOTAL_STAGE = 11,
|
||||
localparam CPLX_WIDTH = REAL_WIDTH + IMGN_WIDTH
|
||||
) (
|
||||
input iclk,
|
||||
input rst_n,
|
||||
|
||||
input ien,
|
||||
input [CPLX_WIDTH-1 : 0] idata,
|
||||
input [TOTAL_STAGE-1 : 0] iaddr,
|
||||
|
||||
output oen,
|
||||
output [CPLX_WIDTH-1 : 0] odata,
|
||||
output [TOTAL_STAGE-1 : 0] oaddr
|
||||
);
|
||||
|
||||
wire bfX_oen;
|
||||
wire [CPLX_WIDTH-1:0] bfX_odata;
|
||||
wire [TOTAL_STAGE-1:0] bfX_oaddr;
|
||||
|
||||
wire Trans_I_oen;
|
||||
wire [CPLX_WIDTH-1:0] Trans_I_odata;
|
||||
wire [TOTAL_STAGE-1:0] Trans_I_oaddr;
|
||||
|
||||
wire bfX_1_oen;
|
||||
wire [CPLX_WIDTH-1:0] bfX_1_data;
|
||||
wire [TOTAL_STAGE-1:0] bfX_1_oaddr;
|
||||
|
||||
generate
|
||||
if(FFT_STG == 2) begin : BF_stg_I2
|
||||
BF_stg1 #(
|
||||
.REAL_WIDTH(REAL_WIDTH),
|
||||
.IMGN_WIDTH(IMGN_WIDTH),
|
||||
.TOTAL_STAGE(TOTAL_STAGE),
|
||||
.FFT_STG(2)
|
||||
)BF_instI (
|
||||
.iclk(iclk),
|
||||
.rst_n(rst_n),
|
||||
.ien(ien),
|
||||
.iaddr(iaddr),
|
||||
.idata(idata),
|
||||
.oen(bfX_oen),
|
||||
.oaddr(bfX_oaddr),
|
||||
.odata(bfX_odata)
|
||||
);
|
||||
end
|
||||
else begin : BF_stgX_I
|
||||
BF_stgX #(
|
||||
.REAL_WIDTH(REAL_WIDTH),
|
||||
.IMGN_WIDTH(IMGN_WIDTH),
|
||||
.TOTAL_STAGE(TOTAL_STAGE),
|
||||
.FFT_STG(FFT_STG)
|
||||
)BF_instI (
|
||||
.iclk(iclk),
|
||||
.rst_n(rst_n),
|
||||
.ien(ien),
|
||||
.iaddr(iaddr),
|
||||
.idata(idata),
|
||||
.oen(bfX_oen),
|
||||
.oaddr(bfX_oaddr),
|
||||
.odata(bfX_odata)
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate if(FFT_STG > 1) begin : ftrans_conjugate
|
||||
ftrans #(
|
||||
.FTRANS_STYLE("conjugate"), //conjugate
|
||||
.REAL_WIDTH(REAL_WIDTH),
|
||||
.IMGN_WIDTH(IMGN_WIDTH),
|
||||
.TOTAL_STAGE(TOTAL_STAGE),
|
||||
.FFT_STG(FFT_STG)
|
||||
) ftrans_conjugate_inst (
|
||||
.iclk(iclk),
|
||||
.ien(bfX_oen),
|
||||
.iaddr(bfX_oaddr),
|
||||
.idata(bfX_odata),
|
||||
.oen(Trans_I_oen),
|
||||
.oaddr(Trans_I_oaddr),
|
||||
.odata(Trans_I_odata)
|
||||
);
|
||||
end
|
||||
else begin
|
||||
assign oen = bfX_oen;
|
||||
assign oaddr = bfX_oaddr;
|
||||
assign odata = bfX_odata;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if(FFT_STG == 3) begin : BF_stg_II2
|
||||
BF_stg1 #(
|
||||
.REAL_WIDTH(REAL_WIDTH),
|
||||
.IMGN_WIDTH(IMGN_WIDTH),
|
||||
.TOTAL_STAGE(TOTAL_STAGE),
|
||||
.FFT_STG(2)
|
||||
) BF_instII (
|
||||
.iclk(iclk),
|
||||
.rst_n(rst_n),
|
||||
.ien(Trans_I_oen),
|
||||
.iaddr(Trans_I_oaddr),
|
||||
.idata(Trans_I_odata),
|
||||
.oen(bfX_1_oen),
|
||||
.oaddr(bfX_1_oaddr),
|
||||
.odata(bfX_1_data)
|
||||
);
|
||||
end
|
||||
else if(FFT_STG == 2) begin : BF_stg_II1
|
||||
BF_stg1 #(
|
||||
.REAL_WIDTH(REAL_WIDTH),
|
||||
.IMGN_WIDTH(IMGN_WIDTH),
|
||||
.TOTAL_STAGE(TOTAL_STAGE),
|
||||
.FFT_STG(1)
|
||||
) BF_instII (
|
||||
.iclk(iclk),
|
||||
.rst_n(rst_n),
|
||||
.ien(Trans_I_oen),
|
||||
.iaddr(Trans_I_oaddr),
|
||||
.idata(Trans_I_odata),
|
||||
.oen(bfX_1_oen),
|
||||
.oaddr(bfX_1_oaddr),
|
||||
.odata(bfX_1_data)
|
||||
);
|
||||
end
|
||||
else begin : BF_stgX_II
|
||||
BF_stgX #(
|
||||
.REAL_WIDTH(REAL_WIDTH),
|
||||
.IMGN_WIDTH(IMGN_WIDTH),
|
||||
.TOTAL_STAGE(TOTAL_STAGE),
|
||||
.FFT_STG(FFT_STG-1)
|
||||
) BF_instII (
|
||||
.iclk(iclk),
|
||||
.rst_n(rst_n),
|
||||
.ien(Trans_I_oen),
|
||||
.iaddr(Trans_I_oaddr),
|
||||
.idata(Trans_I_odata),
|
||||
.oen(bfX_1_oen),
|
||||
.oaddr(bfX_1_oaddr),
|
||||
.odata(bfX_1_data)
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
if(FFT_STG > 2) begin : ftrans_twiddle
|
||||
ftrans #(
|
||||
.FTRANS_STYLE("twiddle"), //conjugate
|
||||
.REAL_WIDTH(REAL_WIDTH),
|
||||
.IMGN_WIDTH(IMGN_WIDTH),
|
||||
.TOTAL_STAGE(TOTAL_STAGE),
|
||||
.FFT_STG(FFT_STG)
|
||||
) ftrans_twiddle_inst (
|
||||
.iclk(iclk),
|
||||
.ien(bfX_1_oen),
|
||||
.iaddr(bfX_1_oaddr),
|
||||
.idata(bfX_1_data),
|
||||
.oen(oen),
|
||||
.oaddr(oaddr),
|
||||
.odata(odata)
|
||||
);
|
||||
end
|
||||
else begin
|
||||
assign oen = bfX_1_oen;
|
||||
assign oaddr = bfX_1_oaddr;
|
||||
assign odata = bfX_1_data;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
endmodule
|
154
lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/ftrans.v
Normal file
154
lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/ftrans.v
Normal file
@ -0,0 +1,154 @@
|
||||
`timescale 1ns/100ps
|
||||
|
||||
module ftrans #(
|
||||
parameter FTRANS_STYLE = "twiddle", //conjugate
|
||||
parameter REAL_WIDTH = 18,
|
||||
parameter IMGN_WIDTH = 18,
|
||||
parameter TOTAL_STAGE = 11,
|
||||
parameter FFT_STG = 7,
|
||||
localparam CPLX_WIDTH = REAL_WIDTH + IMGN_WIDTH
|
||||
) (
|
||||
input iclk,
|
||||
|
||||
input ien,
|
||||
input [CPLX_WIDTH-1:0] idata,
|
||||
input [TOTAL_STAGE-1:0] iaddr,
|
||||
|
||||
output oen,
|
||||
output [CPLX_WIDTH-1:0] odata,
|
||||
output [TOTAL_STAGE-1:0] oaddr
|
||||
);
|
||||
|
||||
wire k1 = iaddr[FFT_STG-1];
|
||||
wire k2 = iaddr[FFT_STG-2];
|
||||
|
||||
wire signed [REAL_WIDTH-1:0] data_real = idata[CPLX_WIDTH-1:REAL_WIDTH];
|
||||
wire signed [IMGN_WIDTH-1:0] data_imag = idata[IMGN_WIDTH-1:0];
|
||||
|
||||
reg [CPLX_WIDTH-1:0] idata_r = 0;
|
||||
reg [CPLX_WIDTH-1:0] odata_r = 0;
|
||||
generate if(FTRANS_STYLE == "conjugate") begin : conjugate
|
||||
always @(posedge iclk) begin
|
||||
if({k1, k2} == 2'b11)begin
|
||||
idata_r <= {data_real,-data_imag};
|
||||
odata_r <= idata_r;
|
||||
end
|
||||
else begin
|
||||
idata_r <= idata;
|
||||
odata_r <= idata_r;
|
||||
end
|
||||
end
|
||||
end
|
||||
else if(FTRANS_STYLE == "twiddle") begin : twiddle
|
||||
wire [FFT_STG-3:0] n3 = iaddr[FFT_STG-3:0];
|
||||
wire [FFT_STG-2:0] addr1 = k1 ? {1'b0, n3} : { (FFT_STG-1) {1'b0} };
|
||||
wire [FFT_STG-2:0] addr2 = k2 ? {n3, 1'b0} : { (FFT_STG-1) {1'b0} };
|
||||
wire [FFT_STG-1:0] ROM_addr = addr1 + addr2; // ROM_addr = (k1 + 2*k2) * n3
|
||||
|
||||
wire [REAL_WIDTH-1:0] twiddle_ore;
|
||||
wire [IMGN_WIDTH-1:0] twiddle_oim;
|
||||
ftwiddle #(
|
||||
.REAL_WIDTH(REAL_WIDTH),
|
||||
.IMGN_WIDTH(IMGN_WIDTH),
|
||||
.TW_STAGE(FFT_STG)
|
||||
) ftwiddle_inst (
|
||||
.idx(ROM_addr),
|
||||
.ore(twiddle_ore),
|
||||
.oim(twiddle_oim)
|
||||
);
|
||||
|
||||
wire [CPLX_WIDTH-1:0] mul_ore;
|
||||
wire [CPLX_WIDTH-1:0] mul_oim;
|
||||
cmpl_mult #(
|
||||
.REAL_WIDTH(REAL_WIDTH),
|
||||
.IMGN_WIDTH(IMGN_WIDTH)
|
||||
) cmpl_mult_inst (
|
||||
.clock(iclk),
|
||||
.dataa_real(data_real),
|
||||
.dataa_imag(data_imag),
|
||||
.datab_real(twiddle_ore),
|
||||
.datab_imag(twiddle_oim),
|
||||
.result_real(mul_ore),
|
||||
.result_imag(mul_oim)
|
||||
);
|
||||
always @(posedge iclk) begin
|
||||
odata_r <= {mul_ore[CPLX_WIDTH-1:REAL_WIDTH],mul_oim[CPLX_WIDTH-1:IMGN_WIDTH]};
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
assign odata = odata_r;
|
||||
|
||||
localparam LATENCY = 2;
|
||||
reg [TOTAL_STAGE-1:0] oaddr_d [LATENCY-1:0];
|
||||
integer i;
|
||||
initial begin
|
||||
for (i = 0; i<LATENCY; i=i+1) begin
|
||||
oaddr_d[i] = 0;
|
||||
end
|
||||
end
|
||||
integer index;
|
||||
always @(posedge iclk) begin
|
||||
oaddr_d[0] <= iaddr;
|
||||
for(index=0; index<LATENCY-1; index=index+1) begin
|
||||
oaddr_d[index+1] <= oaddr_d[index];
|
||||
end
|
||||
end
|
||||
assign oaddr = oaddr_d[LATENCY-1];
|
||||
|
||||
reg [LATENCY-1:0] oen_d = 0;
|
||||
always @(posedge iclk) begin
|
||||
oen_d <= {oen_d[LATENCY-2:0], ien};
|
||||
end
|
||||
assign oen = oen_d[LATENCY-1];
|
||||
|
||||
// generate if(FTRANS_STYLE == "conjugate") begin
|
||||
// localparam LATENCY = 2;
|
||||
// reg [TOTAL_STAGE-1:0] oaddr_d [LATENCY-1:0];
|
||||
// integer i;
|
||||
// initial begin
|
||||
// for (i = 0; i<LATENCY; i=i+1) begin
|
||||
// oaddr_d[i] = 0;
|
||||
// end
|
||||
// end
|
||||
// integer index;
|
||||
// always @(posedge iclk) begin
|
||||
// oaddr_d[0] <= iaddr;
|
||||
// for(index=0; index<LATENCY-1; index=index+1) begin
|
||||
// oaddr_d[index+1] <= oaddr_d[index];
|
||||
// end
|
||||
// end
|
||||
// assign oaddr = oaddr_d[LATENCY-1];
|
||||
|
||||
// reg [LATENCY-1:0] oen_d = 0;
|
||||
// always @(posedge iclk) begin
|
||||
// oen_d <= {oen_d[LATENCY-2:0], ien};
|
||||
// end
|
||||
// assign oen = oen_d[LATENCY-1];
|
||||
// end
|
||||
// else if(FTRANS_STYLE == "twiddle") begin
|
||||
// localparam LATENCY = 3;
|
||||
// reg [TOTAL_STAGE-1:0] oaddr_d [LATENCY-1:0];
|
||||
// integer i;
|
||||
// initial begin
|
||||
// for (i = 0; i<LATENCY; i=i+1) begin
|
||||
// oaddr_d[i] = 0;
|
||||
// end
|
||||
// end
|
||||
// integer index;
|
||||
// always @(posedge iclk) begin
|
||||
// oaddr_d[0] <= iaddr;
|
||||
// for(index=0; index<LATENCY-1; index=index+1) begin
|
||||
// oaddr_d[index+1] <= oaddr_d[index];
|
||||
// end
|
||||
// end
|
||||
// assign oaddr = oaddr_d[LATENCY-1];
|
||||
|
||||
// reg [LATENCY-1:0] oen_d = 0;
|
||||
// always @(posedge iclk) begin
|
||||
// oen_d <= {oen_d[LATENCY-2:0], ien};
|
||||
// end
|
||||
// assign oen = oen_d[LATENCY-1];
|
||||
// end
|
||||
// endgenerate
|
||||
|
||||
endmodule
|
1142
lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/ftwiddle.v
Normal file
1142
lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/ftwiddle.v
Normal file
File diff suppressed because it is too large
Load Diff
81
lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/testbench.v
Normal file
81
lib/common/Apply/DSP/Advance/FFT/Flow_FFT_IFFT/testbench.v
Normal file
@ -0,0 +1,81 @@
|
||||
`timescale 1ns/100ps
|
||||
module testbench();
|
||||
|
||||
parameter TOTAL_STAGE = 8;
|
||||
|
||||
reg clk_100m = 0;
|
||||
reg sys_rst_n = 0;
|
||||
reg [TOTAL_STAGE-1:0] addr = 0;
|
||||
|
||||
wire valid_out;
|
||||
always begin
|
||||
#10 clk_100m = ~clk_100m;
|
||||
end
|
||||
always begin
|
||||
#50 sys_rst_n = 1;
|
||||
end
|
||||
always begin
|
||||
if (valid_out) begin
|
||||
#10 addr = addr + 1;#10;
|
||||
end
|
||||
else begin
|
||||
#10 addr = 0;#10;
|
||||
end
|
||||
end
|
||||
|
||||
parameter REAL_WIDTH = 18;
|
||||
parameter IMGN_WIDTH = 18;
|
||||
|
||||
wire [REAL_WIDTH-1:0] cos_wave;
|
||||
wire [IMGN_WIDTH-1:0] sin_wave;
|
||||
wire [15:0] pha_diff;
|
||||
Cordic #
|
||||
(
|
||||
.XY_BITS(REAL_WIDTH),
|
||||
.PH_BITS(16), //1~32
|
||||
.ITERATIONS(16), //1~32
|
||||
.CORDIC_STYLE("ROTATE"), //ROTATE //VECTOR
|
||||
.PHASE_ACC("ON") //ON //OFF
|
||||
)
|
||||
IQ_Gen_u
|
||||
(
|
||||
.clk_in(clk_100m),
|
||||
.RST(1'd0),
|
||||
.x_i(0),
|
||||
.y_i(0),
|
||||
.phase_in(16'd2356),//Fre_word = ((2^PH_BITS)/fc)* f fc:时钟频率 f输出频率
|
||||
|
||||
.x_o(cos_wave),
|
||||
.y_o(sin_wave),
|
||||
.phase_out(pha_diff),
|
||||
|
||||
.valid_in(1),
|
||||
.valid_out(valid_out)
|
||||
);
|
||||
|
||||
wire oen;
|
||||
wire [REAL_WIDTH-1:0] oReal;
|
||||
wire [IMGN_WIDTH-1:0] oImag;
|
||||
wire [TOTAL_STAGE-1:0] oaddr;
|
||||
fft #(
|
||||
.REAL_WIDTH(REAL_WIDTH),
|
||||
.IMGN_WIDTH(REAL_WIDTH),
|
||||
.TOTAL_STAGE(TOTAL_STAGE)
|
||||
)
|
||||
fft_ins
|
||||
(
|
||||
.iclk(clk_100m),
|
||||
.rst_n(sys_rst_n),
|
||||
|
||||
.iaddr(addr),
|
||||
.iReal(cos_wave),
|
||||
.iImag(0),
|
||||
.ien(valid_out),
|
||||
|
||||
.oReal(oReal),
|
||||
.oImag(oImag),
|
||||
.oaddr(oaddr),
|
||||
.oen(oen)
|
||||
);
|
||||
|
||||
endmodule
|
212
lib/common/Apply/DSP/Advance/Filter/CIC/CIC_DOWN_S2.v
Normal file
212
lib/common/Apply/DSP/Advance/Filter/CIC/CIC_DOWN_S2.v
Normal file
@ -0,0 +1,212 @@
|
||||
`timescale 1 ns / 1 ns
|
||||
module CIC_DOWN_S2 #(
|
||||
parameter INPUT_WIDTH = 12,
|
||||
parameter OUTPUT_WIDTH = 15
|
||||
) (
|
||||
input clk,
|
||||
input clk_enable,
|
||||
input reset,
|
||||
input [15:0] FACTOR,
|
||||
input signed [INPUT_WIDTH-1:0] filter_in,
|
||||
output signed [OUTPUT_WIDTH-1:0] filter_out,
|
||||
output ce_out
|
||||
);
|
||||
|
||||
localparam FILTER_WIDTH = OUTPUT_WIDTH;
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//Module Architecture: CIC_Down_S2
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Local Functions
|
||||
// Type Definitions
|
||||
// Constants
|
||||
// Signals
|
||||
reg [15:0] cur_count = 0; // ufix2
|
||||
wire phase_1; // boolean
|
||||
reg ce_out_reg = 0; // boolean
|
||||
//
|
||||
reg signed [INPUT_WIDTH-1:0] input_register = 0; // sfix16_En15
|
||||
// -- Section 1 Signals
|
||||
wire signed [INPUT_WIDTH-1:0] section_in1; // sfix16_En15
|
||||
wire signed [FILTER_WIDTH-1:0] section_cast1; // sfix18_En15
|
||||
wire signed [FILTER_WIDTH-1:0] sum1; // sfix18_En15
|
||||
reg signed [FILTER_WIDTH-1:0] section_out1 = 0; // sfix18_En15
|
||||
wire signed [FILTER_WIDTH-1:0] add_cast; // sfix18_En15
|
||||
wire signed [FILTER_WIDTH-1:0] add_cast_1; // sfix18_En15
|
||||
wire signed [FILTER_WIDTH:0] add_temp; // sfix19_En15
|
||||
// -- Section 2 Signals
|
||||
wire signed [FILTER_WIDTH-1:0] section_in2; // sfix18_En15
|
||||
wire signed [FILTER_WIDTH-1:0] sum2; // sfix18_En15
|
||||
reg signed [FILTER_WIDTH-1:0] section_out2 = 0; // sfix18_En15
|
||||
wire signed [FILTER_WIDTH-1:0] add_cast_2; // sfix18_En15
|
||||
wire signed [FILTER_WIDTH-1:0] add_cast_3; // sfix18_En15
|
||||
wire signed [FILTER_WIDTH:0] add_temp_1; // sfix19_En15
|
||||
// -- Section 3 Signals
|
||||
wire signed [FILTER_WIDTH-1:0] section_in3; // sfix18_En15
|
||||
reg signed [FILTER_WIDTH-1:0] diff1 = 0; // sfix18_En15
|
||||
wire signed [FILTER_WIDTH-1:0] section_out3; // sfix18_En15
|
||||
wire signed [FILTER_WIDTH-1:0] sub_cast; // sfix18_En15
|
||||
wire signed [FILTER_WIDTH-1:0] sub_cast_1; // sfix18_En15
|
||||
wire signed [FILTER_WIDTH:0] sub_temp; // sfix19_En15
|
||||
// -- Section 4 Signals
|
||||
wire signed [FILTER_WIDTH-1:0] section_in4; // sfix18_En15
|
||||
reg signed [FILTER_WIDTH-1:0] diff2 = 0; // sfix18_En15
|
||||
wire signed [FILTER_WIDTH-1:0] section_out4; // sfix18_En15
|
||||
wire signed [FILTER_WIDTH-1:0] sub_cast_2; // sfix18_En15
|
||||
wire signed [FILTER_WIDTH-1:0] sub_cast_3; // sfix18_En15
|
||||
wire signed [FILTER_WIDTH:0] sub_temp_1; // sfix19_En15
|
||||
//
|
||||
reg signed [FILTER_WIDTH-1:0] output_register = 0; // sfix18_En15
|
||||
|
||||
// Block Statements
|
||||
// ------------------ CE Output Generation ------------------
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin: ce_output
|
||||
if (reset == 1'b1) begin
|
||||
cur_count <= 16'd0;
|
||||
end
|
||||
else begin
|
||||
if (clk_enable == 1'b1) begin
|
||||
if (cur_count == FACTOR-1) begin
|
||||
cur_count <= 16'd0;
|
||||
end
|
||||
else begin
|
||||
cur_count <= cur_count + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end // ce_output
|
||||
|
||||
assign phase_1 = (cur_count == 16'd1 && clk_enable == 1'b1)? 1 : 0;
|
||||
|
||||
// ------------------ CE Output Register ------------------
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin: ce_output_register
|
||||
if (reset == 1'b1) begin
|
||||
ce_out_reg <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
ce_out_reg <= phase_1;
|
||||
end
|
||||
end // ce_output_register
|
||||
|
||||
// ------------------ Input Register ------------------
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin: input_reg_process
|
||||
if (reset == 1'b1) begin
|
||||
input_register <= 0;
|
||||
end
|
||||
else begin
|
||||
if (clk_enable == 1'b1) begin
|
||||
input_register <= filter_in;
|
||||
end
|
||||
end
|
||||
end // input_reg_process
|
||||
|
||||
// ------------------ Section # 1 : Integrator ------------------
|
||||
|
||||
assign section_in1 = input_register;
|
||||
|
||||
assign section_cast1 = $signed({{(FILTER_WIDTH-INPUT_WIDTH){section_in1[INPUT_WIDTH-1]}}, section_in1});
|
||||
|
||||
assign add_cast = section_cast1;
|
||||
assign add_cast_1 = section_out1;
|
||||
assign add_temp = add_cast + add_cast_1;
|
||||
assign sum1 = add_temp[FILTER_WIDTH-1:0];
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin: integrator_delay_section1
|
||||
if (reset == 1'b1) begin
|
||||
section_out1 <= 0;
|
||||
end
|
||||
else begin
|
||||
if (clk_enable == 1'b1) begin
|
||||
section_out1 <= sum1;
|
||||
end
|
||||
end
|
||||
end // integrator_delay_section1
|
||||
|
||||
// ------------------ Section # 2 : Integrator ------------------
|
||||
|
||||
assign section_in2 = section_out1;
|
||||
|
||||
assign add_cast_2 = section_in2;
|
||||
assign add_cast_3 = section_out2;
|
||||
assign add_temp_1 = add_cast_2 + add_cast_3;
|
||||
assign sum2 = add_temp_1[FILTER_WIDTH-1:0];
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin: integrator_delay_section2
|
||||
if (reset == 1'b1) begin
|
||||
section_out2 <= 0;
|
||||
end
|
||||
else begin
|
||||
if (clk_enable == 1'b1) begin
|
||||
section_out2 <= sum2;
|
||||
end
|
||||
end
|
||||
end // integrator_delay_section2
|
||||
|
||||
// ------------------ Section # 3 : Comb ------------------
|
||||
|
||||
assign section_in3 = section_out2;
|
||||
|
||||
assign sub_cast = section_in3;
|
||||
assign sub_cast_1 = diff1;
|
||||
assign sub_temp = sub_cast - sub_cast_1;
|
||||
assign section_out3 = sub_temp[FILTER_WIDTH-1:0];
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin: comb_delay_section3
|
||||
if (reset == 1'b1) begin
|
||||
diff1 <= 0;
|
||||
end
|
||||
else begin
|
||||
if (phase_1 == 1'b1) begin
|
||||
diff1 <= section_in3;
|
||||
end
|
||||
end
|
||||
end // comb_delay_section3
|
||||
|
||||
// ------------------ Section # 4 : Comb ------------------
|
||||
|
||||
assign section_in4 = section_out3;
|
||||
|
||||
assign sub_cast_2 = section_in4;
|
||||
assign sub_cast_3 = diff2;
|
||||
assign sub_temp_1 = sub_cast_2 - sub_cast_3;
|
||||
assign section_out4 = sub_temp_1[FILTER_WIDTH-1:0];
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin: comb_delay_section4
|
||||
if (reset == 1'b1) begin
|
||||
diff2 <= 0;
|
||||
end
|
||||
else begin
|
||||
if (phase_1 == 1'b1) begin
|
||||
diff2 <= section_in4;
|
||||
end
|
||||
end
|
||||
end // comb_delay_section4
|
||||
|
||||
// ------------------ Output Register ------------------
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin: output_reg_process
|
||||
if (reset == 1'b1) begin
|
||||
output_register <= 0;
|
||||
end
|
||||
else begin
|
||||
if (phase_1 == 1'b1) begin
|
||||
output_register <= section_out4;
|
||||
end
|
||||
end
|
||||
end // output_reg_process
|
||||
|
||||
// Assignment Statements
|
||||
assign ce_out = ce_out_reg;
|
||||
assign filter_out = output_register;
|
||||
endmodule // CIC_Down_S2
|
267
lib/common/Apply/DSP/Advance/Filter/CIC/CIC_DOWN_S3.v
Normal file
267
lib/common/Apply/DSP/Advance/Filter/CIC/CIC_DOWN_S3.v
Normal file
@ -0,0 +1,267 @@
|
||||
`timescale 1 ns / 1 ns
|
||||
module CIC_DOWN_S3 #(
|
||||
parameter INPUT_WIDTH = 12,
|
||||
parameter OUTPUT_WIDTH = 15
|
||||
) (
|
||||
input clk,
|
||||
input clk_enable,
|
||||
input reset,
|
||||
input [15:0] FACTOR,
|
||||
input signed [INPUT_WIDTH-1:0] filter_in,
|
||||
output signed [OUTPUT_WIDTH-1:0] filter_out,
|
||||
output ce_out
|
||||
);
|
||||
|
||||
localparam FILTER_WIDTH = OUTPUT_WIDTH;
|
||||
////////////////////////////////////////////////////////////////
|
||||
//Module Architecture: CIC_DOWN_S3
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Local Functions
|
||||
// Type Definitions
|
||||
// Constants
|
||||
// Signals
|
||||
reg [15:0] cur_count = 0; // ufix2
|
||||
wire phase_1; // boolean
|
||||
reg ce_out_reg = 0; // boolean
|
||||
//
|
||||
reg signed [INPUT_WIDTH-1:0] input_register = 0; // sfix12_En11
|
||||
// -- Section 1 Signals
|
||||
wire signed [INPUT_WIDTH-1:0] section_in1; // sfix12_En11
|
||||
wire signed [FILTER_WIDTH-1:0] section_cast1; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH-1:0] sum1; // sfix15_En11
|
||||
reg signed [FILTER_WIDTH-1:0] section_out1 = 0; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH-1:0] add_cast; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH-1:0] add_cast_1; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH:0] add_temp; // sfix16_En11
|
||||
// -- Section 2 Signals
|
||||
wire signed [FILTER_WIDTH-1:0] section_in2; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH-1:0] sum2; // sfix15_En11
|
||||
reg signed [FILTER_WIDTH-1:0] section_out2 = 0; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH-1:0] add_cast_2; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH-1:0] add_cast_3; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH:0] add_temp_1; // sfix16_En11
|
||||
// -- Section 3 Signals
|
||||
wire signed [FILTER_WIDTH-1:0] section_in3; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH-1:0] sum3; // sfix15_En11
|
||||
reg signed [FILTER_WIDTH-1:0] section_out3 = 0; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH-1:0] add_cast_4; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH-1:0] add_cast_5; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH:0] add_temp_2; // sfix16_En11
|
||||
// -- Section 4 Signals
|
||||
wire signed [FILTER_WIDTH-1:0] section_in4; // sfix15_En11
|
||||
reg signed [FILTER_WIDTH-1:0] diff1 = 0; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH-1:0] section_out4; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH-1:0] sub_cast; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH-1:0] sub_cast_1; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH:0] sub_temp; // sfix16_En11
|
||||
// -- Section 5 Signals
|
||||
wire signed [FILTER_WIDTH-1:0] section_in5; // sfix15_En11
|
||||
reg signed [FILTER_WIDTH-1:0] diff2 = 0; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH-1:0] section_out5; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH-1:0] sub_cast_2; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH-1:0] sub_cast_3; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH:0] sub_temp_1; // sfix16_En11
|
||||
// -- Section 6 Signals
|
||||
wire signed [FILTER_WIDTH-1:0] section_in6; // sfix15_En11
|
||||
reg signed [FILTER_WIDTH-1:0] diff3 = 0; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH-1:0] section_out6; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH-1:0] sub_cast_4; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH-1:0] sub_cast_5; // sfix15_En11
|
||||
wire signed [FILTER_WIDTH:0] sub_temp_2; // sfix16_En11
|
||||
//
|
||||
reg signed [FILTER_WIDTH-1:0] output_register = 0; // sfix15_En11
|
||||
|
||||
// Block Statements
|
||||
// ------------------ CE Output Generation ------------------
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin: ce_output
|
||||
if (reset == 1'b1) begin
|
||||
cur_count <= 16'd0;
|
||||
end
|
||||
else begin
|
||||
if (clk_enable == 1'b1) begin
|
||||
if (cur_count == FACTOR-1) begin
|
||||
cur_count <= 16'd0;
|
||||
end
|
||||
else begin
|
||||
cur_count <= cur_count + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end // ce_output
|
||||
|
||||
assign phase_1 = (cur_count == 16'd1 && clk_enable == 1'b1)? 1 : 0;
|
||||
|
||||
// ------------------ CE Output Register ------------------
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin: ce_output_register
|
||||
if (reset == 1'b1) begin
|
||||
ce_out_reg <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
ce_out_reg <= phase_1;
|
||||
end
|
||||
end // ce_output_register
|
||||
|
||||
// ------------------ Input Register ------------------
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin: input_reg_process
|
||||
if (reset == 1'b1) begin
|
||||
input_register <= 0;
|
||||
end
|
||||
else begin
|
||||
if (clk_enable == 1'b1) begin
|
||||
input_register <= filter_in;
|
||||
end
|
||||
end
|
||||
end // input_reg_process
|
||||
|
||||
// ------------------ Section # 1 : Integrator ------------------
|
||||
|
||||
assign section_in1 = input_register;
|
||||
|
||||
assign section_cast1 = $signed({{(FILTER_WIDTH-INPUT_WIDTH){section_in1[INPUT_WIDTH-1]}}, section_in1});
|
||||
|
||||
assign add_cast = section_cast1;
|
||||
assign add_cast_1 = section_out1;
|
||||
assign add_temp = add_cast + add_cast_1;
|
||||
assign sum1 = add_temp[FILTER_WIDTH-1:0];
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin: integrator_delay_section1
|
||||
if (reset == 1'b1) begin
|
||||
section_out1 <= 0;
|
||||
end
|
||||
else begin
|
||||
if (clk_enable == 1'b1) begin
|
||||
section_out1 <= sum1;
|
||||
end
|
||||
end
|
||||
end // integrator_delay_section1
|
||||
|
||||
// ------------------ Section # 2 : Integrator ------------------
|
||||
|
||||
assign section_in2 = section_out1;
|
||||
|
||||
assign add_cast_2 = section_in2;
|
||||
assign add_cast_3 = section_out2;
|
||||
assign add_temp_1 = add_cast_2 + add_cast_3;
|
||||
assign sum2 = add_temp_1[FILTER_WIDTH-1:0];
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin: integrator_delay_section2
|
||||
if (reset == 1'b1) begin
|
||||
section_out2 <= 0;
|
||||
end
|
||||
else begin
|
||||
if (clk_enable == 1'b1) begin
|
||||
section_out2 <= sum2;
|
||||
end
|
||||
end
|
||||
end // integrator_delay_section2
|
||||
|
||||
// ------------------ Section # 3 : Integrator ------------------
|
||||
|
||||
assign section_in3 = section_out2;
|
||||
|
||||
assign add_cast_4 = section_in3;
|
||||
assign add_cast_5 = section_out3;
|
||||
assign add_temp_2 = add_cast_4 + add_cast_5;
|
||||
assign sum3 = add_temp_2[FILTER_WIDTH-1:0];
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin: integrator_delay_section3
|
||||
if (reset == 1'b1) begin
|
||||
section_out3 <= 0;
|
||||
end
|
||||
else begin
|
||||
if (clk_enable == 1'b1) begin
|
||||
section_out3 <= sum3;
|
||||
end
|
||||
end
|
||||
end // integrator_delay_section3
|
||||
|
||||
// ------------------ Section # 4 : Comb ------------------
|
||||
|
||||
assign section_in4 = section_out3;
|
||||
|
||||
assign sub_cast = section_in4;
|
||||
assign sub_cast_1 = diff1;
|
||||
assign sub_temp = sub_cast - sub_cast_1;
|
||||
assign section_out4 = sub_temp[FILTER_WIDTH:0];
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin: comb_delay_section4
|
||||
if (reset == 1'b1) begin
|
||||
diff1 <= 0;
|
||||
end
|
||||
else begin
|
||||
if (phase_1 == 1'b1) begin
|
||||
diff1 <= section_in4;
|
||||
end
|
||||
end
|
||||
end // comb_delay_section4
|
||||
|
||||
// ------------------ Section # 5 : Comb ------------------
|
||||
|
||||
assign section_in5 = section_out4;
|
||||
|
||||
assign sub_cast_2 = section_in5;
|
||||
assign sub_cast_3 = diff2;
|
||||
assign sub_temp_1 = sub_cast_2 - sub_cast_3;
|
||||
assign section_out5 = sub_temp_1[FILTER_WIDTH-1:0];
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin: comb_delay_section5
|
||||
if (reset == 1'b1) begin
|
||||
diff2 <= 0;
|
||||
end
|
||||
else begin
|
||||
if (phase_1 == 1'b1) begin
|
||||
diff2 <= section_in5;
|
||||
end
|
||||
end
|
||||
end // comb_delay_section5
|
||||
|
||||
// ------------------ Section # 6 : Comb ------------------
|
||||
|
||||
assign section_in6 = section_out5;
|
||||
|
||||
assign sub_cast_4 = section_in6;
|
||||
assign sub_cast_5 = diff3;
|
||||
assign sub_temp_2 = sub_cast_4 - sub_cast_5;
|
||||
assign section_out6 = sub_temp_2[FILTER_WIDTH-1:0];
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin: comb_delay_section6
|
||||
if (reset == 1'b1) begin
|
||||
diff3 <= 0;
|
||||
end
|
||||
else begin
|
||||
if (phase_1 == 1'b1) begin
|
||||
diff3 <= section_in6;
|
||||
end
|
||||
end
|
||||
end // comb_delay_section6
|
||||
|
||||
// ------------------ Output Register ------------------
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin: output_reg_process
|
||||
if (reset == 1'b1) begin
|
||||
output_register <= 0;
|
||||
end
|
||||
else begin
|
||||
if (phase_1 == 1'b1) begin
|
||||
output_register <= section_out6;
|
||||
end
|
||||
end
|
||||
end // output_reg_process
|
||||
|
||||
// Assignment Statements
|
||||
assign ce_out = ce_out_reg;
|
||||
assign filter_out = output_register;
|
||||
endmodule // CIC_DOWN_S3
|
204
lib/common/Apply/DSP/Advance/Filter/CIC/CIC_DOWN_S4.v
Normal file
204
lib/common/Apply/DSP/Advance/Filter/CIC/CIC_DOWN_S4.v
Normal file
@ -0,0 +1,204 @@
|
||||
`timescale 1 ns / 1 ns
|
||||
module CIC_DOWN_S4 #(
|
||||
parameter FACTOR = 10,
|
||||
parameter INPUT_WIDTH = 12,
|
||||
parameter OUTPUT_WIDTH = 15
|
||||
) (
|
||||
input clk,
|
||||
input clk_enable,
|
||||
input reset,
|
||||
input signed [INPUT_WIDTH-1:0] filter_in,
|
||||
output signed [OUTPUT_WIDTH-1:0] filter_out,
|
||||
output ce_out
|
||||
);
|
||||
|
||||
localparam FILTER_WIDTH = OUTPUT_WIDTH;
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//Module Architecture: CIC_DOWN_S4
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Local Functions
|
||||
// Type Definitions
|
||||
// Constants
|
||||
// Signals
|
||||
reg [15:0] cur_count = 0; // ufix2
|
||||
wire phase_1; // boolean
|
||||
reg ce_out_reg = 0; // boolean
|
||||
//
|
||||
reg signed [INPUT_WIDTH-1:0] input_register = 0; // sfix16_En15
|
||||
// -- Section 1 Signals
|
||||
wire signed [INPUT_WIDTH-1:0] section_in1; // sfix16_En15
|
||||
wire signed [FILTER_WIDTH-1:0] section_cast1; // sfix20_En15
|
||||
wire signed [FILTER_WIDTH-1:0] sum1; // sfix20_En15
|
||||
reg signed [FILTER_WIDTH-1:0] section_out1 = 0; // sfix20_En15
|
||||
wire signed [FILTER_WIDTH-1:0] add_cast; // sfix20_En15
|
||||
wire signed [FILTER_WIDTH-1:0] add_cast_1; // sfix20_En15
|
||||
wire signed [FILTER_WIDTH:0] add_temp; // sfix21_En15
|
||||
// -- Section 2 Signals
|
||||
wire signed [FILTER_WIDTH-1:0] section_in2; // sfix20_En15
|
||||
wire signed [FILTER_WIDTH-1:0] sum2; // sfix20_En15
|
||||
reg signed [FILTER_WIDTH-1:0] section_out2 = 0; // sfix20_En15
|
||||
wire signed [FILTER_WIDTH-1:0] add_cast_2; // sfix20_En15
|
||||
wire signed [FILTER_WIDTH-1:0] add_cast_3; // sfix20_En15
|
||||
wire signed [FILTER_WIDTH:0] add_temp_1; // sfix21_En15
|
||||
// -- Section 3 Signals
|
||||
wire signed [FILTER_WIDTH-1:0] section_in3; // sfix20_En15
|
||||
reg signed [FILTER_WIDTH-1:0] diff1 = 0; // sfix20_En15
|
||||
wire signed [FILTER_WIDTH-1:0] section_out3; // sfix20_En15
|
||||
wire signed [FILTER_WIDTH-1:0] sub_cast; // sfix20_En15
|
||||
wire signed [FILTER_WIDTH-1:0] sub_cast_1; // sfix20_En15
|
||||
wire signed [FILTER_WIDTH:0] sub_temp; // sfix21_En15
|
||||
// -- Section 4 Signals
|
||||
wire signed [FILTER_WIDTH-1:0] section_in4; // sfix20_En15
|
||||
reg signed [FILTER_WIDTH-1:0] diff2 = 0; // sfix20_En15
|
||||
wire signed [FILTER_WIDTH-1:0] section_out4; // sfix20_En15
|
||||
wire signed [FILTER_WIDTH-1:0] sub_cast_2; // sfix20_En15
|
||||
wire signed [FILTER_WIDTH-1:0] sub_cast_3; // sfix20_En15
|
||||
wire signed [FILTER_WIDTH:0] sub_temp_1; // sfix21_En15
|
||||
//
|
||||
reg signed [FILTER_WIDTH-1:0] output_register = 0; // sfix20_En15
|
||||
|
||||
// Block Statements
|
||||
// ------------------ CE Output Generation ------------------
|
||||
|
||||
always @ (posedge clk or posedge reset) begin: ce_output
|
||||
if (reset == 1'b1) begin
|
||||
cur_count <= 16'd0;
|
||||
end
|
||||
else begin
|
||||
if (clk_enable == 1'b1) begin
|
||||
if (cur_count == FACTOR-1) begin
|
||||
cur_count <= 16'd0;
|
||||
end
|
||||
else begin
|
||||
cur_count <= cur_count + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end // ce_output
|
||||
|
||||
assign phase_1 = (cur_count == 16'd1 && clk_enable == 1'b1)? 1 : 0;
|
||||
|
||||
// ------------------ CE Output Register ------------------
|
||||
|
||||
always @ (posedge clk or posedge reset) begin: ce_output_register
|
||||
if (reset == 1'b1) begin
|
||||
ce_out_reg <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
ce_out_reg <= phase_1;
|
||||
end
|
||||
end // ce_output_register
|
||||
|
||||
// ------------------ Input Register ------------------
|
||||
|
||||
always @ (posedge clk or posedge reset) begin: input_reg_process
|
||||
if (reset == 1'b1) begin
|
||||
input_register <= 0;
|
||||
end
|
||||
else begin
|
||||
if (clk_enable == 1'b1) begin
|
||||
input_register <= filter_in;
|
||||
end
|
||||
end
|
||||
end // input_reg_process
|
||||
|
||||
// ------------------ Section # 1 : Integrator ------------------
|
||||
|
||||
assign section_in1 = input_register;
|
||||
|
||||
assign section_cast1 = $signed({{(FILTER_WIDTH-INPUT_WIDTH){section_in1[INPUT_WIDTH-1]}}, section_in1});
|
||||
|
||||
assign add_cast = section_cast1;
|
||||
assign add_cast_1 = section_out1;
|
||||
assign add_temp = add_cast + add_cast_1;
|
||||
assign sum1 = add_temp[FILTER_WIDTH-1:0];
|
||||
|
||||
always @ (posedge clk or posedge reset) begin: integrator_delay_section1
|
||||
if (reset == 1'b1) begin
|
||||
section_out1 <= 0;
|
||||
end
|
||||
else begin
|
||||
if (clk_enable == 1'b1) begin
|
||||
section_out1 <= sum1;
|
||||
end
|
||||
end
|
||||
end // integrator_delay_section1
|
||||
|
||||
// ------------------ Section # 2 : Integrator ------------------
|
||||
|
||||
assign section_in2 = section_out1;
|
||||
|
||||
assign add_cast_2 = section_in2;
|
||||
assign add_cast_3 = section_out2;
|
||||
assign add_temp_1 = add_cast_2 + add_cast_3;
|
||||
assign sum2 = add_temp_1[FILTER_WIDTH-1:0];
|
||||
|
||||
always @ (posedge clk or posedge reset) begin: integrator_delay_section2
|
||||
if (reset == 1'b1) begin
|
||||
section_out2 <= 0;
|
||||
end
|
||||
else begin
|
||||
if (clk_enable == 1'b1) begin
|
||||
section_out2 <= sum2;
|
||||
end
|
||||
end
|
||||
end // integrator_delay_section2
|
||||
|
||||
// ------------------ Section # 3 : Comb ------------------
|
||||
|
||||
assign section_in3 = section_out2;
|
||||
|
||||
assign sub_cast = section_in3;
|
||||
assign sub_cast_1 = diff1;
|
||||
assign sub_temp = sub_cast - sub_cast_1;
|
||||
assign section_out3 = sub_temp[FILTER_WIDTH-1:0];
|
||||
|
||||
always @ (posedge clk or posedge reset) begin: comb_delay_section3
|
||||
if (reset == 1'b1) begin
|
||||
diff1 <= 0;
|
||||
end
|
||||
else begin
|
||||
if (phase_1 == 1'b1) begin
|
||||
diff1 <= section_in3;
|
||||
end
|
||||
end
|
||||
end // comb_delay_section3
|
||||
|
||||
// ------------------ Section # 4 : Comb ------------------
|
||||
|
||||
assign section_in4 = section_out3;
|
||||
|
||||
assign sub_cast_2 = section_in4;
|
||||
assign sub_cast_3 = diff2;
|
||||
assign sub_temp_1 = sub_cast_2 - sub_cast_3;
|
||||
assign section_out4 = sub_temp_1[FILTER_WIDTH-1:0];
|
||||
|
||||
always @ (posedge clk or posedge reset) begin: comb_delay_section4
|
||||
if (reset == 1'b1) begin
|
||||
diff2 <= 0;
|
||||
end
|
||||
else begin
|
||||
if (phase_1 == 1'b1) begin
|
||||
diff2 <= section_in4;
|
||||
end
|
||||
end
|
||||
end // comb_delay_section4
|
||||
|
||||
// ------------------ Output Register ------------------
|
||||
|
||||
always @ (posedge clk or posedge reset) begin: output_reg_process
|
||||
if (reset == 1'b1) begin
|
||||
output_register <= 0;
|
||||
end
|
||||
else begin
|
||||
if (phase_1 == 1'b1) begin
|
||||
output_register <= section_out4;
|
||||
end
|
||||
end
|
||||
end // output_reg_process
|
||||
|
||||
// Assignment Statements
|
||||
assign ce_out = ce_out_reg;
|
||||
assign filter_out = output_register;
|
||||
endmodule // CIC_DOWN_S4
|
BIN
lib/common/Apply/DSP/Advance/PLL/Code/adfmreceiver.pdf
Normal file
BIN
lib/common/Apply/DSP/Advance/PLL/Code/adfmreceiver.pdf
Normal file
Binary file not shown.
43
lib/common/Apply/DSP/Advance/PLL/Code/circuit.v
Normal file
43
lib/common/Apply/DSP/Advance/PLL/Code/circuit.v
Normal file
@ -0,0 +1,43 @@
|
||||
module circuit(
|
||||
input clk,
|
||||
input reset,
|
||||
input [7:0] fmin,
|
||||
output [11:0] dmout
|
||||
);
|
||||
|
||||
wire [11:0] d1;
|
||||
wire [11:0] d2;
|
||||
wire [7:0] dout;
|
||||
wire [7:0] output_xhdl0;
|
||||
|
||||
multiplier I1(
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
.input1(fmin),
|
||||
.input2(dout),
|
||||
.output_xhdl0(output_xhdl0)
|
||||
);
|
||||
|
||||
fir I4(
|
||||
.clock(clk),
|
||||
.reset(reset),
|
||||
.data_in(d1),
|
||||
.data_out(dmout)
|
||||
);
|
||||
|
||||
loop_filter I3(
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
.c(output_xhdl0),
|
||||
.d1(d1),
|
||||
.d2(d2)
|
||||
);
|
||||
|
||||
nco I2(
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
.din(d2),
|
||||
.dout(dout)
|
||||
);
|
||||
|
||||
endmodule
|
72
lib/common/Apply/DSP/Advance/PLL/Code/fir.v
Normal file
72
lib/common/Apply/DSP/Advance/PLL/Code/fir.v
Normal file
@ -0,0 +1,72 @@
|
||||
module FIR(clock, reset, data_in, data_out);
|
||||
input clock;
|
||||
input reset;
|
||||
input [11:0] data_in;
|
||||
output [11:0] data_out;
|
||||
reg [11:0] data_out;
|
||||
|
||||
|
||||
reg [15:0] d0;
|
||||
reg [15:0] d1;
|
||||
reg [15:0] d2;
|
||||
reg [15:0] d3;
|
||||
reg [15:0] d4;
|
||||
reg [15:0] d5;
|
||||
reg [15:0] d6;
|
||||
reg [15:0] d7;
|
||||
reg [15:0] d8;
|
||||
reg [15:0] d9;
|
||||
reg [15:0] d10;
|
||||
reg [15:0] d11;
|
||||
reg [15:0] d12;
|
||||
reg [15:0] d13;
|
||||
reg [15:0] d14;
|
||||
reg [15:0] d15;
|
||||
reg [15:0] sum;
|
||||
|
||||
|
||||
always @(posedge clock or posedge reset)
|
||||
if (reset == 1'b1)
|
||||
begin
|
||||
d0 <= {16{1'b0}};
|
||||
d1 <= {16{1'b0}};
|
||||
d2 <= {16{1'b0}};
|
||||
d3 <= {16{1'b0}};
|
||||
d4 <= {16{1'b0}};
|
||||
d5 <= {16{1'b0}};
|
||||
d6 <= {16{1'b0}};
|
||||
d7 <= {16{1'b0}};
|
||||
d8 <= {16{1'b0}};
|
||||
d9 <= {16{1'b0}};
|
||||
d10 <= {16{1'b0}};
|
||||
d11 <= {16{1'b0}};
|
||||
d12 <= {16{1'b0}};
|
||||
d13 <= {16{1'b0}};
|
||||
d14 <= {16{1'b0}};
|
||||
d15 <= {16{1'b0}};
|
||||
sum <= {16{1'b0}};
|
||||
data_out <= {12{1'b0}};
|
||||
end
|
||||
else
|
||||
begin
|
||||
d0 <= {data_in[11], data_in[11], data_in[11], data_in[11], data_in};
|
||||
d1 <= d0;
|
||||
d2 <= d1;
|
||||
d3 <= d2;
|
||||
d4 <= d3;
|
||||
d5 <= d4;
|
||||
d6 <= d5;
|
||||
d7 <= d6;
|
||||
d8 <= d7;
|
||||
d9 <= d8;
|
||||
d10 <= d9;
|
||||
d11 <= d10;
|
||||
d12 <= d11;
|
||||
d13 <= d12;
|
||||
d14 <= d13;
|
||||
d15 <= d14;
|
||||
sum <= (d0 + d1 + d2 + d3 + d4 + d5 + d6 + d7 + d8 + d9 + d10 + d11 + d12 + d13 + d14 + d15) >> 4;
|
||||
data_out <= (sum[11:0]);
|
||||
end
|
||||
|
||||
endmodule
|
29
lib/common/Apply/DSP/Advance/PLL/Code/loop_filter.v
Normal file
29
lib/common/Apply/DSP/Advance/PLL/Code/loop_filter.v
Normal file
@ -0,0 +1,29 @@
|
||||
module loop_filter(CLK, RESET, C, D1, D2);
|
||||
input CLK;
|
||||
input RESET;
|
||||
input [7:0] C;
|
||||
output [11:0] D1;
|
||||
output [11:0] D2;
|
||||
reg [11:0] D1;
|
||||
reg [11:0] D2;
|
||||
|
||||
|
||||
reg [11:0] E;
|
||||
reg [11:0] dtemp;
|
||||
|
||||
|
||||
always @(posedge CLK or posedge RESET)
|
||||
if (RESET == 1'b1) begin
|
||||
D1 <= {12{1'b0}};
|
||||
D2 <= {12{1'b0}};
|
||||
E <= {12{1'b0}};
|
||||
dtemp <= {12{1'b0}};
|
||||
end
|
||||
else begin
|
||||
dtemp <= ({C[7], C[7], C[7], C, 1'b0}) + dtemp - E;
|
||||
E <= {dtemp[11], dtemp[11], dtemp[11], dtemp[11], dtemp[11:4]};
|
||||
D1 <= dtemp;
|
||||
D2 <= {dtemp[11:4], 4'b0000};
|
||||
end
|
||||
|
||||
endmodule
|
148
lib/common/Apply/DSP/Advance/PLL/Code/multiplier.v
Normal file
148
lib/common/Apply/DSP/Advance/PLL/Code/multiplier.v
Normal file
@ -0,0 +1,148 @@
|
||||
//--------------------------------------------------------------------------------------------
|
||||
//
|
||||
// Generated by X-HDL VHDL Translator - Version 2.0.0 Feb. 1, 2011
|
||||
// ?? 3? 29 2020 15:44:24
|
||||
//
|
||||
// Input file :
|
||||
// Component name : multiplier
|
||||
// Author :
|
||||
// Company :
|
||||
//
|
||||
// Description :
|
||||
//
|
||||
//
|
||||
//--------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
module multiplier(CLK, RESET, input1, input2, output_xhdl0);
|
||||
input CLK;
|
||||
input RESET;
|
||||
input [7:0] input1;
|
||||
input [7:0] input2;
|
||||
output [7:0] output_xhdl0;
|
||||
reg [7:0] output_xhdl0;
|
||||
|
||||
|
||||
reg [15:0] out_temp;
|
||||
reg [15:0] input1_buf;
|
||||
reg [15:0] part0;
|
||||
reg [15:0] part1;
|
||||
reg [15:0] part2;
|
||||
reg [15:0] part3;
|
||||
reg [15:0] part4;
|
||||
reg [15:0] part5;
|
||||
reg [15:0] part6;
|
||||
reg [15:0] part7;
|
||||
|
||||
|
||||
always @(posedge CLK or posedge RESET)
|
||||
if (RESET == 1'b1)
|
||||
begin
|
||||
out_temp <= {16{1'b0}};
|
||||
output_xhdl0 <= {8{1'b0}};
|
||||
input1_buf <= {16{1'b0}};
|
||||
part0 <= {16{1'b0}};
|
||||
part1 <= {16{1'b0}};
|
||||
part2 <= {16{1'b0}};
|
||||
part3 <= {16{1'b0}};
|
||||
part4 <= {16{1'b0}};
|
||||
part5 <= {16{1'b0}};
|
||||
part6 <= {16{1'b0}};
|
||||
part7 <= {16{1'b0}};
|
||||
end
|
||||
else
|
||||
begin
|
||||
input1_buf <= {input1[7], input1[7], input1[7], input1[7], input1[7], input1[7], input1[7], input1[7], signed_xhdl1(input1)};
|
||||
if (input2[0] == 1'b1)
|
||||
part0 <= -(input1_buf);
|
||||
else
|
||||
part0 <= {16{1'b0}};
|
||||
if (input2[1] == 1'b1)
|
||||
begin
|
||||
if (input2[0] == 1'b1)
|
||||
part1 <= {16{1'b0}};
|
||||
else
|
||||
part1 <= -(input1_buf);
|
||||
end
|
||||
else
|
||||
if (input2[0] == 1'b1)
|
||||
part1 <= input1_buf;
|
||||
else
|
||||
part1 <= {16{1'b0}};
|
||||
if (input2[2] == 1'b1)
|
||||
begin
|
||||
if (input2[1] == 1'b1)
|
||||
part2 <= {16{1'b0}};
|
||||
else
|
||||
part2 <= -(input1_buf);
|
||||
end
|
||||
else
|
||||
if (input2[1] == 1'b1)
|
||||
part2 <= input1_buf;
|
||||
else
|
||||
part2 <= {16{1'b0}};
|
||||
if (input2[3] == 1'b1)
|
||||
begin
|
||||
if (input2[2] == 1'b1)
|
||||
part3 <= {16{1'b0}};
|
||||
else
|
||||
part3 <= -(input1_buf);
|
||||
end
|
||||
else
|
||||
if (input2[2] == 1'b1)
|
||||
part3 <= input1_buf;
|
||||
else
|
||||
part3 <= {16{1'b0}};
|
||||
if (input2[4] == 1'b1)
|
||||
begin
|
||||
if (input2[3] == 1'b1)
|
||||
part4 <= {16{1'b0}};
|
||||
else
|
||||
part4 <= -(input1_buf);
|
||||
end
|
||||
else
|
||||
if (input2[3] == 1'b1)
|
||||
part4 <= input1_buf;
|
||||
else
|
||||
part4 <= {16{1'b0}};
|
||||
if (input2[5] == 1'b1)
|
||||
begin
|
||||
if (input2[4] == 1'b1)
|
||||
part5 <= {16{1'b0}};
|
||||
else
|
||||
part5 <= -(input1_buf);
|
||||
end
|
||||
else
|
||||
if (input2[4] == 1'b1)
|
||||
part5 <= input1_buf;
|
||||
else
|
||||
part5 <= {16{1'b0}};
|
||||
if (input2[6] == 1'b1)
|
||||
begin
|
||||
if (input2[5] == 1'b1)
|
||||
part6 <= {16{1'b0}};
|
||||
else
|
||||
part6 <= -(input1_buf);
|
||||
end
|
||||
else
|
||||
if (input2[5] == 1'b1)
|
||||
part6 <= input1_buf;
|
||||
else
|
||||
part6 <= {16{1'b0}};
|
||||
if (input2[7] == 1'b1)
|
||||
begin
|
||||
if (input2[6] == 1'b1)
|
||||
part7 <= {16{1'b0}};
|
||||
else
|
||||
part7 <= -(input1_buf);
|
||||
end
|
||||
else
|
||||
if (input2[6] == 1'b1)
|
||||
part7 <= input1_buf;
|
||||
else
|
||||
part7 <= {16{1'b0}};
|
||||
out_temp <= part0 + ({part1[14:0], 1'b0}) + ({part2[13:0], 2'b00}) + ({part3[12:0], 3'b000}) + ({part4[11:0], 4'b0000}) + ({part5[10:0], 5'b00000}) + ({part6[9:0], 6'b000000}) + ({part7[8:0], 7'b0000000});
|
||||
output_xhdl0 <= out_temp[15:8];
|
||||
end
|
||||
|
||||
endmodule
|
BIN
lib/common/Apply/DSP/Advance/PLL/Image/architecture.png
Normal file
BIN
lib/common/Apply/DSP/Advance/PLL/Image/architecture.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
BIN
lib/common/Apply/DSP/Advance/PLL/Image/fmsquare.jpg
Normal file
BIN
lib/common/Apply/DSP/Advance/PLL/Image/fmsquare.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
BIN
lib/common/Apply/DSP/Advance/PLL/Image/fmtriangular.jpg
Normal file
BIN
lib/common/Apply/DSP/Advance/PLL/Image/fmtriangular.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
90
lib/common/Apply/DSP/Base/CLK/CLK_DIV.v
Normal file
90
lib/common/Apply/DSP/Base/CLK/CLK_DIV.v
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
奇数倍分频:奇数倍分频常常在论坛上有人问起,实际上,奇数倍分频有两种实现方法:
|
||||
首先,完全可以通过计数器来实现,如进行三分频,通过待分频时钟 上升沿触发计数器进行模三计数,
|
||||
当计数器计数到邻近值进行两次翻转,比如可以在计数器计数到1时,输出时钟进行翻转,计数到2时再次进行翻转。
|
||||
即是在计数 值在邻近的1和2进行了两次翻转。这样实现的三分频占空比为1/3或者2/3。
|
||||
|
||||
如果要实现占空比为50%的三分频时钟,
|
||||
可以通过待分频时钟下降沿触发计数,和上升沿同样的方法计数进行三分频,
|
||||
然后下降沿产生的三分频时钟和上升沿产生的时钟进行相或运算,即可得到占空比为50%的三分频时钟。
|
||||
这种方法可以 实现任意的奇数分频。
|
||||
归类为一般的方法为:对于实现占空比为50%的N倍奇数分频,
|
||||
首先进行上升沿触发进行模N计数,计数选定到某一个值进行输出时钟翻 转,然后经过(N-1)/2再次进行翻转得到一个占空比非50%奇数n分频时钟。
|
||||
再者同时进行下降沿触发的模N计数,到和上升沿触发输出时钟翻转选定值相 同值时,
|
||||
进行输出时钟时钟翻转,同样经过(N-1)/2时,输出时钟再次翻转生成占空比非50%的奇数n分频时钟。
|
||||
两个占空比非50%的n分频时钟相或运 算,得到占空比为50%的奇数n分频时钟。
|
||||
|
||||
另外一种方法:对进行奇数倍n分频时钟,首先进行n/2分频(带小数,即等于(n-1)/2+0.5),
|
||||
然后再 进行二分频得到。得到占空比为50%的奇数倍分频。
|
||||
*/
|
||||
|
||||
/*******************************************************************************/
|
||||
// wire clk_div;
|
||||
// CLK_DIV #
|
||||
// (.WIDTH(8))
|
||||
// CLK_DIV_u
|
||||
// (
|
||||
// .clk_in(clk_sys),
|
||||
// .rst_n(1'b1),
|
||||
// .N(2),
|
||||
// .clk_div(clk_div)
|
||||
// );
|
||||
/*******************************************************************************/
|
||||
`timescale 1ns / 1ps
|
||||
module CLK_DIV #
|
||||
(
|
||||
parameter WIDTH = 8
|
||||
)
|
||||
(
|
||||
input clk_in,
|
||||
input rst_n,
|
||||
input [WIDTH - 1:0] N,
|
||||
output clk_div
|
||||
);
|
||||
|
||||
reg [WIDTH-1:0] cnt_p = 0;// 上升沿计数单位
|
||||
reg [WIDTH-1:0] cnt_n = 0;// 下降沿计数单位
|
||||
reg clk_in_p = 0;// 上升沿时钟
|
||||
reg clk_in_n = 0;// 下降沿时钟
|
||||
|
||||
//其中N==1是判断不分频,N[0]是判断是奇数还是偶数,若为1则是奇数分频,若是偶数则是偶数分频。
|
||||
assign clk_div = (N == 1) ? clk_in : (N[0]) ? (clk_in_p | clk_in_n) : (clk_in_p);
|
||||
|
||||
always@(posedge clk_in or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
cnt_p <= 0;
|
||||
else if (cnt_p == (N-1))
|
||||
cnt_p <= 0;
|
||||
else
|
||||
cnt_p <= cnt_p + 1;
|
||||
end
|
||||
|
||||
always@(posedge clk_in or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
clk_in_p <= 1;//此处设置为0也是可以的,这个没有硬性的要求,不管是取0还是取1结果都是正确的。
|
||||
else if (cnt_p < (N>>1))/*N整体向右移动一位,最高位补零,其实就是N/2,不过在计算奇数的时候有很明显的优越性*/
|
||||
clk_in_p <= 1;
|
||||
else
|
||||
clk_in_p <= 0;
|
||||
end
|
||||
|
||||
always@(negedge clk_in or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
cnt_n <= 0;
|
||||
else if (cnt_n == (N-1))
|
||||
cnt_n <= 0;
|
||||
else
|
||||
cnt_n <= cnt_n + 1;
|
||||
end
|
||||
|
||||
always@(negedge clk_in or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
clk_in_n <= 1;
|
||||
else if (cnt_n < (N>>1))
|
||||
clk_in_n <= 1;
|
||||
else
|
||||
clk_in_n <= 0;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
19
lib/common/Apply/DSP/Base/CLK/CLK_Sample.v
Normal file
19
lib/common/Apply/DSP/Base/CLK/CLK_Sample.v
Normal file
@ -0,0 +1,19 @@
|
||||
module CLK_Sample # (
|
||||
parameter PHASE_WIDTH = 32
|
||||
) (
|
||||
input clk_in,
|
||||
input RST,
|
||||
input [PHASE_WIDTH-1:0] sample_fre,
|
||||
output clk_sample
|
||||
);
|
||||
|
||||
reg [PHASE_WIDTH-1:0] addr_r = 0;
|
||||
always @(posedge clk_in) begin
|
||||
if (RST)
|
||||
addr_r <= 32'd0;
|
||||
else
|
||||
addr_r <= addr_r + sample_fre;
|
||||
end
|
||||
assign clk_sample = addr_r[PHASE_WIDTH-1];
|
||||
|
||||
endmodule
|
327
lib/common/Apply/DSP/Base/DDS/DDS_Gen.v
Normal file
327
lib/common/Apply/DSP/Base/DDS/DDS_Gen.v
Normal file
@ -0,0 +1,327 @@
|
||||
module DDS_Gen #(
|
||||
parameter OUTPUT_WIDTH = 12,
|
||||
parameter PHASE_WIDTH = 32
|
||||
) (
|
||||
input clk,
|
||||
input [PHASE_WIDTH - 1 : 0] Fre_word, // (fre*4294967296)/clk/1000000
|
||||
input [PHASE_WIDTH - 1 : 0] Pha_word, // (fre*4294967296)/clk/1000000
|
||||
output [OUTPUT_WIDTH - 1 : 0] wave_out_sin,
|
||||
output [OUTPUT_WIDTH - 1 : 0] wave_out_tri,
|
||||
output [OUTPUT_WIDTH - 1 : 0] wave_out_saw
|
||||
);
|
||||
|
||||
localparam [OUTPUT_WIDTH - 1 : 0] DC_SUB = 2**(OUTPUT_WIDTH-1);
|
||||
|
||||
reg [OUTPUT_WIDTH - 1 : 0] wave_out_sin_r;
|
||||
reg [OUTPUT_WIDTH - 1 : 0] wave_out_tri_r;
|
||||
reg [OUTPUT_WIDTH - 1 : 0] wave_out_saw_r;
|
||||
|
||||
reg [PHASE_WIDTH - 1 : 0] addr_r0 = 0;
|
||||
reg [PHASE_WIDTH - 1 : 0] addr_r1 = 0;
|
||||
always @(posedge clk) begin
|
||||
addr_r0 <= addr_r0 + Fre_word;
|
||||
addr_r1 <= addr_r0 + Pha_word;
|
||||
end
|
||||
|
||||
|
||||
always @(posedge clk ) begin
|
||||
wave_out_saw_r <= addr_r1[PHASE_WIDTH - 1 : PHASE_WIDTH - OUTPUT_WIDTH];
|
||||
end
|
||||
assign wave_out_saw = wave_out_saw_r;
|
||||
|
||||
always @(posedge clk ) begin
|
||||
if (addr_r1[PHASE_WIDTH - 1])
|
||||
wave_out_tri_r <= (2**(OUTPUT_WIDTH + 1)-1) - addr_r1[PHASE_WIDTH - 1 : PHASE_WIDTH - OUTPUT_WIDTH - 1];
|
||||
else
|
||||
wave_out_tri_r <= addr_r1[PHASE_WIDTH - 1 : PHASE_WIDTH - OUTPUT_WIDTH - 1];
|
||||
end
|
||||
assign wave_out_tri = wave_out_tri_r - DC_SUB;
|
||||
|
||||
reg [9:0] addr_r = 0;
|
||||
always @(posedge clk) begin
|
||||
addr_r <= addr_r1[PHASE_WIDTH - 1 : PHASE_WIDTH - 10];
|
||||
end
|
||||
|
||||
reg [7:0] addr;
|
||||
always @(*) begin
|
||||
case (addr_r[9:8])
|
||||
2'b00 : begin addr <= addr_r[7:0]; end
|
||||
2'b01 : begin addr <= addr_r[7:0] ^ 8'b1111_1111; end
|
||||
2'b10 : begin addr <= addr_r[7:0]; end
|
||||
2'b11 : begin addr <= addr_r[7:0] ^ 8'b1111_1111; end
|
||||
default : begin addr <= 8'd0; end
|
||||
endcase
|
||||
end
|
||||
|
||||
reg signed [13:0] wave_sin_buf;
|
||||
always @(*) begin
|
||||
case (addr)
|
||||
8'd0 : begin wave_sin_buf <= 0; end
|
||||
8'd1 : begin wave_sin_buf <= 50; end
|
||||
8'd2 : begin wave_sin_buf <= 101; end
|
||||
8'd3 : begin wave_sin_buf <= 151; end
|
||||
8'd4 : begin wave_sin_buf <= 201; end
|
||||
8'd5 : begin wave_sin_buf <= 252; end
|
||||
8'd6 : begin wave_sin_buf <= 302; end
|
||||
8'd7 : begin wave_sin_buf <= 352; end
|
||||
8'd8 : begin wave_sin_buf <= 402; end
|
||||
8'd9 : begin wave_sin_buf <= 453; end
|
||||
8'd10 : begin wave_sin_buf <= 503; end
|
||||
8'd11 : begin wave_sin_buf <= 553; end
|
||||
8'd12 : begin wave_sin_buf <= 603; end
|
||||
8'd13 : begin wave_sin_buf <= 653; end
|
||||
8'd14 : begin wave_sin_buf <= 703; end
|
||||
8'd15 : begin wave_sin_buf <= 754; end
|
||||
8'd16 : begin wave_sin_buf <= 804; end
|
||||
8'd17 : begin wave_sin_buf <= 854; end
|
||||
8'd18 : begin wave_sin_buf <= 904; end
|
||||
8'd19 : begin wave_sin_buf <= 954; end
|
||||
8'd20 : begin wave_sin_buf <= 1004; end
|
||||
8'd21 : begin wave_sin_buf <= 1054; end
|
||||
8'd22 : begin wave_sin_buf <= 1103; end
|
||||
8'd23 : begin wave_sin_buf <= 1153; end
|
||||
8'd24 : begin wave_sin_buf <= 1203; end
|
||||
8'd25 : begin wave_sin_buf <= 1253; end
|
||||
8'd26 : begin wave_sin_buf <= 1302; end
|
||||
8'd27 : begin wave_sin_buf <= 1352; end
|
||||
8'd28 : begin wave_sin_buf <= 1402; end
|
||||
8'd29 : begin wave_sin_buf <= 1451; end
|
||||
8'd30 : begin wave_sin_buf <= 1501; end
|
||||
8'd31 : begin wave_sin_buf <= 1550; end
|
||||
8'd32 : begin wave_sin_buf <= 1600; end
|
||||
8'd33 : begin wave_sin_buf <= 1649; end
|
||||
8'd34 : begin wave_sin_buf <= 1698; end
|
||||
8'd35 : begin wave_sin_buf <= 1747; end
|
||||
8'd36 : begin wave_sin_buf <= 1796; end
|
||||
8'd37 : begin wave_sin_buf <= 1845; end
|
||||
8'd38 : begin wave_sin_buf <= 1894; end
|
||||
8'd39 : begin wave_sin_buf <= 1943; end
|
||||
8'd40 : begin wave_sin_buf <= 1992; end
|
||||
8'd41 : begin wave_sin_buf <= 2041; end
|
||||
8'd42 : begin wave_sin_buf <= 2090; end
|
||||
8'd43 : begin wave_sin_buf <= 2138; end
|
||||
8'd44 : begin wave_sin_buf <= 2187; end
|
||||
8'd45 : begin wave_sin_buf <= 2235; end
|
||||
8'd46 : begin wave_sin_buf <= 2284; end
|
||||
8'd47 : begin wave_sin_buf <= 2332; end
|
||||
8'd48 : begin wave_sin_buf <= 2380; end
|
||||
8'd49 : begin wave_sin_buf <= 2428; end
|
||||
8'd50 : begin wave_sin_buf <= 2476; end
|
||||
8'd51 : begin wave_sin_buf <= 2524; end
|
||||
8'd52 : begin wave_sin_buf <= 2572; end
|
||||
8'd53 : begin wave_sin_buf <= 2620; end
|
||||
8'd54 : begin wave_sin_buf <= 2667; end
|
||||
8'd55 : begin wave_sin_buf <= 2715; end
|
||||
8'd56 : begin wave_sin_buf <= 2762; end
|
||||
8'd57 : begin wave_sin_buf <= 2809; end
|
||||
8'd58 : begin wave_sin_buf <= 2857; end
|
||||
8'd59 : begin wave_sin_buf <= 2904; end
|
||||
8'd60 : begin wave_sin_buf <= 2951; end
|
||||
8'd61 : begin wave_sin_buf <= 2998; end
|
||||
8'd62 : begin wave_sin_buf <= 3044; end
|
||||
8'd63 : begin wave_sin_buf <= 3091; end
|
||||
8'd64 : begin wave_sin_buf <= 3137; end
|
||||
8'd65 : begin wave_sin_buf <= 3184; end
|
||||
8'd66 : begin wave_sin_buf <= 3230; end
|
||||
8'd67 : begin wave_sin_buf <= 3276; end
|
||||
8'd68 : begin wave_sin_buf <= 3322; end
|
||||
8'd69 : begin wave_sin_buf <= 3368; end
|
||||
8'd70 : begin wave_sin_buf <= 3414; end
|
||||
8'd71 : begin wave_sin_buf <= 3460; end
|
||||
8'd72 : begin wave_sin_buf <= 3505; end
|
||||
8'd73 : begin wave_sin_buf <= 3551; end
|
||||
8'd74 : begin wave_sin_buf <= 3596; end
|
||||
8'd75 : begin wave_sin_buf <= 3641; end
|
||||
8'd76 : begin wave_sin_buf <= 3686; end
|
||||
8'd77 : begin wave_sin_buf <= 3731; end
|
||||
8'd78 : begin wave_sin_buf <= 3776; end
|
||||
8'd79 : begin wave_sin_buf <= 3820; end
|
||||
8'd80 : begin wave_sin_buf <= 3865; end
|
||||
8'd81 : begin wave_sin_buf <= 3909; end
|
||||
8'd82 : begin wave_sin_buf <= 3953; end
|
||||
8'd83 : begin wave_sin_buf <= 3997; end
|
||||
8'd84 : begin wave_sin_buf <= 4041; end
|
||||
8'd85 : begin wave_sin_buf <= 4085; end
|
||||
8'd86 : begin wave_sin_buf <= 4128; end
|
||||
8'd87 : begin wave_sin_buf <= 4172; end
|
||||
8'd88 : begin wave_sin_buf <= 4215; end
|
||||
8'd89 : begin wave_sin_buf <= 4258; end
|
||||
8'd90 : begin wave_sin_buf <= 4301; end
|
||||
8'd91 : begin wave_sin_buf <= 4343; end
|
||||
8'd92 : begin wave_sin_buf <= 4386; end
|
||||
8'd93 : begin wave_sin_buf <= 4428; end
|
||||
8'd94 : begin wave_sin_buf <= 4471; end
|
||||
8'd95 : begin wave_sin_buf <= 4513; end
|
||||
8'd96 : begin wave_sin_buf <= 4555; end
|
||||
8'd97 : begin wave_sin_buf <= 4596; end
|
||||
8'd98 : begin wave_sin_buf <= 4638; end
|
||||
8'd99 : begin wave_sin_buf <= 4679; end
|
||||
8'd100 : begin wave_sin_buf <= 4720; end
|
||||
8'd101 : begin wave_sin_buf <= 4761; end
|
||||
8'd102 : begin wave_sin_buf <= 4802; end
|
||||
8'd103 : begin wave_sin_buf <= 4843; end
|
||||
8'd104 : begin wave_sin_buf <= 4883; end
|
||||
8'd105 : begin wave_sin_buf <= 4924; end
|
||||
8'd106 : begin wave_sin_buf <= 4964; end
|
||||
8'd107 : begin wave_sin_buf <= 5004; end
|
||||
8'd108 : begin wave_sin_buf <= 5044; end
|
||||
8'd109 : begin wave_sin_buf <= 5083; end
|
||||
8'd110 : begin wave_sin_buf <= 5122; end
|
||||
8'd111 : begin wave_sin_buf <= 5162; end
|
||||
8'd112 : begin wave_sin_buf <= 5201; end
|
||||
8'd113 : begin wave_sin_buf <= 5239; end
|
||||
8'd114 : begin wave_sin_buf <= 5278; end
|
||||
8'd115 : begin wave_sin_buf <= 5316; end
|
||||
8'd116 : begin wave_sin_buf <= 5354; end
|
||||
8'd117 : begin wave_sin_buf <= 5392; end
|
||||
8'd118 : begin wave_sin_buf <= 5430; end
|
||||
8'd119 : begin wave_sin_buf <= 5468; end
|
||||
8'd120 : begin wave_sin_buf <= 5505; end
|
||||
8'd121 : begin wave_sin_buf <= 5542; end
|
||||
8'd122 : begin wave_sin_buf <= 5579; end
|
||||
8'd123 : begin wave_sin_buf <= 5616; end
|
||||
8'd124 : begin wave_sin_buf <= 5652; end
|
||||
8'd125 : begin wave_sin_buf <= 5689; end
|
||||
8'd126 : begin wave_sin_buf <= 5725; end
|
||||
8'd127 : begin wave_sin_buf <= 5761; end
|
||||
8'd128 : begin wave_sin_buf <= 5796; end
|
||||
8'd129 : begin wave_sin_buf <= 5832; end
|
||||
8'd130 : begin wave_sin_buf <= 5867; end
|
||||
8'd131 : begin wave_sin_buf <= 5902; end
|
||||
8'd132 : begin wave_sin_buf <= 5937; end
|
||||
8'd133 : begin wave_sin_buf <= 5971; end
|
||||
8'd134 : begin wave_sin_buf <= 6006; end
|
||||
8'd135 : begin wave_sin_buf <= 6040; end
|
||||
8'd136 : begin wave_sin_buf <= 6074; end
|
||||
8'd137 : begin wave_sin_buf <= 6107; end
|
||||
8'd138 : begin wave_sin_buf <= 6141; end
|
||||
8'd139 : begin wave_sin_buf <= 6174; end
|
||||
8'd140 : begin wave_sin_buf <= 6207; end
|
||||
8'd141 : begin wave_sin_buf <= 6239; end
|
||||
8'd142 : begin wave_sin_buf <= 6272; end
|
||||
8'd143 : begin wave_sin_buf <= 6304; end
|
||||
8'd144 : begin wave_sin_buf <= 6336; end
|
||||
8'd145 : begin wave_sin_buf <= 6368; end
|
||||
8'd146 : begin wave_sin_buf <= 6399; end
|
||||
8'd147 : begin wave_sin_buf <= 6431; end
|
||||
8'd148 : begin wave_sin_buf <= 6462; end
|
||||
8'd149 : begin wave_sin_buf <= 6493; end
|
||||
8'd150 : begin wave_sin_buf <= 6523; end
|
||||
8'd151 : begin wave_sin_buf <= 6553; end
|
||||
8'd152 : begin wave_sin_buf <= 6584; end
|
||||
8'd153 : begin wave_sin_buf <= 6613; end
|
||||
8'd154 : begin wave_sin_buf <= 6643; end
|
||||
8'd155 : begin wave_sin_buf <= 6672; end
|
||||
8'd156 : begin wave_sin_buf <= 6701; end
|
||||
8'd157 : begin wave_sin_buf <= 6730; end
|
||||
8'd158 : begin wave_sin_buf <= 6759; end
|
||||
8'd159 : begin wave_sin_buf <= 6787; end
|
||||
8'd160 : begin wave_sin_buf <= 6815; end
|
||||
8'd161 : begin wave_sin_buf <= 6843; end
|
||||
8'd162 : begin wave_sin_buf <= 6870; end
|
||||
8'd163 : begin wave_sin_buf <= 6897; end
|
||||
8'd164 : begin wave_sin_buf <= 6925; end
|
||||
8'd165 : begin wave_sin_buf <= 6951; end
|
||||
8'd166 : begin wave_sin_buf <= 6978; end
|
||||
8'd167 : begin wave_sin_buf <= 7004; end
|
||||
8'd168 : begin wave_sin_buf <= 7030; end
|
||||
8'd169 : begin wave_sin_buf <= 7056; end
|
||||
8'd170 : begin wave_sin_buf <= 7081; end
|
||||
8'd171 : begin wave_sin_buf <= 7106; end
|
||||
8'd172 : begin wave_sin_buf <= 7131; end
|
||||
8'd173 : begin wave_sin_buf <= 7156; end
|
||||
8'd174 : begin wave_sin_buf <= 7180; end
|
||||
8'd175 : begin wave_sin_buf <= 7204; end
|
||||
8'd176 : begin wave_sin_buf <= 7228; end
|
||||
8'd177 : begin wave_sin_buf <= 7251; end
|
||||
8'd178 : begin wave_sin_buf <= 7275; end
|
||||
8'd179 : begin wave_sin_buf <= 7298; end
|
||||
8'd180 : begin wave_sin_buf <= 7320; end
|
||||
8'd181 : begin wave_sin_buf <= 7343; end
|
||||
8'd182 : begin wave_sin_buf <= 7365; end
|
||||
8'd183 : begin wave_sin_buf <= 7387; end
|
||||
8'd184 : begin wave_sin_buf <= 7408; end
|
||||
8'd185 : begin wave_sin_buf <= 7430; end
|
||||
8'd186 : begin wave_sin_buf <= 7451; end
|
||||
8'd187 : begin wave_sin_buf <= 7472; end
|
||||
8'd188 : begin wave_sin_buf <= 7492; end
|
||||
8'd189 : begin wave_sin_buf <= 7512; end
|
||||
8'd190 : begin wave_sin_buf <= 7532; end
|
||||
8'd191 : begin wave_sin_buf <= 7552; end
|
||||
8'd192 : begin wave_sin_buf <= 7571; end
|
||||
8'd193 : begin wave_sin_buf <= 7590; end
|
||||
8'd194 : begin wave_sin_buf <= 7609; end
|
||||
8'd195 : begin wave_sin_buf <= 7627; end
|
||||
8'd196 : begin wave_sin_buf <= 7646; end
|
||||
8'd197 : begin wave_sin_buf <= 7664; end
|
||||
8'd198 : begin wave_sin_buf <= 7681; end
|
||||
8'd199 : begin wave_sin_buf <= 7698; end
|
||||
8'd200 : begin wave_sin_buf <= 7715; end
|
||||
8'd201 : begin wave_sin_buf <= 7732; end
|
||||
8'd202 : begin wave_sin_buf <= 7749; end
|
||||
8'd203 : begin wave_sin_buf <= 7765; end
|
||||
8'd204 : begin wave_sin_buf <= 7781; end
|
||||
8'd205 : begin wave_sin_buf <= 7796; end
|
||||
8'd206 : begin wave_sin_buf <= 7812; end
|
||||
8'd207 : begin wave_sin_buf <= 7827; end
|
||||
8'd208 : begin wave_sin_buf <= 7841; end
|
||||
8'd209 : begin wave_sin_buf <= 7856; end
|
||||
8'd210 : begin wave_sin_buf <= 7870; end
|
||||
8'd211 : begin wave_sin_buf <= 7884; end
|
||||
8'd212 : begin wave_sin_buf <= 7897; end
|
||||
8'd213 : begin wave_sin_buf <= 7910; end
|
||||
8'd214 : begin wave_sin_buf <= 7923; end
|
||||
8'd215 : begin wave_sin_buf <= 7936; end
|
||||
8'd216 : begin wave_sin_buf <= 7948; end
|
||||
8'd217 : begin wave_sin_buf <= 7960; end
|
||||
8'd218 : begin wave_sin_buf <= 7972; end
|
||||
8'd219 : begin wave_sin_buf <= 7983; end
|
||||
8'd220 : begin wave_sin_buf <= 7994; end
|
||||
8'd221 : begin wave_sin_buf <= 8005; end
|
||||
8'd222 : begin wave_sin_buf <= 8016; end
|
||||
8'd223 : begin wave_sin_buf <= 8026; end
|
||||
8'd224 : begin wave_sin_buf <= 8036; end
|
||||
8'd225 : begin wave_sin_buf <= 8045; end
|
||||
8'd226 : begin wave_sin_buf <= 8055; end
|
||||
8'd227 : begin wave_sin_buf <= 8064; end
|
||||
8'd228 : begin wave_sin_buf <= 8072; end
|
||||
8'd229 : begin wave_sin_buf <= 8081; end
|
||||
8'd230 : begin wave_sin_buf <= 8089; end
|
||||
8'd231 : begin wave_sin_buf <= 8097; end
|
||||
8'd232 : begin wave_sin_buf <= 8104; end
|
||||
8'd233 : begin wave_sin_buf <= 8111; end
|
||||
8'd234 : begin wave_sin_buf <= 8118; end
|
||||
8'd235 : begin wave_sin_buf <= 8125; end
|
||||
8'd236 : begin wave_sin_buf <= 8131; end
|
||||
8'd237 : begin wave_sin_buf <= 8137; end
|
||||
8'd238 : begin wave_sin_buf <= 8142; end
|
||||
8'd239 : begin wave_sin_buf <= 8148; end
|
||||
8'd240 : begin wave_sin_buf <= 8153; end
|
||||
8'd241 : begin wave_sin_buf <= 8157; end
|
||||
8'd242 : begin wave_sin_buf <= 8162; end
|
||||
8'd243 : begin wave_sin_buf <= 8166; end
|
||||
8'd244 : begin wave_sin_buf <= 8170; end
|
||||
8'd245 : begin wave_sin_buf <= 8173; end
|
||||
8'd246 : begin wave_sin_buf <= 8176; end
|
||||
8'd247 : begin wave_sin_buf <= 8179; end
|
||||
8'd248 : begin wave_sin_buf <= 8182; end
|
||||
8'd249 : begin wave_sin_buf <= 8184; end
|
||||
8'd250 : begin wave_sin_buf <= 8186; end
|
||||
8'd251 : begin wave_sin_buf <= 8188; end
|
||||
8'd252 : begin wave_sin_buf <= 8189; end
|
||||
8'd253 : begin wave_sin_buf <= 8190; end
|
||||
8'd254 : begin wave_sin_buf <= 8191; end
|
||||
8'd255 : begin wave_sin_buf <= 8191; end
|
||||
default : begin wave_sin_buf <= 0; end
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
case (addr_r[9])
|
||||
1'b0 : begin wave_out_sin_r <= wave_sin_buf[13 : 14 - OUTPUT_WIDTH]; end
|
||||
1'b1 : begin wave_out_sin_r <= -wave_sin_buf[13 : 14 - OUTPUT_WIDTH]; end
|
||||
default : begin wave_out_sin_r <= 14'd0; end
|
||||
endcase
|
||||
end
|
||||
assign wave_out_sin = wave_out_sin_r;
|
||||
endmodule
|
96
lib/common/Apply/DSP/Base/Measure/Fre_meas.v
Normal file
96
lib/common/Apply/DSP/Base/Measure/Fre_meas.v
Normal file
@ -0,0 +1,96 @@
|
||||
module Fre_meas(
|
||||
input clk_in,
|
||||
input square,
|
||||
input [31:0] GATE_TIME,
|
||||
output [31:0] CNTCLK, //闸门内系统时钟周期计数
|
||||
output [31:0] CNTSQU //闸门内待测方波时钟周期计数
|
||||
);
|
||||
//parameter GATE_TIME = 28'd49_999_999;//实际闸门计数是99_999_999,仿真时设为10ms
|
||||
|
||||
reg square_r0 = 1'b0;
|
||||
reg square_r1 = 1'b0;
|
||||
reg square_r2 = 1'b0;
|
||||
reg square_r3 = 1'b0;
|
||||
|
||||
reg gate = 1'b0; //闸门信号
|
||||
reg gatebuf = 1'b0; //与方波同步之后的闸门信号
|
||||
reg gatebuf1 = 1'b0;//同步闸门信号延时一拍
|
||||
|
||||
reg [31:0] cnt1 = 28'd0; //产生 1s 的闸门信号的计数器
|
||||
reg [31:0] cnt2 = 28'd0;
|
||||
reg [31:0] cnt2_r = 28'd0;
|
||||
reg [31:0] cnt3 = 28'd0;
|
||||
reg [31:0] cnt3_r = 28'd0;
|
||||
|
||||
wire square_pose,square_nege;
|
||||
wire gate_start,gate_end;
|
||||
|
||||
//使方波和100MHz时钟同步并捕捉待测方波的边沿
|
||||
always @ (posedge clk_in)
|
||||
begin
|
||||
square_r0 <= square;
|
||||
square_r1 <= square_r0;//将外部输入的方波打两拍
|
||||
square_r2 <= square_r1;
|
||||
square_r3 <= square_r2;
|
||||
end
|
||||
|
||||
assign square_pose = square_r2 & ~square_r3;
|
||||
assign square_nege = ~square_r2 & square_r3;
|
||||
|
||||
always @ (posedge clk_in)
|
||||
begin
|
||||
if(cnt1 == GATE_TIME)begin
|
||||
cnt1 <= 28'd0;
|
||||
gate <= ~gate;//产生 1s 的闸门信号
|
||||
end
|
||||
else begin
|
||||
cnt1 <= cnt1 + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @ (posedge clk_in )
|
||||
begin
|
||||
if(square_pose == 1'b1)
|
||||
begin
|
||||
gatebuf <= gate;//使闸门信号与待测方波同步,保证一个闸门包含整数个方波周期
|
||||
end
|
||||
gatebuf1 <= gatebuf;//将同步之后的闸门信号打一拍,用于捕捉闸门信号的边沿
|
||||
end
|
||||
|
||||
assign gate_start = gatebuf & ~gatebuf1;//表示闸门开始时刻
|
||||
assign gate_end = ~gatebuf & gatebuf1;//闸门结束时刻
|
||||
|
||||
//计数系统时钟周期
|
||||
always @ (posedge clk_in)
|
||||
begin
|
||||
if(gate_start == 1'b1) begin
|
||||
cnt2 <= 28'd1;
|
||||
end
|
||||
else if(gate_end == 1'b1) begin
|
||||
cnt2_r <= cnt2;//将所得结果保存在cnt2_r中,并将计数器清零
|
||||
cnt2 <= 28'd0;
|
||||
end
|
||||
else if(gatebuf1 == 1'b1) begin//在闸门内计数系统时钟周期
|
||||
cnt2 <= cnt2 + 1'b1;end
|
||||
end
|
||||
|
||||
//计数待测方波周期数
|
||||
always @ (posedge clk_in )
|
||||
begin
|
||||
if(gate_start == 1'b1) begin
|
||||
cnt3 <= 28'd0;
|
||||
end
|
||||
else if(gate_end == 1'b1) begin
|
||||
cnt3_r <= cnt3;//将所得结果保存在cnt3_r中,并将计数器清零
|
||||
cnt3 <= 28'd0;
|
||||
end
|
||||
else if(gatebuf1 == 1'b1 && square_nege == 1'b1) begin//在闸门内计数待测方波周期数(数闸门内方波的下降沿)
|
||||
cnt3 <= cnt3 + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
assign CNTCLK = cnt2_r;
|
||||
assign CNTSQU = cnt3_r;
|
||||
|
||||
endmodule
|
101
lib/common/Apply/DSP/Base/Measure/Max_meas.v
Normal file
101
lib/common/Apply/DSP/Base/Measure/Max_meas.v
Normal file
@ -0,0 +1,101 @@
|
||||
module Max_meas #
|
||||
(
|
||||
parameter data_width = 4'd12,
|
||||
parameter range_width = 4'd10
|
||||
)
|
||||
(
|
||||
input clk_in,
|
||||
input rst_n,
|
||||
input [range_width-1:0] range,
|
||||
input signed [data_width - 1:0] data_in,
|
||||
output signed [data_width - 1:0] data_out
|
||||
);
|
||||
|
||||
localparam state_output = 3'b010;
|
||||
localparam state_initial = 3'b000;
|
||||
localparam state_detection = 3'b001;
|
||||
|
||||
reg signed [data_width - 1:0] data_out_buf = 0;
|
||||
reg signed [data_width - 1:0] data_out_buf1 = 0;
|
||||
reg [2:0] state = 3'b000;
|
||||
reg test_sig = 1'b0;
|
||||
reg test_sig_buf = 1'b0;
|
||||
wire test_done_sig = ~test_sig & test_sig_buf;
|
||||
wire test_start_sig = test_sig & ~test_sig_buf;
|
||||
|
||||
/***************************************************/
|
||||
//define the time counter
|
||||
reg [range_width-1:0] cnt0 = 1;
|
||||
|
||||
always@(posedge clk_in)
|
||||
begin
|
||||
if (range == 0)
|
||||
begin
|
||||
test_sig <= 1'b1;
|
||||
end
|
||||
else if (cnt0 == range)
|
||||
begin
|
||||
cnt0 <= 10'd0; //count done,clearing the time counter
|
||||
test_sig <= 1'd0;
|
||||
end
|
||||
else
|
||||
test_sig <= 1'd1; //cnt0 counter = cnt0 counter + 1
|
||||
cnt0 <= cnt0 + 1'b1;
|
||||
end
|
||||
/***************************************************/
|
||||
|
||||
|
||||
|
||||
always@(posedge clk_in)
|
||||
begin
|
||||
if (range == 0)
|
||||
begin
|
||||
test_sig_buf <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
test_sig_buf <= test_sig;
|
||||
end
|
||||
end
|
||||
|
||||
always@(posedge clk_in or negedge rst_n)
|
||||
begin
|
||||
if(!rst_n)
|
||||
begin
|
||||
data_out_buf <= 0;
|
||||
data_out_buf1 <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
case(state)
|
||||
state_initial:begin
|
||||
if(test_start_sig)
|
||||
begin
|
||||
state <= state_detection;
|
||||
data_out_buf <= 0;
|
||||
end
|
||||
end
|
||||
state_detection:begin
|
||||
if(test_done_sig)
|
||||
state <= state_output;
|
||||
else
|
||||
if(data_in > data_out_buf)
|
||||
begin
|
||||
data_out_buf <= data_in;
|
||||
if (range == 0)
|
||||
begin
|
||||
data_out_buf1 <= data_out_buf;
|
||||
end
|
||||
end
|
||||
end
|
||||
state_output:begin
|
||||
data_out_buf1 <= data_out_buf;
|
||||
state <= state_initial;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
assign data_out=data_out_buf1;
|
||||
|
||||
endmodule
|
101
lib/common/Apply/DSP/Base/Measure/Min_meas.v
Normal file
101
lib/common/Apply/DSP/Base/Measure/Min_meas.v
Normal file
@ -0,0 +1,101 @@
|
||||
module Min_meas #
|
||||
(
|
||||
parameter data_width = 4'd12,
|
||||
parameter range_width = 4'd10
|
||||
)
|
||||
(
|
||||
input clk_in,
|
||||
input rst_n,
|
||||
input [range_width-1:0] range,
|
||||
input signed [data_width - 1:0] data_in,
|
||||
output signed [data_width - 1:0] data_out
|
||||
);
|
||||
|
||||
localparam state_output = 3'b010;
|
||||
localparam state_initial = 3'b000;
|
||||
localparam state_detection = 3'b001;
|
||||
|
||||
reg signed [data_width - 1:0] data_out_buf = 0;
|
||||
reg signed [data_width - 1:0] data_out_buf1 = 0;
|
||||
reg [2:0] state = 3'b000;
|
||||
reg test_sig = 1'b0;
|
||||
reg test_sig_buf = 1'b0;
|
||||
wire test_done_sig = ~test_sig & test_sig_buf;
|
||||
wire test_start_sig = test_sig & ~test_sig_buf;
|
||||
|
||||
/***************************************************/
|
||||
//define the time counter
|
||||
reg [range_width-1:0] cnt0 = 1;
|
||||
|
||||
always@(posedge clk_in)
|
||||
begin
|
||||
if (range == 0)
|
||||
begin
|
||||
test_sig <= 1'b1;
|
||||
end
|
||||
else if (cnt0 == range)
|
||||
begin
|
||||
cnt0 <= 10'd0; //count done,clearing the time counter
|
||||
test_sig <= 1'd0;
|
||||
end
|
||||
else
|
||||
test_sig <= 1'd1; //cnt0 counter = cnt0 counter + 1
|
||||
cnt0 <= cnt0 + 1'b1;
|
||||
end
|
||||
/***************************************************/
|
||||
|
||||
|
||||
|
||||
always@(posedge clk_in)
|
||||
begin
|
||||
if (range == 0)
|
||||
begin
|
||||
test_sig_buf <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
test_sig_buf <= test_sig;
|
||||
end
|
||||
end
|
||||
|
||||
always@(posedge clk_in or negedge rst_n)
|
||||
begin
|
||||
if(!rst_n)
|
||||
begin
|
||||
data_out_buf <= 0;
|
||||
data_out_buf1 <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
case(state)
|
||||
state_initial:begin
|
||||
if(test_start_sig)
|
||||
begin
|
||||
state <= state_detection;
|
||||
data_out_buf <= 0;
|
||||
end
|
||||
end
|
||||
state_detection:begin
|
||||
if(test_done_sig)
|
||||
state <= state_output;
|
||||
else
|
||||
if(data_in > data_out_buf)
|
||||
begin
|
||||
data_out_buf <= data_in;
|
||||
if (range == 0)
|
||||
begin
|
||||
data_out_buf1 <= data_out_buf;
|
||||
end
|
||||
end
|
||||
end
|
||||
state_output:begin
|
||||
data_out_buf1 <= data_out_buf;
|
||||
state <= state_initial;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
assign data_out=data_out_buf1;
|
||||
|
||||
endmodule
|
76
lib/common/Apply/DSP/Base/Measure/Valid_Meas.v
Normal file
76
lib/common/Apply/DSP/Base/Measure/Valid_Meas.v
Normal file
@ -0,0 +1,76 @@
|
||||
`timescale 1ns / 1ps
|
||||
module measure
|
||||
(
|
||||
input clk_sys,
|
||||
input clk_samp,
|
||||
input rst_n,
|
||||
input mearsure_start,
|
||||
input [11:0] AD_data,
|
||||
output measure_done_q,
|
||||
output [21:0] data_out
|
||||
);
|
||||
parameter cnt_clear = 22'd255;
|
||||
reg clk_samp_buf0;
|
||||
reg clk_samp_buf1;
|
||||
wire clk_samp_impluse = clk_samp_buf0 & ~clk_samp_buf1;//采样脉冲信号
|
||||
wire [21:0] mult_data;
|
||||
reg [16:0] cnt;
|
||||
reg [39:0] sig_energy;
|
||||
reg [21:0] data_out_buf;
|
||||
reg measure_en;
|
||||
wire measure_done = (cnt == cnt_clear) ? 1'b1:1'b0;
|
||||
assign measure_done_q = measure_done;
|
||||
always@(posedge clk_sys)
|
||||
begin
|
||||
clk_samp_buf0 <= clk_samp;
|
||||
clk_samp_buf1 <= clk_samp_buf0;
|
||||
end
|
||||
always@(posedge clk_sys)
|
||||
begin
|
||||
if(!rst_n)
|
||||
begin
|
||||
measure_en <= 1'b0;
|
||||
end
|
||||
else if(mearsure_start)
|
||||
measure_en <= 1'b1;
|
||||
else if(measure_done)
|
||||
measure_en <= 1'b0;
|
||||
else
|
||||
measure_en <= measure_en;
|
||||
end
|
||||
always@(posedge clk_sys)
|
||||
begin
|
||||
if(!rst_n)
|
||||
begin
|
||||
sig_energy <= 40'd0;
|
||||
cnt <= 17'd0;
|
||||
data_out_buf <= 22'd0;
|
||||
end
|
||||
else if(cnt == cnt_clear)
|
||||
begin
|
||||
sig_energy <= 40'd0;
|
||||
data_out_buf <= sig_energy[39:8];
|
||||
cnt <= 17'd0;
|
||||
end
|
||||
else if(clk_samp_impluse && measure_en)
|
||||
begin
|
||||
cnt <= cnt + 17'd1;
|
||||
sig_energy <= sig_energy + mult_data;
|
||||
end
|
||||
else
|
||||
begin
|
||||
sig_energy <= sig_energy;
|
||||
data_out_buf <= data_out_buf;
|
||||
cnt <= cnt;
|
||||
end
|
||||
end
|
||||
mult1 mult1_inst
|
||||
(
|
||||
.A(AD_data),
|
||||
.B(AD_data),
|
||||
.P(mult_data),
|
||||
.CLK(clk_sys),
|
||||
.CE(clk_samp_impluse)
|
||||
);
|
||||
assign data_out = data_out_buf;
|
||||
endmodule
|
69
lib/common/Apply/Image/Advance_Apply/Image_XYCrop.v
Normal file
69
lib/common/Apply/Image/Advance_Apply/Image_XYCrop.v
Normal file
@ -0,0 +1,69 @@
|
||||
`timescale 1ns / 1ps
|
||||
module Image_XYCrop(
|
||||
input clk,
|
||||
input rst_n,
|
||||
|
||||
//CMOS
|
||||
input image_in_vsync,
|
||||
input image_in_href,
|
||||
input image_in_data,
|
||||
|
||||
output image_out_vsync,
|
||||
output image_out_href_left,
|
||||
output image_out_data_left,
|
||||
output image_out_href_right,
|
||||
output image_out_data_right
|
||||
);
|
||||
|
||||
//-----------------------------------
|
||||
reg image_in_href_r = 0;
|
||||
reg image_in_vsync_r = 0;
|
||||
reg image_in_data_r = 0;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
image_in_vsync_r <= 0;
|
||||
image_in_href_r <= 0;
|
||||
image_in_data_r <= 0;
|
||||
end
|
||||
else begin
|
||||
image_in_vsync_r <= image_in_vsync;
|
||||
image_in_href_r <= image_in_href;
|
||||
image_in_data_r <= image_in_data;
|
||||
end
|
||||
end
|
||||
//-----------------------------------
|
||||
//Image Ysize Crop
|
||||
reg [11:0] image_ypos = 0;
|
||||
wire image_in_href_negedge = (image_in_href_r & ~image_in_href) ? 1'b1 : 1'b0;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n)
|
||||
image_ypos <= 0;
|
||||
else if(image_in_vsync == 1'b1) begin
|
||||
if(image_in_href_negedge == 1'b1) //行同步信号的下降沿,一行信号赋值完成后,image_ypos累加1
|
||||
image_ypos <= image_ypos + 1'b1;
|
||||
else
|
||||
image_ypos <= image_ypos;
|
||||
end
|
||||
else
|
||||
image_ypos <= 0;
|
||||
end
|
||||
assign image_out_vsync = image_in_vsync_r; // image_out_vsync是打一拍后的 image_in_vsync的信号,延时了一个时钟周期
|
||||
|
||||
//-----------------------------------
|
||||
//Image Hsize Crop
|
||||
reg [11:0] image_xpos = 0;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n)
|
||||
image_xpos <= 0;
|
||||
else if(image_in_href == 1'b1)
|
||||
image_xpos <= image_xpos + 1'b1;
|
||||
else
|
||||
image_xpos <= 0;
|
||||
end
|
||||
|
||||
assign image_out_href_right = ((image_in_href_r == 1'b1) && (image_xpos > 10'd640) && (image_xpos < 12'd1280)) ? 1'b1 : 1'b0;
|
||||
assign image_out_data_right = (image_out_vsync & image_out_href_right) ? image_in_data_r : 1'd0;
|
||||
assign image_out_href_left = ((image_in_href_r == 1'b1) && (image_xpos <= 10'd640)) ? 1'b1 : 1'b0;
|
||||
assign image_out_data_left = (image_out_vsync & image_out_href_left) ? image_in_data_r : 1'd0;
|
||||
|
||||
endmodule
|
113
lib/common/Apply/Image/Advance_Apply/Parallel_Line_Detector.v
Normal file
113
lib/common/Apply/Image/Advance_Apply/Parallel_Line_Detector.v
Normal file
@ -0,0 +1,113 @@
|
||||
module Parallel_Line_Detector #(
|
||||
parameter IMG_VDISP = 1240,
|
||||
parameter X_THRESHOLD = 100,
|
||||
parameter Y_THRESHOLD = 100,
|
||||
parameter X_Center_Value = 540,
|
||||
parameter Y_Center_Value = 540
|
||||
) (
|
||||
input clk,
|
||||
input rst_n,
|
||||
//
|
||||
input per_img_Bit,
|
||||
input per_frame_href,
|
||||
input per_frame_vsync,
|
||||
//
|
||||
output X_up_down,
|
||||
output Y_up_down,
|
||||
output [15:0] X_distance,
|
||||
output [15:0] Y_distance
|
||||
);
|
||||
|
||||
|
||||
//检测行同步信号边沿,一行数据的开始和结束
|
||||
wire href_pos,href_neg,vsync_neg;
|
||||
reg [1:0] per_frame_href_r,per_frame_vsync_r;
|
||||
always @ (posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
per_frame_href_r <= 2'b0;
|
||||
per_frame_vsync_r <= 2'b0;
|
||||
end
|
||||
else begin
|
||||
per_frame_href_r <= {per_frame_href_r[0],per_frame_href};
|
||||
per_frame_vsync_r <= {per_frame_vsync_r[0],per_frame_vsync};
|
||||
end
|
||||
end
|
||||
assign href_pos =(~per_frame_href_r[1] & per_frame_href_r[0]) ? 1'b1 : 1'b0; //一行信号的开始
|
||||
assign href_neg =(~per_frame_href_r[0] & per_frame_href_r[1]) ? 1'b1 : 1'b0; //一行信号的结束
|
||||
assign vsync_neg =(~per_frame_vsync_r[0] & per_frame_vsync_r[1]) ? 1'b1 : 1'b0; //一帧信号的结束
|
||||
|
||||
/**************************************直线检测部分**************************************/
|
||||
wire IMG_BIT_INPUT = ~per_img_Bit; //输入的边缘数据
|
||||
|
||||
reg [15:0] x_coordinate_cnt; //列计数器,横坐标 X
|
||||
reg [15:0] y_coordinate_cnt; //行计数器,纵坐标 Y
|
||||
|
||||
reg [15:0] X_edge_center; //纵向纤芯坐标
|
||||
reg [15:0] Y_edge_center; //横向纤芯坐标
|
||||
|
||||
//竖线线检测的相关变量
|
||||
reg [15:0] X_edge_acc = 0; //列边沿坐标的累加
|
||||
reg [15:0] X_edge_cnt = 0; //列边沿的计数器
|
||||
reg [15:0] per_row_acc [IMG_VDISP:1]; //每列的累加值
|
||||
reg [IMG_VDISP:1] per_row_flag; //每列的累加值
|
||||
|
||||
//横线检测的相关变量
|
||||
reg [15:0] Y_edge_acc = 0; //行边沿坐标的累加
|
||||
reg [15:0] Y_edge_cnt = 0; //行边沿的计数器
|
||||
reg [15:0] per_href_acc = 0; //每行的累加值
|
||||
|
||||
//直线检测处理语句块
|
||||
integer i;
|
||||
always @ (posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
Y_edge_acc <= 16'd0;
|
||||
Y_edge_cnt <= 16'd0;
|
||||
X_edge_acc <= 16'd0;
|
||||
X_edge_cnt <= 16'd0;
|
||||
per_href_acc <= 16'd0;
|
||||
x_coordinate_cnt <= 16'd0;
|
||||
y_coordinate_cnt <= 16'd0;
|
||||
for (i = 1; i<=IMG_VDISP; i=i+1) begin
|
||||
per_row_acc[i] <= 16'd0;
|
||||
per_row_flag[i] <= 1'd0;
|
||||
end
|
||||
end
|
||||
else if (per_frame_href) begin
|
||||
if (href_pos) y_coordinate_cnt <= y_coordinate_cnt + 1'd1;
|
||||
else y_coordinate_cnt <= y_coordinate_cnt;
|
||||
if ((per_row_acc[x_coordinate_cnt] >= X_THRESHOLD) && (~per_row_flag[x_coordinate_cnt])) begin
|
||||
X_edge_cnt <= X_edge_cnt + 1'd1;
|
||||
per_row_flag[x_coordinate_cnt] <= 1'b1;
|
||||
X_edge_acc <= X_edge_acc + x_coordinate_cnt;
|
||||
end
|
||||
per_href_acc <= per_href_acc + IMG_BIT_INPUT;
|
||||
x_coordinate_cnt <= x_coordinate_cnt + 1'd1;
|
||||
per_row_acc[x_coordinate_cnt] <= per_row_acc[x_coordinate_cnt] + IMG_BIT_INPUT;
|
||||
end
|
||||
else if(href_neg) begin //一行数据结束
|
||||
if(per_href_acc >= Y_THRESHOLD) begin
|
||||
Y_edge_cnt <= Y_edge_cnt + 1'd1;
|
||||
Y_edge_acc <= Y_edge_acc + y_coordinate_cnt;
|
||||
end
|
||||
per_href_acc <= 16'd0;
|
||||
x_coordinate_cnt <= 16'd0;
|
||||
end
|
||||
else if (vsync_neg) begin
|
||||
X_edge_center = X_edge_acc / X_edge_cnt;
|
||||
Y_edge_center = Y_edge_acc / Y_edge_cnt;
|
||||
X_edge_acc <= 16'd0; X_edge_cnt <= 16'd0;
|
||||
Y_edge_acc <= 16'd0; Y_edge_cnt <= 16'd0;
|
||||
for (i = 1; i<=IMG_VDISP; i=i+1) begin
|
||||
per_row_acc[i] <= 16'd0;
|
||||
per_row_flag[i] <= 1'd0;
|
||||
end
|
||||
y_coordinate_cnt <= 16'd0;
|
||||
end
|
||||
end
|
||||
|
||||
assign X_distance = $signed(X_edge_center) - $signed(X_Center_Value);
|
||||
assign Y_distance = $signed(Y_edge_center) - $signed(Y_Center_Value);
|
||||
assign X_up_down = X_distance[16];
|
||||
assign Y_up_down = Y_distance[16];
|
||||
|
||||
endmodule
|
162
lib/common/Apply/Image/Basic_Apply/Dat/RAW8_RGB888.v
Normal file
162
lib/common/Apply/Image/Basic_Apply/Dat/RAW8_RGB888.v
Normal file
@ -0,0 +1,162 @@
|
||||
`timescale 1ns/1ns
|
||||
module RAW8_RGB888 #(
|
||||
parameter [10:0] IMG_HDISP = 11'd640, //640*480
|
||||
parameter [10:0] IMG_VDISP = 11'd480
|
||||
) (
|
||||
//global clock
|
||||
input clk, //cmos video pixel clock
|
||||
input rst_n, //global reset
|
||||
|
||||
//CMOS YCbCr444 data output
|
||||
input per_frame_vsync, //Prepared Image data vsync valid signal
|
||||
input per_frame_href, //Prepared Image data href vaild signal
|
||||
|
||||
input [7:0] per_img_RAW, //Prepared Image data 8 Bit RAW Data
|
||||
|
||||
|
||||
//CMOS RGB888 data output
|
||||
output post_frame_vsync, //Processed Image data vsync valid signal
|
||||
output post_frame_href, //Processed Image data href vaild signal
|
||||
output [7:0] post_img_red, //Prepared Image green data to be processed
|
||||
output [7:0] post_img_green, //Prepared Image green data to be processed
|
||||
output [7:0] post_img_blue //Prepared Image blue data to be processed
|
||||
);
|
||||
|
||||
//----------------------------------------------------
|
||||
//Generate 8Bit 3X3 Matrix for Video Image Processor.
|
||||
//Image data has been processd
|
||||
wire matrix_frame_vsync; //Prepared Image data vsync valid signal
|
||||
wire matrix_frame_href; //Prepared Image data href vaild signal
|
||||
wire [7:0] matrix_p11, matrix_p12, matrix_p13; //3X3 Matrix output
|
||||
wire [7:0] matrix_p21, matrix_p22, matrix_p23;
|
||||
wire [7:0] matrix_p31, matrix_p32, matrix_p33;
|
||||
Matrix_Generate_3X3_Buf # (
|
||||
.DATA_WIDTH ( 8 ),
|
||||
.IMG_HDISP (IMG_HDISP), //640*480
|
||||
.IMG_VDISP (IMG_VDISP)
|
||||
) Matrix_Generate_3X3_Buf_u (
|
||||
//global clock
|
||||
.clk (clk), //cmos video pixel clock
|
||||
.rst_n (rst_n), //global reset
|
||||
|
||||
//Image data prepred to be processd
|
||||
.per_frame_vsync (per_frame_vsync), //Prepared Image data vsync valid signal
|
||||
.per_frame_href (per_frame_href), //Prepared Image data href vaild signal
|
||||
.per_img_Data (per_img_RAW), //Prepared Image brightness input
|
||||
|
||||
//Image data has been processd
|
||||
.matrix_frame_vsync (matrix_frame_vsync), //Processed Image data vsync valid signal
|
||||
.matrix_frame_href (matrix_frame_href), //Processed Image data href vaild signal
|
||||
.matrix_p11(matrix_p11), .matrix_p12(matrix_p12), .matrix_p13(matrix_p13), //3X3 Matrix output
|
||||
.matrix_p21(matrix_p21), .matrix_p22(matrix_p22), .matrix_p23(matrix_p23),
|
||||
.matrix_p31(matrix_p31), .matrix_p32(matrix_p32), .matrix_p33(matrix_p33)
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------
|
||||
//sync the frame vsync and href signal and generate frame begin & end signal
|
||||
reg matrix_frame_href_r;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n)
|
||||
matrix_frame_href_r <= 0;
|
||||
else
|
||||
matrix_frame_href_r <= matrix_frame_href;
|
||||
end
|
||||
wire matrix_frame_href_end = (matrix_frame_href_r & ~matrix_frame_href) ? 1'b1 : 1'b0; //Line over signal
|
||||
|
||||
//----------------------------------------
|
||||
//Count the frame lines
|
||||
reg [10:0] line_cnt;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n)
|
||||
line_cnt <= 0;
|
||||
else if(matrix_frame_vsync == 1'b1) begin
|
||||
if(matrix_frame_href_end)
|
||||
line_cnt <= (line_cnt < IMG_VDISP - 1'b1) ? line_cnt + 1'b1 : 10'd0;
|
||||
else
|
||||
line_cnt <= line_cnt;
|
||||
end
|
||||
else
|
||||
line_cnt <= 0;
|
||||
end
|
||||
|
||||
//----------------------------------------
|
||||
//Count the pixels
|
||||
reg [10:0] point_cnt;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n)
|
||||
point_cnt <= 0;
|
||||
else if(matrix_frame_href == 1'b1) //Line valid
|
||||
point_cnt <= (line_cnt < IMG_HDISP - 1'b1) ? point_cnt + 1'b1 : 10'd0;
|
||||
else
|
||||
point_cnt <= 0;
|
||||
end
|
||||
|
||||
//--------------------------------------
|
||||
//Convet RAW 2 RGB888 Format
|
||||
//
|
||||
localparam OddLINE_OddPOINT = 2'b10; //odd lines + odd point
|
||||
localparam OddLINE_Even_POINT = 2'b11; //odd lines + even point
|
||||
localparam EvenLINE_OddPOINT = 2'b00; //even lines + odd point
|
||||
localparam EvenLINE_EvenPOINT = 2'b01; //even lines + even point
|
||||
reg [9:0] post_img_red_r;
|
||||
reg [9:0] post_img_green_r;
|
||||
reg [9:0] post_img_blue_r;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
post_img_red_r <= 0;
|
||||
post_img_green_r<= 0;
|
||||
post_img_blue_r <= 0;
|
||||
end
|
||||
else begin
|
||||
case({line_cnt[0], point_cnt[0]})
|
||||
//-------------------------BGBG...BGBG--------------------//
|
||||
OddLINE_OddPOINT:begin //odd lines + odd point
|
||||
//Center Blue
|
||||
post_img_red_r <= (matrix_p11 + matrix_p13 + matrix_p31 + matrix_p33)>>2;
|
||||
post_img_green_r<= (matrix_p12 + matrix_p21 + matrix_p23 + matrix_p32)>>2;
|
||||
post_img_blue_r <= matrix_p22;
|
||||
end
|
||||
OddLINE_Even_POINT:begin //odd lines + even point
|
||||
//Center Green
|
||||
post_img_red_r <= (matrix_p12 + matrix_p32)>>1;
|
||||
post_img_green_r<= matrix_p22;
|
||||
post_img_blue_r <= (matrix_p21 + matrix_p23)>>1;
|
||||
end
|
||||
//-------------------------GRGR...GRGR--------------------//
|
||||
EvenLINE_OddPOINT:begin //even lines + odd point
|
||||
//Center Green
|
||||
post_img_red_r <= (matrix_p21 + matrix_p23)>>1;
|
||||
post_img_green_r<= matrix_p22;
|
||||
post_img_blue_r <= (matrix_p12 + matrix_p32)>>1;
|
||||
end
|
||||
EvenLINE_EvenPOINT:begin //even lines + even point
|
||||
//Center Red
|
||||
post_img_red_r <= matrix_p22;
|
||||
post_img_green_r<= (matrix_p12 + matrix_p21 + matrix_p23 + matrix_p32)>>2;
|
||||
post_img_blue_r <= (matrix_p11 + matrix_p13 + matrix_p31 + matrix_p33)>>2;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
assign post_img_red = post_img_red_r[7:0];
|
||||
assign post_img_green = post_img_green_r[7:0];
|
||||
assign post_img_blue = post_img_blue_r[7:0];
|
||||
|
||||
//------------------------------------------
|
||||
//lag n clocks signal sync
|
||||
reg [1:0] post_frame_vsync_r;
|
||||
reg [1:0] post_frame_href_r;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
post_frame_vsync_r <= 0;
|
||||
post_frame_href_r <= 0;
|
||||
end
|
||||
else begin
|
||||
post_frame_vsync_r <= {post_frame_vsync_r[0], matrix_frame_vsync};
|
||||
post_frame_href_r <= {post_frame_href_r[0], matrix_frame_href};
|
||||
end
|
||||
end
|
||||
assign post_frame_vsync = post_frame_vsync_r[0];
|
||||
assign post_frame_href = post_frame_href_r[0];
|
||||
|
||||
endmodule
|
118
lib/common/Apply/Image/Basic_Apply/Dat/RGB888_YCbCr444.v
Normal file
118
lib/common/Apply/Image/Basic_Apply/Dat/RGB888_YCbCr444.v
Normal file
@ -0,0 +1,118 @@
|
||||
`timescale 1ns/1ns
|
||||
module RGB888_YCbCr444 (
|
||||
//global clock
|
||||
input clk, //cmos video pixel clock
|
||||
input rst_n, //global reset
|
||||
|
||||
//Image data prepred to be processd
|
||||
input per_frame_vsync, //Prepared Image data vsync valid signal
|
||||
input per_frame_href, //Prepared Image data href vaild signal
|
||||
input [7:0] per_img_red, //Prepared Image red data to be processed
|
||||
input [7:0] per_img_green, //Prepared Image green data to be processed
|
||||
input [7:0] per_img_blue, //Prepared Image blue data to be processed
|
||||
|
||||
//Image data has been processd
|
||||
output post_frame_vsync, //Processed Image data vsync valid signal
|
||||
output post_frame_href, //Processed Image data href vaild signal
|
||||
output [7:0] post_img_Y, //Processed Image brightness output
|
||||
output [7:0] post_img_Cb, //Processed Image blue shading output
|
||||
output [7:0] post_img_Cr //Processed Image red shading output
|
||||
);
|
||||
|
||||
//--------------------------------------------
|
||||
/*********************************************
|
||||
//Refer to <OV7725 Camera Module Software Applicaton Note> page 5
|
||||
Y = (77 *R + 150*G + 29 *B)>>8
|
||||
Cb = (-43*R - 85 *G + 128*B)>>8 + 128
|
||||
Cr = (128*R - 107*G - 21 *B)>>8 + 128
|
||||
--->
|
||||
Y = (77 *R + 150*G + 29 *B)>>8
|
||||
Cb = (-43*R - 85 *G + 128*B + 32768)>>8
|
||||
Cr = (128*R - 107*G - 21 *B + 32768)>>8
|
||||
**********************************************/
|
||||
//Step 1
|
||||
reg [15:0] img_red_r0, img_red_r1, img_red_r2;
|
||||
reg [15:0] img_green_r0, img_green_r1, img_green_r2;
|
||||
reg [15:0] img_blue_r0, img_blue_r1, img_blue_r2;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
img_red_r0 <= 0;
|
||||
img_red_r1 <= 0;
|
||||
img_red_r2 <= 0;
|
||||
img_green_r0 <= 0;
|
||||
img_green_r1 <= 0;
|
||||
img_green_r2 <= 0;
|
||||
img_blue_r0 <= 0;
|
||||
img_blue_r1 <= 0;
|
||||
img_blue_r2 <= 0;
|
||||
end
|
||||
else begin
|
||||
img_red_r0 <= per_img_red * 8'd77;
|
||||
img_red_r1 <= per_img_red * 8'd43;
|
||||
img_red_r2 <= per_img_red * 8'd128;
|
||||
img_green_r0 <= per_img_green * 8'd150;
|
||||
img_green_r1 <= per_img_green * 8'd85;
|
||||
img_green_r2 <= per_img_green * 8'd107;
|
||||
img_blue_r0 <= per_img_blue * 8'd29;
|
||||
img_blue_r1 <= per_img_blue * 8'd128;
|
||||
img_blue_r2 <= per_img_blue * 8'd21;
|
||||
end
|
||||
end
|
||||
|
||||
//--------------------------------------------------
|
||||
//Step 2
|
||||
reg [15:0] img_Y_r0;
|
||||
reg [15:0] img_Cb_r0;
|
||||
reg [15:0] img_Cr_r0;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
img_Y_r0 <= 0;
|
||||
img_Cb_r0 <= 0;
|
||||
img_Cr_r0 <= 0;
|
||||
end
|
||||
else begin
|
||||
img_Y_r0 <= img_red_r0 + img_green_r0 + img_blue_r0;
|
||||
img_Cb_r0 <= img_blue_r1 - img_red_r1 - img_green_r1 + 16'd32768;
|
||||
img_Cr_r0 <= img_red_r2 + img_green_r2 + img_blue_r2 + 16'd32768;
|
||||
end
|
||||
end
|
||||
|
||||
//--------------------------------------------------
|
||||
//Step 3
|
||||
reg [7:0] img_Y_r1;
|
||||
reg [7:0] img_Cb_r1;
|
||||
reg [7:0] img_Cr_r1;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
img_Y_r1 <= 0;
|
||||
img_Cb_r1 <= 0;
|
||||
img_Cr_r1 <= 0;
|
||||
end
|
||||
else begin
|
||||
img_Y_r1 <= img_Y_r0[15:8];
|
||||
img_Cb_r1 <= img_Cb_r0[15:8];
|
||||
img_Cr_r1 <= img_Cr_r0[15:8];
|
||||
end
|
||||
end
|
||||
|
||||
//------------------------------------------
|
||||
//lag 3 clocks signal sync
|
||||
reg [2:0] per_frame_vsync_r;
|
||||
reg [2:0] per_frame_href_r;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
per_frame_vsync_r <= 0;
|
||||
per_frame_href_r <= 0;
|
||||
end
|
||||
else begin
|
||||
per_frame_vsync_r <= {per_frame_vsync_r[1:0], per_frame_vsync};
|
||||
per_frame_href_r <= {per_frame_href_r[1:0], per_frame_href};
|
||||
end
|
||||
end
|
||||
assign post_frame_vsync = per_frame_vsync_r[2];
|
||||
assign post_frame_href = per_frame_href_r[2];
|
||||
assign post_img_Y = post_frame_href ? img_Y_r1 : 8'd0;
|
||||
assign post_img_Cb = post_frame_href ? img_Cb_r1: 8'd0;
|
||||
assign post_img_Cr = post_frame_href ? img_Cr_r1: 8'd0;
|
||||
|
||||
endmodule
|
103
lib/common/Apply/Image/Basic_Apply/Detector/Dilation_Detector.v
Normal file
103
lib/common/Apply/Image/Basic_Apply/Detector/Dilation_Detector.v
Normal file
@ -0,0 +1,103 @@
|
||||
`timescale 1ns/1ns
|
||||
module Bit_Dilation_Detector #(
|
||||
parameter [10:0] IMG_HDISP = 11'd640, //640*480
|
||||
parameter [10:0] IMG_VDISP = 11'd480
|
||||
) (
|
||||
//global clock
|
||||
input clk, //cmos video pixel clock
|
||||
input rst_n, //global reset
|
||||
//Image data prepred to be processd
|
||||
input per_frame_vsync, //Prepared Image data vsync valid signal
|
||||
input per_frame_href, //Prepared Image data href vaild signal
|
||||
input per_img_Bit, //Prepared Image Bit flag outout(1: Value, 0:inValid)
|
||||
//Image data has been processd
|
||||
output post_frame_vsync, //Processed Image data vsync valid signal
|
||||
output post_frame_href, //Processed Image data href vaild signal
|
||||
output post_img_Bit //Processed Image Bit flag outout(1: Value, 0:inValid)
|
||||
);
|
||||
|
||||
//----------------------------------------------------
|
||||
//Generate 1Bit 3X3 Matrix for Video Image Processor.
|
||||
//Image data has been processd
|
||||
wire matrix_frame_vsync; //Prepared Image data vsync valid signal
|
||||
wire matrix_frame_href; //Prepared Image data href vaild signal
|
||||
wire matrix_p11, matrix_p12, matrix_p13; //3X3 Matrix output
|
||||
wire matrix_p21, matrix_p22, matrix_p23;
|
||||
wire matrix_p31, matrix_p32, matrix_p33;
|
||||
Matrix_Generate_3X3 #(
|
||||
.DATA_WIDTH ( 1 ),
|
||||
.IMG_HDISP (IMG_HDISP), //640*480
|
||||
.IMG_VDISP (IMG_VDISP)
|
||||
) Matrix_Generate_3X3_u (
|
||||
//global clock
|
||||
.clk (clk), //cmos video pixel clock
|
||||
.rst_n (rst_n), //global reset
|
||||
//Image data prepred to be processd
|
||||
.per_frame_vsync (per_frame_vsync), //Prepared Image data vsync valid signal
|
||||
.per_frame_href (per_frame_href), //Prepared Image data href vaild signal
|
||||
.per_img_Data (per_img_Bit), //Prepared Image brightness input
|
||||
//Image data has been processd
|
||||
.matrix_frame_vsync (matrix_frame_vsync), //Processed Image data vsync valid signal
|
||||
.matrix_frame_href (matrix_frame_href), //Processed Image data href vaild signal
|
||||
.matrix_p11(matrix_p11), .matrix_p12(matrix_p12), .matrix_p13(matrix_p13), //3X3 Matrix output
|
||||
.matrix_p21(matrix_p21), .matrix_p22(matrix_p22), .matrix_p23(matrix_p23),
|
||||
.matrix_p31(matrix_p31), .matrix_p32(matrix_p32), .matrix_p33(matrix_p33)
|
||||
);
|
||||
|
||||
//Add you arithmetic here
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
//-------------------------------------------
|
||||
//-------------------------------------------
|
||||
//Dilation Parameter
|
||||
// Original Dilation Pixel
|
||||
// [ 0 0 0 ] [ 1 1 1 ] [ P1 P2 P3 ]
|
||||
// [ 0 1 0 ] [ 1 1 1 ] [ P4 P5 P6 ]
|
||||
// [ 0 0 0 ] [ 1 1 1 ] [ P7 P8 P9 ]
|
||||
//P = P1 | P2 | P3 | P4 | P5 | P6 | P7 | 8 | 9;
|
||||
//---------------------------------------
|
||||
//Dilation with or operation,1 : White, 0 : Black
|
||||
//Step1
|
||||
reg post_img_Bit1, post_img_Bit2, post_img_Bit3;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
post_img_Bit1 <= 1'b0;
|
||||
post_img_Bit2 <= 1'b0;
|
||||
post_img_Bit3 <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
post_img_Bit1 <= matrix_p11 | matrix_p12 | matrix_p13;
|
||||
post_img_Bit2 <= matrix_p21 | matrix_p22 | matrix_p23;
|
||||
post_img_Bit3 <= matrix_p21 | matrix_p32 | matrix_p33;
|
||||
end
|
||||
end
|
||||
|
||||
//Step 2
|
||||
reg post_img_Bit4;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n)
|
||||
post_img_Bit4 <= 1'b0;
|
||||
else
|
||||
post_img_Bit4 <= post_img_Bit1 | post_img_Bit2 | post_img_Bit3;
|
||||
end
|
||||
|
||||
//------------------------------------------
|
||||
//lag 2 clocks signal sync
|
||||
reg [1:0] per_frame_vsync_r;
|
||||
reg [1:0] per_frame_href_r;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
per_frame_vsync_r <= 0;
|
||||
per_frame_href_r <= 0;
|
||||
end
|
||||
else begin
|
||||
per_frame_vsync_r <= {per_frame_vsync_r[0], matrix_frame_vsync};
|
||||
per_frame_href_r <= {per_frame_href_r[0], matrix_frame_href};
|
||||
end
|
||||
end
|
||||
assign post_frame_vsync = per_frame_vsync_r[1];
|
||||
assign post_frame_href = per_frame_href_r[1];
|
||||
assign post_img_Bit = post_frame_href ? post_img_Bit4 : 1'b0;
|
||||
|
||||
endmodule
|
105
lib/common/Apply/Image/Basic_Apply/Detector/Erosion_Detector.v
Normal file
105
lib/common/Apply/Image/Basic_Apply/Detector/Erosion_Detector.v
Normal file
@ -0,0 +1,105 @@
|
||||
`timescale 1ns/1ns
|
||||
module Bit_Erosion_Detector #(
|
||||
parameter [10:0] IMG_HDISP = 11'd640, //640*480
|
||||
parameter [10:0] IMG_VDISP = 11'd480
|
||||
) (
|
||||
//global clock
|
||||
input clk, //cmos video pixel clock
|
||||
input rst_n, //global reset
|
||||
|
||||
//Image data prepred to be processd
|
||||
input per_frame_vsync, //Prepared Image data vsync valid signal
|
||||
input per_frame_href, //Prepared Image data href vaild signal
|
||||
input per_img_Bit, //Prepared Image Bit flag outout(1: Value, 0:inValid)
|
||||
|
||||
//Image data has been processd
|
||||
output post_frame_vsync, //Processed Image data vsync valid signal
|
||||
output post_frame_href, //Processed Image data href vaild signal
|
||||
output post_img_Bit //Processed Image Bit flag outout(1: Value, 0:inValid)
|
||||
);
|
||||
|
||||
//----------------------------------------------------
|
||||
//Generate 1Bit 3X3 Matrix for Video Image Processor.
|
||||
//Image data has been processd
|
||||
wire matrix_frame_vsync; //Prepared Image data vsync valid signal
|
||||
wire matrix_frame_href; //Prepared Image data href vaild signal
|
||||
wire matrix_p11, matrix_p12, matrix_p13; //3X3 Matrix output
|
||||
wire matrix_p21, matrix_p22, matrix_p23;
|
||||
wire matrix_p31, matrix_p32, matrix_p33;
|
||||
Matrix_Generate_3X3 #(
|
||||
.DATA_WIDTH ( 1 ),
|
||||
.IMG_HDISP (IMG_HDISP), //640*480
|
||||
.IMG_VDISP (IMG_VDISP)
|
||||
) Matrix_Generate_3X3_u (
|
||||
//global clock
|
||||
.clk (clk), //cmos video pixel clock
|
||||
.rst_n (rst_n), //global reset
|
||||
//Image data prepred to be processd
|
||||
.per_frame_vsync (per_frame_vsync), //Prepared Image data vsync valid signal
|
||||
.per_frame_href (per_frame_href), //Prepared Image data href vaild signal
|
||||
.per_img_Data (per_img_Bit), //Prepared Image brightness input
|
||||
//Image data has been processd
|
||||
.matrix_frame_vsync (matrix_frame_vsync), //Processed Image data vsync valid signal
|
||||
.matrix_frame_href (matrix_frame_href), //Processed Image data href vaild signal
|
||||
.matrix_p11(matrix_p11), .matrix_p12(matrix_p12), .matrix_p13(matrix_p13), //3X3 Matrix output
|
||||
.matrix_p21(matrix_p21), .matrix_p22(matrix_p22), .matrix_p23(matrix_p23),
|
||||
.matrix_p31(matrix_p31), .matrix_p32(matrix_p32), .matrix_p33(matrix_p33)
|
||||
);
|
||||
|
||||
//Add you arithmetic here
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
//-------------------------------------------
|
||||
//-------------------------------------------
|
||||
//Eronsion Parameter
|
||||
// Original Dilation Pixel
|
||||
// [ 0 0 0 ] [ 1 1 1 ] [ P1 P2 P3 ]
|
||||
// [ 0 1 0 ] [ 1 1 1 ] [ P4 P5 P6 ]
|
||||
// [ 0 0 0 ] [ 1 1 1 ] [ P7 P8 P9 ]
|
||||
//P = P1 & P2 & P3 & P4 & P5 & P6 & P7 & 8 & 9;
|
||||
//---------------------------------------
|
||||
//Eonsion with or operation
|
||||
//Step1
|
||||
reg post_img_Bit1, post_img_Bit2, post_img_Bit3;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
post_img_Bit1 <= 1'b0;
|
||||
post_img_Bit2 <= 1'b0;
|
||||
post_img_Bit3 <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
post_img_Bit1 <= matrix_p11 & matrix_p12 & matrix_p13;
|
||||
post_img_Bit2 <= matrix_p21 & matrix_p22 & matrix_p23;
|
||||
post_img_Bit3 <= matrix_p21 & matrix_p32 & matrix_p33;
|
||||
end
|
||||
end
|
||||
|
||||
//Step 2
|
||||
reg post_img_Bit4;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n)
|
||||
post_img_Bit4 <= 1'b0;
|
||||
else
|
||||
post_img_Bit4 <= post_img_Bit1 & post_img_Bit2 & post_img_Bit3;
|
||||
end
|
||||
|
||||
//------------------------------------------
|
||||
//lag 2 clocks signal sync
|
||||
reg [1:0] per_frame_vsync_r;
|
||||
reg [1:0] per_frame_href_r;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
per_frame_vsync_r <= 0;
|
||||
per_frame_href_r <= 0;
|
||||
end
|
||||
else begin
|
||||
per_frame_vsync_r <= {per_frame_vsync_r[0], matrix_frame_vsync};
|
||||
per_frame_href_r <= {per_frame_href_r[0], matrix_frame_href};
|
||||
end
|
||||
end
|
||||
assign post_frame_vsync = per_frame_vsync_r[1];
|
||||
assign post_frame_href = per_frame_href_r[1];
|
||||
assign post_img_Bit = post_frame_href ? post_img_Bit4 : 1'b0;
|
||||
|
||||
endmodule
|
@ -0,0 +1,155 @@
|
||||
`timescale 1ns/1ns
|
||||
module Sobel_Edge_Detector #(
|
||||
parameter [10:0] IMG_HDISP = 11'd640, //640*480
|
||||
parameter [10:0] IMG_VDISP = 11'd480
|
||||
) (
|
||||
//global clock
|
||||
input clk, //cmos video pixel clock
|
||||
input rst_n, //global reset
|
||||
//Image data prepred to be processd
|
||||
input per_frame_vsync, //Prepared Image data vsync valid signal
|
||||
input per_frame_href, //Prepared Image data href vaild signal
|
||||
input [7:0] per_img_Gray, //Prepared Image brightness input
|
||||
//Image data has been processd
|
||||
output post_frame_vsync, //Processed Image data vsync valid signal
|
||||
output post_frame_href, //Processed Image data href vaild signal
|
||||
output post_img_Bit, //Processed Image Bit flag outout(1: Value, 0:inValid)
|
||||
//user interface
|
||||
input [7:0] Sobel_Threshold //Sobel Threshold for image edge detect
|
||||
);
|
||||
|
||||
//----------------------------------------------------
|
||||
//Generate 8Bit 3X3 Matrix for Video Image Processor.
|
||||
//Image data has been processd
|
||||
wire matrix_frame_vsync; //Prepared Image data vsync valid signal
|
||||
wire matrix_frame_href; //Prepared Image data href vaild signal
|
||||
wire [7:0] matrix_p11, matrix_p12, matrix_p13; //3X3 Matrix output
|
||||
wire [7:0] matrix_p21, matrix_p22, matrix_p23;
|
||||
wire [7:0] matrix_p31, matrix_p32, matrix_p33;
|
||||
Matrix_Generate_3X3_Buf # (
|
||||
.DATA_WIDTH ( 8 ),
|
||||
.IMG_HDISP (IMG_HDISP), //640*480
|
||||
.IMG_VDISP (IMG_VDISP)
|
||||
) Matrix_Generate_3X3_Buf_u (
|
||||
//global clock
|
||||
.clk (clk), //cmos video pixel clock
|
||||
.rst_n (rst_n), //global reset
|
||||
//Image data prepred to be processd
|
||||
.per_frame_vsync (per_frame_vsync), //Prepared Image data vsync valid signal
|
||||
.per_frame_href (per_frame_href), //Prepared Image data href vaild signal
|
||||
.per_img_Data (per_img_Gray), //Prepared Image brightness input
|
||||
//Image data has been processd
|
||||
.matrix_frame_vsync (matrix_frame_vsync), //Processed Image data vsync valid signal
|
||||
.matrix_frame_href (matrix_frame_href), //Processed Image data href vaild signal
|
||||
.matrix_p11(matrix_p11), .matrix_p12(matrix_p12), .matrix_p13(matrix_p13), //3X3 Matrix output
|
||||
.matrix_p21(matrix_p21), .matrix_p22(matrix_p22), .matrix_p23(matrix_p23),
|
||||
.matrix_p31(matrix_p31), .matrix_p32(matrix_p32), .matrix_p33(matrix_p33)
|
||||
);
|
||||
|
||||
//Add you arithmetic here
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
//-------------------------------------------
|
||||
//Sobel Parameter
|
||||
// Gx Gy Pixel
|
||||
// [ -1 0 +1 ] [ +1 +2 +1 ] [ P11 P12 P13 ]
|
||||
// [ -2 0 +2 ] [ 0 0 0 ] [ P21 P22 P23 ]
|
||||
// [ -1 0 +1 ] [ -1 -2 -1 ] [ P31 P32 P33 ]
|
||||
|
||||
// localparam P11 = 8'd15, P12 = 8'd94, P13 = 8'd136;
|
||||
// localparam P21 = 8'd31, P22 = 8'd127, P23 = 8'd231;
|
||||
// localparam P31 = 8'd44, P32 = 8'd181, P33 = 8'd249;
|
||||
//Caculate horizontal Grade with |abs|
|
||||
//Step 1-2
|
||||
reg [9:0] Gx_temp1; //postive result
|
||||
reg [9:0] Gx_temp2; //negetive result
|
||||
reg [9:0] Gx_data; //Horizontal grade data
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
Gx_temp1 <= 0;
|
||||
Gx_temp2 <= 0;
|
||||
Gx_data <= 0;
|
||||
end
|
||||
else begin
|
||||
Gx_temp1 <= matrix_p13 + (matrix_p23 << 1) + matrix_p33; //postive result
|
||||
Gx_temp2 <= matrix_p11 + (matrix_p21 << 1) + matrix_p31; //negetive result
|
||||
Gx_data <= (Gx_temp1 >= Gx_temp2) ? Gx_temp1 - Gx_temp2 : Gx_temp2 - Gx_temp1;
|
||||
end
|
||||
end
|
||||
|
||||
//---------------------------------------
|
||||
//Caculate vertical Grade with |abs|
|
||||
//Step 1-2
|
||||
reg [9:0] Gy_temp1; //postive result
|
||||
reg [9:0] Gy_temp2; //negetive result
|
||||
reg [9:0] Gy_data; //Vertical grade data
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
Gy_temp1 <= 0;
|
||||
Gy_temp2 <= 0;
|
||||
Gy_data <= 0;
|
||||
end
|
||||
else begin
|
||||
Gy_temp1 <= matrix_p11 + (matrix_p12 << 1) + matrix_p13; //postive result
|
||||
Gy_temp2 <= matrix_p31 + (matrix_p32 << 1) + matrix_p33; //negetive result
|
||||
Gy_data <= (Gy_temp1 >= Gy_temp2) ? Gy_temp1 - Gy_temp2 : Gy_temp2 - Gy_temp1;
|
||||
end
|
||||
end
|
||||
|
||||
//---------------------------------------
|
||||
//Caculate the square of distance = (Gx^2 + Gy^2)
|
||||
//Step 3
|
||||
reg [20:0] Gxy_square;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n)
|
||||
Gxy_square <= 0;
|
||||
else
|
||||
Gxy_square <= Gx_data * Gx_data + Gy_data * Gy_data;
|
||||
end
|
||||
|
||||
//---------------------------------------
|
||||
//Caculate the distance of P5 = (Gx^2 + Gy^2)^0.5
|
||||
//Step 4
|
||||
Sqrt #(
|
||||
.q_port_width (11),
|
||||
.r_port_width (12),
|
||||
.width (21)
|
||||
) SQRT_u (
|
||||
.radical (Gxy_square),
|
||||
.q (Dim),
|
||||
.remainder ()
|
||||
);
|
||||
|
||||
//---------------------------------------
|
||||
//Compare and get the Sobel_data
|
||||
//Step 5
|
||||
reg post_img_Bit_r;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n)
|
||||
post_img_Bit_r <= 1'b0; //Default None
|
||||
else if(Dim >= Sobel_Threshold)
|
||||
post_img_Bit_r <= 1'b1; //Edge Flag
|
||||
else
|
||||
post_img_Bit_r <= 1'b0; //Not Edge
|
||||
end
|
||||
|
||||
//------------------------------------------
|
||||
//lag 5 clocks signal sync
|
||||
reg [4:0] per_frame_vsync_r;
|
||||
reg [4:0] per_frame_href_r;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
per_frame_vsync_r <= 0;
|
||||
per_frame_href_r <= 0;
|
||||
end
|
||||
else begin
|
||||
per_frame_vsync_r <= {per_frame_vsync_r[3:0], matrix_frame_vsync};
|
||||
per_frame_href_r <= {per_frame_href_r[3:0], matrix_frame_href};
|
||||
end
|
||||
end
|
||||
assign post_frame_vsync = per_frame_vsync_r[4];
|
||||
assign post_frame_href = per_frame_href_r[4];
|
||||
assign post_img_Bit = post_frame_href ? post_img_Bit_r : 1'b0;
|
||||
|
||||
endmodule
|
@ -0,0 +1,92 @@
|
||||
`timescale 1ns/1ns
|
||||
module Gray_Median_Filter #(
|
||||
parameter [10:0] IMG_HDISP = 11'd640, //640*480
|
||||
parameter [10:0] IMG_VDISP = 11'd480
|
||||
) (
|
||||
//global clock
|
||||
input clk, //100MHz
|
||||
input rst_n, //global reset
|
||||
//Image data prepred to be processd
|
||||
input per_frame_vsync, //Prepared Image data vsync valid signal
|
||||
input per_frame_href, //Prepared Image data href vaild signal
|
||||
input [7:0] per_img_Gray, //Prepared Image brightness input
|
||||
//Image data has been processd
|
||||
output post_frame_vsync, //Processed Image data vsync valid signal
|
||||
output post_frame_href, //Processed Image data href vaild signal
|
||||
output [7:0] post_img_Gray //Processed Image brightness input
|
||||
);
|
||||
|
||||
//----------------------------------------------------
|
||||
//Generate 8Bit 3X3 Matrix for Video Image Processor.
|
||||
//Image data has been processd
|
||||
wire matrix_frame_vsync; //Prepared Image data vsync valid signal
|
||||
wire matrix_frame_href; //Prepared Image data href vaild signal
|
||||
wire matrix_frame_clken; //Prepared Image data output/capture enable clock
|
||||
wire [7:0] matrix_p11, matrix_p12, matrix_p13; //3X3 Matrix output
|
||||
wire [7:0] matrix_p21, matrix_p22, matrix_p23;
|
||||
wire [7:0] matrix_p31, matrix_p32, matrix_p33;
|
||||
Matrix_Generate_3X3_Buf # (
|
||||
.DATA_WIDTH ( 8 ),
|
||||
.IMG_HDISP (IMG_HDISP), //640*480
|
||||
.IMG_VDISP (IMG_VDISP)
|
||||
) Matrix_Generate_3X3_Buf_u (
|
||||
//global clock
|
||||
.clk (clk), //cmos video pixel clock
|
||||
.rst_n (rst_n), //global reset
|
||||
//Image data prepred to be processd
|
||||
.per_frame_vsync (per_frame_vsync), //Prepared Image data vsync valid signal
|
||||
.per_frame_href (per_frame_href), //Prepared Image data href vaild signal
|
||||
.per_img_Data (per_img_Gray), //Prepared Image brightness input
|
||||
//Image data has been processd
|
||||
.matrix_frame_vsync (matrix_frame_vsync), //Processed Image data vsync valid signal
|
||||
.matrix_frame_href (matrix_frame_href), //Processed Image data href vaild signal
|
||||
.matrix_p11(matrix_p11), .matrix_p12(matrix_p12), .matrix_p13(matrix_p13), //3X3 Matrix output
|
||||
.matrix_p21(matrix_p21), .matrix_p22(matrix_p22), .matrix_p23(matrix_p23),
|
||||
.matrix_p31(matrix_p31), .matrix_p32(matrix_p32), .matrix_p33(matrix_p33)
|
||||
);
|
||||
|
||||
|
||||
//Add you arithmetic here
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
//Median Filter of 3X3 datas, need 3 clock
|
||||
wire [7:0] mid_value;
|
||||
Median_Filter_3X3 u_Median_Filter_3X3(
|
||||
.clk (clk),
|
||||
.rst_n (rst_n),
|
||||
//ROW1
|
||||
.data11 (matrix_p11),
|
||||
.data12 (matrix_p12),
|
||||
.data13 (matrix_p13),
|
||||
//ROW2
|
||||
.data21 (matrix_p21),
|
||||
.data22 (matrix_p22),
|
||||
.data23 (matrix_p23),
|
||||
//ROW3
|
||||
.data31 (matrix_p31),
|
||||
.data32 (matrix_p32),
|
||||
.data33 (matrix_p33),
|
||||
|
||||
.target_data (mid_value)
|
||||
);
|
||||
|
||||
//------------------------------------------
|
||||
//lag 3 clocks signal sync
|
||||
reg [2:0] per_frame_vsync_r;
|
||||
reg [2:0] per_frame_href_r;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
per_frame_vsync_r <= 0;
|
||||
per_frame_href_r <= 0;
|
||||
end
|
||||
else begin
|
||||
per_frame_vsync_r <= {per_frame_vsync_r[1:0], matrix_frame_vsync};
|
||||
per_frame_href_r <= {per_frame_href_r[1:0], matrix_frame_href};
|
||||
end
|
||||
end
|
||||
assign post_frame_vsync = per_frame_vsync_r[2];
|
||||
assign post_frame_href = per_frame_href_r[2];
|
||||
assign post_img_Gray = post_frame_href ? mid_value : 8'd0;
|
||||
|
||||
endmodule
|
118
lib/common/Apply/Image/Basic_Apply/Filter/Median_Filter_3X3.v
Normal file
118
lib/common/Apply/Image/Basic_Apply/Filter/Median_Filter_3X3.v
Normal file
@ -0,0 +1,118 @@
|
||||
`timescale 1ns/1ns
|
||||
module Median_Filter_3X3 (
|
||||
input clk,
|
||||
input rst_n,
|
||||
|
||||
input [7:0] data11, data12, data13,
|
||||
input [7:0] data21, data22, data23,
|
||||
input [7:0] data31, data32, data33,
|
||||
|
||||
output [7:0] target_data
|
||||
);
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
//FPGA Median Filter Sort order
|
||||
// Pixel Sort1 Sort2 Sort3
|
||||
// [ P1 P2 P3 ] [ Max1 Mid1 Min1 ]
|
||||
// [ P4 P5 P6 ] [ Max2 Mid2 Min2 ] [Max_min, Mid_mid, Min_max] mid_valid
|
||||
// [ P7 P8 P9 ] [ Max3 Mid3 Min3 ]
|
||||
|
||||
//Step1
|
||||
wire [7:0] max_data1, mid_data1, min_data1;
|
||||
Sort3 u_Sort3_1 (
|
||||
.clk (clk),
|
||||
.rst_n (rst_n),
|
||||
|
||||
.data1 (data11),
|
||||
.data2 (data12),
|
||||
.data3 (data13),
|
||||
|
||||
.max_data (max_data1),
|
||||
.mid_data (mid_data1),
|
||||
.min_data (min_data1)
|
||||
);
|
||||
|
||||
wire [7:0] max_data2, mid_data2, min_data2;
|
||||
Sort3 u_Sort3_2 (
|
||||
.clk (clk),
|
||||
.rst_n (rst_n),
|
||||
|
||||
.data1 (data21),
|
||||
.data2 (data22),
|
||||
.data3 (data23),
|
||||
|
||||
.max_data (max_data2),
|
||||
.mid_data (mid_data2),
|
||||
.min_data (min_data2)
|
||||
);
|
||||
|
||||
wire [7:0] max_data3, mid_data3, min_data3;
|
||||
Sort3 u_Sort3_3 (
|
||||
.clk (clk),
|
||||
.rst_n (rst_n),
|
||||
|
||||
.data1 (data31),
|
||||
.data2 (data32),
|
||||
.data3 (data33),
|
||||
|
||||
.max_data (max_data3),
|
||||
.mid_data (mid_data3),
|
||||
.min_data (min_data3)
|
||||
);
|
||||
|
||||
//Step2
|
||||
wire [7:0] max_min_data, mid_mid_data, min_max_data;
|
||||
Sort3 u_Sort3_4 (
|
||||
.clk (clk),
|
||||
.rst_n (rst_n),
|
||||
|
||||
.data1 (max_data1),
|
||||
.data2 (max_data2),
|
||||
.data3 (max_data3),
|
||||
|
||||
.max_data (),
|
||||
.mid_data (),
|
||||
.min_data (max_min_data)
|
||||
);
|
||||
|
||||
Sort3 u_Sort3_5 (
|
||||
.clk (clk),
|
||||
.rst_n (rst_n),
|
||||
|
||||
.data1 (mid_data1),
|
||||
.data2 (mid_data2),
|
||||
.data3 (mid_data3),
|
||||
|
||||
.max_data (),
|
||||
.mid_data (mid_mid_data),
|
||||
.min_data ()
|
||||
);
|
||||
|
||||
Sort3 u_Sort3_6 (
|
||||
.clk (clk),
|
||||
.rst_n (rst_n),
|
||||
|
||||
.data1 (min_data1),
|
||||
.data2 (min_data2),
|
||||
.data3 (min_data3),
|
||||
|
||||
.max_data (min_max_data),
|
||||
.mid_data (),
|
||||
.min_data ()
|
||||
);
|
||||
|
||||
//step3
|
||||
Sort3 u_Sort3_7 (
|
||||
.clk (clk),
|
||||
.rst_n (rst_n),
|
||||
|
||||
.data1 (max_min_data),
|
||||
.data2 (mid_mid_data),
|
||||
.data3 (min_max_data),
|
||||
|
||||
.max_data (),
|
||||
.mid_data (target_data),
|
||||
.min_data ()
|
||||
);
|
||||
|
||||
endmodule
|
115
lib/common/Apply/Image/Basic_Apply/Matrix/Matrix_Generate_3X3.v
Normal file
115
lib/common/Apply/Image/Basic_Apply/Matrix/Matrix_Generate_3X3.v
Normal file
@ -0,0 +1,115 @@
|
||||
`timescale 1ns/1ns
|
||||
module Matrix_Generate_3X3 #(
|
||||
parameter DATA_WIDTH = 8,
|
||||
parameter IMG_HDISP = 640, //640*480
|
||||
parameter IMG_VDISP = 480
|
||||
) (
|
||||
//global clock
|
||||
input clk, //cmos video pixel clock
|
||||
input rst_n, //global reset
|
||||
|
||||
//Image data prepred to be processd
|
||||
input per_frame_vsync, //Prepared Image data vsync valid signal
|
||||
input per_frame_href, //Prepared Image data href vaild signal
|
||||
input [DATA_WIDTH-1:0] per_img_Data, //Prepared Image brightness input
|
||||
|
||||
//Image data has been processd
|
||||
output matrix_frame_vsync, //Prepared Image data vsync valid signal
|
||||
output matrix_frame_href, //Prepared Image data href vaild signal
|
||||
|
||||
output reg [DATA_WIDTH-1:0] matrix_p11, matrix_p12, matrix_p13, //3X3 Matrix output
|
||||
output reg [DATA_WIDTH-1:0] matrix_p21, matrix_p22, matrix_p23,
|
||||
output reg [DATA_WIDTH-1:0] matrix_p31, matrix_p32, matrix_p33
|
||||
);
|
||||
|
||||
|
||||
//Generate 3*3 matrix
|
||||
//--------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------
|
||||
//sync row3_data with per_frame_clken & row1_data & raw2_data
|
||||
wire [DATA_WIDTH-1:0] row1_data; //frame data of the 1th row
|
||||
wire [DATA_WIDTH-1:0] row2_data; //frame data of the 2th row
|
||||
reg [DATA_WIDTH-1:0] row3_data; //frame data of the 3th row
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n)
|
||||
row3_data <= 0;
|
||||
else begin
|
||||
if(per_frame_href)
|
||||
row3_data <= per_img_Data;
|
||||
else
|
||||
row3_data <= row3_data;
|
||||
end
|
||||
end
|
||||
|
||||
//---------------------------------------
|
||||
//module of shift ram for raw data
|
||||
wire shift_clk_en = per_frame_href;
|
||||
Line_Shift_RAM #(
|
||||
.RAM_Length ( IMG_HDISP ),
|
||||
.DATA_WIDTH ( DATA_WIDTH )
|
||||
) u_Line_Shift_RAM (
|
||||
.clock ( clk ),
|
||||
.clken ( shift_clk_en ),
|
||||
.shiftin ( row3_data ),
|
||||
|
||||
.taps0x ( row2_data ),
|
||||
.taps1x ( row1_data )
|
||||
);
|
||||
//------------------------------------------
|
||||
//lag 2 clocks signal sync
|
||||
reg [1:0] per_frame_vsync_r;
|
||||
reg [1:0] per_frame_href_r;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
per_frame_vsync_r <= 0;
|
||||
per_frame_href_r <= 0;
|
||||
end
|
||||
else begin
|
||||
per_frame_vsync_r <= {per_frame_vsync_r[0], per_frame_vsync};
|
||||
per_frame_href_r <= {per_frame_href_r[0], per_frame_href};
|
||||
end
|
||||
end
|
||||
//Give up the 1th and 2th row edge data caculate for simple process
|
||||
//Give up the 1th and 2th point of 1 line for simple process
|
||||
wire read_frame_href = per_frame_href_r[0]; //RAM read href sync signal
|
||||
assign matrix_frame_vsync = per_frame_vsync_r[1];
|
||||
assign matrix_frame_href = per_frame_href_r[1];
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
/******************************************************************************
|
||||
---------- Convert Matrix ----------
|
||||
[ P31 -> P32 -> P33 -> ] ---> [ P11 P12 P13 ]
|
||||
[ P21 -> P22 -> P23 -> ] ---> [ P21 P22 P23 ]
|
||||
[ P11 -> P12 -> P11 -> ] ---> [ P31 P32 P33 ]
|
||||
******************************************************************************/
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------
|
||||
/***********************************************
|
||||
(1) Read data from Shift_RAM
|
||||
(2) Caculate the Sobel
|
||||
(3) Steady data after Sobel generate
|
||||
************************************************/
|
||||
//wire [2:0] matrix_row1 = {matrix_p11, matrix_p12, matrix_p13}; //Just for test
|
||||
//wire [2:0] matrix_row2 = {matrix_p21, matrix_p22, matrix_p23};
|
||||
//wire [2:0] matrix_row3 = {matrix_p31, matrix_p32, matrix_p33};
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
{matrix_p11, matrix_p12, matrix_p13} <= 0;
|
||||
{matrix_p21, matrix_p22, matrix_p23} <= 0;
|
||||
{matrix_p31, matrix_p32, matrix_p33} <= 0;
|
||||
end
|
||||
else if(read_frame_href) begin
|
||||
{matrix_p11, matrix_p12, matrix_p13} <= {matrix_p12, matrix_p13, row1_data}; //1th shift input
|
||||
{matrix_p21, matrix_p22, matrix_p23} <= {matrix_p22, matrix_p23, row2_data}; //2th shift input
|
||||
{matrix_p31, matrix_p32, matrix_p33} <= {matrix_p32, matrix_p33, row3_data}; //3th shift input
|
||||
end
|
||||
else begin
|
||||
{matrix_p11, matrix_p12, matrix_p13} <= 0;
|
||||
{matrix_p21, matrix_p22, matrix_p23} <= 0;
|
||||
{matrix_p31, matrix_p32, matrix_p33} <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -0,0 +1,148 @@
|
||||
`timescale 1ns/1ns
|
||||
module Matrix_Generate_3X3_Buf #(
|
||||
parameter DATA_WIDTH = 8,
|
||||
parameter IMG_HDISP = 640, //640*480
|
||||
parameter IMG_VDISP = 480
|
||||
) (
|
||||
//global clock
|
||||
input clk, //cmos video pixel clock
|
||||
input rst_n, //global reset
|
||||
|
||||
//Image data prepred to be processd
|
||||
input per_frame_vsync, //Prepared Image data vsync valid signal
|
||||
input per_frame_href, //Prepared Image data href vaild signal
|
||||
input [DATA_WIDTH-1:0] per_img_Data, //Prepared Image brightness input
|
||||
|
||||
//Image data has been processd
|
||||
output matrix_frame_vsync, //Prepared Image data vsync valid signal
|
||||
output matrix_frame_href, //Prepared Image data href vaild signal
|
||||
|
||||
output reg [DATA_WIDTH-1:0] matrix_p11, matrix_p12, matrix_p13, //3X3 Matrix output
|
||||
output reg [DATA_WIDTH-1:0] matrix_p21, matrix_p22, matrix_p23,
|
||||
output reg [DATA_WIDTH-1:0] matrix_p31, matrix_p32, matrix_p33
|
||||
);
|
||||
|
||||
|
||||
//Generate 3*3 matrix
|
||||
//--------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------
|
||||
//sync row3_data with per_frame_clken & row1_data & raw2_data
|
||||
wire [DATA_WIDTH-1:0] row1_data; //frame data of the 1th row
|
||||
wire [DATA_WIDTH-1:0] row2_data; //frame data of the 2th row
|
||||
reg [DATA_WIDTH-1:0] row3_data; //frame data of the 3th row
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n)
|
||||
row3_data <= 0;
|
||||
else begin
|
||||
if(per_frame_href)
|
||||
row3_data <= per_img_Data;
|
||||
else
|
||||
row3_data <= row3_data;
|
||||
end
|
||||
end
|
||||
|
||||
//---------------------------------------
|
||||
//module of shift ram for raw data
|
||||
wire shift_clk_en = per_frame_href;
|
||||
Line_Shift_RAM #(
|
||||
.RAM_Length ( IMG_HDISP ),
|
||||
.DATA_WIDTH ( DATA_WIDTH )
|
||||
) u_Line_Shift_RAM (
|
||||
.clock ( clk ),
|
||||
.clken ( shift_clk_en ),
|
||||
.shiftin ( row3_data ),
|
||||
|
||||
.taps0x ( row2_data ),
|
||||
.taps1x ( row1_data )
|
||||
);
|
||||
//------------------------------------------
|
||||
//lag 2 clocks signal sync
|
||||
reg [2:0] per_frame_vsync_r;
|
||||
reg [2:0] per_frame_href_r;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
per_frame_vsync_r <= 0;
|
||||
per_frame_href_r <= 0;
|
||||
end
|
||||
else begin
|
||||
per_frame_vsync_r <= {per_frame_vsync_r[1:0], per_frame_vsync};
|
||||
per_frame_href_r <= {per_frame_href_r[1:0], per_frame_href};
|
||||
end
|
||||
end
|
||||
//Give up the 1th and 2th row edge data caculate for simple process
|
||||
//Give up the 1th and 2th point of 1 line for simple process
|
||||
wire read_frame_href = per_frame_href_r[0]|per_frame_href_r[1]; //RAM read href sync signal
|
||||
assign matrix_frame_vsync = per_frame_vsync_r[2];
|
||||
assign matrix_frame_href = per_frame_href_r[2];
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
/******************************************************************************
|
||||
---------- Convert Matrix ----------
|
||||
[ P31 -> P32 -> P33 -> ] ---> [ P11 P12 P13 ]
|
||||
[ P21 -> P22 -> P23 -> ] ---> [ P21 P22 P23 ]
|
||||
[ P11 -> P12 -> P11 -> ] ---> [ P31 P32 P33 ]
|
||||
******************************************************************************/
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------
|
||||
/***********************************************
|
||||
(1) Read data from Shift_RAM
|
||||
(2) Caculate the Sobel
|
||||
(3) Steady data after Sobel generate
|
||||
************************************************/
|
||||
//wire [23:0] matrix_row1 = {matrix_p11, matrix_p12, matrix_p13}; //Just for test
|
||||
//wire [23:0] matrix_row2 = {matrix_p21, matrix_p22, matrix_p23};
|
||||
//wire [23:0] matrix_row3 = {matrix_p31, matrix_p32, matrix_p33};
|
||||
reg [31:0] pixel_cnt;
|
||||
reg [DATA_WIDTH-1:0] row1_data0;
|
||||
reg [DATA_WIDTH-1:0] row2_data0;
|
||||
reg [DATA_WIDTH-1:0] row3_data0;
|
||||
reg [DATA_WIDTH-1:0] row1_data1;
|
||||
reg [DATA_WIDTH-1:0] row2_data1;
|
||||
reg [DATA_WIDTH-1:0] row3_data1;
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
pixel_cnt <= 0;
|
||||
row1_data0 <= 0; row1_data1 <= 0;
|
||||
row2_data0 <= 0; row2_data1 <= 0;
|
||||
row3_data0 <= 0; row3_data1 <= 0;
|
||||
{matrix_p11, matrix_p12, matrix_p13} <= 0;
|
||||
{matrix_p21, matrix_p22, matrix_p23} <= 0;
|
||||
{matrix_p31, matrix_p32, matrix_p33} <= 0;
|
||||
end
|
||||
else if(read_frame_href) begin
|
||||
pixel_cnt <= (pixel_cnt < IMG_HDISP) ? pixel_cnt + 1'b1 : 32'd0; //Point Counter
|
||||
{row1_data1, row1_data0} <= {row1_data0, row1_data};
|
||||
{row2_data1, row2_data0} <= {row2_data0, row2_data};
|
||||
{row3_data1, row3_data0} <= {row3_data0, row3_data};
|
||||
if(pixel_cnt == 0) begin
|
||||
{matrix_p11, matrix_p12, matrix_p13} <= 0;
|
||||
{matrix_p21, matrix_p22, matrix_p23} <= 0;
|
||||
{matrix_p31, matrix_p32, matrix_p33} <= 0;
|
||||
end
|
||||
else if(pixel_cnt == 1) begin
|
||||
{matrix_p11, matrix_p12, matrix_p13} <= {row1_data, row1_data0, row1_data};
|
||||
{matrix_p21, matrix_p22, matrix_p23} <= {row2_data, row2_data0, row2_data};
|
||||
{matrix_p31, matrix_p32, matrix_p33} <= {row3_data, row3_data0, row3_data};
|
||||
end
|
||||
else if(pixel_cnt == IMG_HDISP) begin
|
||||
{matrix_p11, matrix_p12, matrix_p13} <= {row1_data1, row1_data, row1_data1};
|
||||
{matrix_p21, matrix_p22, matrix_p23} <= {row2_data1, row2_data, row2_data1};
|
||||
{matrix_p31, matrix_p32, matrix_p33} <= {row3_data1, row3_data, row3_data1};
|
||||
end
|
||||
else begin
|
||||
{matrix_p11, matrix_p12, matrix_p13} <= {row1_data1, row1_data0, row1_data};
|
||||
{matrix_p21, matrix_p22, matrix_p23} <= {row2_data1, row2_data0, row2_data};
|
||||
{matrix_p31, matrix_p32, matrix_p33} <= {row3_data1, row3_data0, row3_data};
|
||||
end
|
||||
end
|
||||
else begin
|
||||
pixel_cnt <= 0;
|
||||
{matrix_p11, matrix_p12, matrix_p13} <= 0;
|
||||
{matrix_p21, matrix_p22, matrix_p23} <= 0;
|
||||
{matrix_p31, matrix_p32, matrix_p33} <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
228
lib/common/Apply/Image/Basic_Apply/Video_Image_Processor.v
Normal file
228
lib/common/Apply/Image/Basic_Apply/Video_Image_Processor.v
Normal file
@ -0,0 +1,228 @@
|
||||
`timescale 1ns/1ns
|
||||
module Video_Image_Processor #(
|
||||
parameter RAW2RG888_YUV444 = "ON",
|
||||
parameter GRAY_MEDIUM = "ON",
|
||||
parameter GRAY_SOBEL = "ON",
|
||||
parameter GRAY_EROSION = "ON",
|
||||
parameter GRAY_DILATION = "ON",
|
||||
parameter IMG_HDISP = 11'd640, //640*480
|
||||
parameter IMG_VDISP = 11'd480
|
||||
) (
|
||||
//global clock
|
||||
input clk, //cmos video pixel clock
|
||||
input rst_n, //global reset
|
||||
//Image data prepred to be processd
|
||||
input per_frame_vsync, //Prepared Image data vsync valid signal
|
||||
input per_frame_href, //Prepared Image data href vaild signal
|
||||
input [7:0] per_img_RAW, //Prepared Image data of YCbCr 4:2:2 {CbY} {CrY}
|
||||
//Image data has been processd
|
||||
output post_frame_vsync, //Processed Image data vsync valid signal
|
||||
output post_frame_href, //Processed Image data href vaild signal
|
||||
output [7:0] post_img_Gray, //Processed Image Gray output
|
||||
//user interface
|
||||
input [7:0] Sobel_Threshold //Sobel Threshold for image edge detect
|
||||
);
|
||||
|
||||
//-------------------------------------
|
||||
//Convert the RAW format to RGB888 format.
|
||||
wire post1_frame_vsync; //Processed Image data vsync valid signal
|
||||
wire post1_frame_href; //Processed Image data href vaild signal
|
||||
wire [7:0] post1_img_red; //Processed Image Red output
|
||||
wire [7:0] post1_img_green; //Processed Image Green output
|
||||
wire [7:0] post1_img_blue; //Processed Image Blueoutput
|
||||
wire post2_frame_vsync; //Processed Image data vsync valid signal
|
||||
wire post2_frame_href; //Processed Image data href vaild signal
|
||||
wire [7:0] post2_img_Gray; //Processed Image Gray output
|
||||
|
||||
generate if(RAW2RG888_YUV444 == "ON") begin : RAW2RG888_YUV444_ON
|
||||
RAW8_RGB888 # (
|
||||
.IMG_HDISP (IMG_HDISP), //640*480
|
||||
.IMG_VDISP (IMG_VDISP)
|
||||
) RAW8_RGB888_u (
|
||||
//global clock
|
||||
.clk (clk), //cmos video pixel clock
|
||||
.rst_n (rst_n), //system reset
|
||||
|
||||
//Image data prepred to be processd
|
||||
.per_frame_vsync (per_frame_vsync), //Prepared Image data vsync valid signal
|
||||
.per_frame_href (per_frame_href), //Prepared Image data href vaild signal
|
||||
.per_img_RAW (per_img_RAW), //Prepared Image data 8 Bit RAW Data
|
||||
|
||||
//Image data has been processd
|
||||
.post_frame_vsync (post1_frame_vsync), //Processed Image data vsync valid signal
|
||||
.post_frame_href (post1_frame_href), //Processed Image data href vaild signal
|
||||
.post_img_red (post1_img_red), //Prepared Image green data to be processed
|
||||
.post_img_green (post1_img_green), //Prepared Image green data to be processed
|
||||
.post_img_blue (post1_img_blue) //Prepared Image blue data to be processed
|
||||
);
|
||||
//-------------------------------------
|
||||
//Convert the RGB888 format to YCbCr444 format.
|
||||
RGB888_YCbCr444 RGB888_YCbCr444_u(
|
||||
//global clock
|
||||
.clk (clk), //cmos video pixel clock
|
||||
.rst_n (rst_n), //system reset
|
||||
|
||||
//Image data prepred to be processd
|
||||
.per_frame_vsync (post1_frame_vsync), //Prepared Image data vsync valid signal
|
||||
.per_frame_href (post1_frame_href), //Prepared Image data href vaild signal
|
||||
.per_img_red (post1_img_red), //Prepared Image red data input
|
||||
.per_img_green (post1_img_green), //Prepared Image green data input
|
||||
.per_img_blue (post1_img_blue), //Prepared Image blue data input
|
||||
|
||||
//Image data has been processd
|
||||
.post_frame_vsync (post2_frame_vsync), //Processed Image frame data valid signal
|
||||
.post_frame_href (post2_frame_href), //Processed Image hsync data valid signal
|
||||
.post_img_Y (post2_img_Gray), //Processed Image brightness output
|
||||
.post_img_Cb (), //Processed Image blue shading output
|
||||
.post_img_Cr () //Processed Image red shading output
|
||||
);
|
||||
end
|
||||
else if(RAW2RG888_YUV444 == "OFF") begin : RAW2RG888_YUV444_OFF
|
||||
assign post2_frame_vsync = per_frame_vsync;
|
||||
assign post2_frame_href = per_frame_href;
|
||||
assign post2_img_Gray = per_img_RAW;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
//--------------------------------------
|
||||
//Gray Image median filter for better picture quality.
|
||||
wire post3_frame_vsync; //Processed Image data vsync valid signal
|
||||
wire post3_frame_href; //Processed Image data href vaild signal
|
||||
wire [7:0] post3_img_Gray; //Processed Image Gray output
|
||||
generate if(GRAY_MEDIUM == "ON") begin : GRAY_MEDIUM_ON
|
||||
Gray_Median_Filter # (
|
||||
.IMG_HDISP (IMG_HDISP), //640*480
|
||||
.IMG_VDISP (IMG_VDISP)
|
||||
) Gray_Median_Filter_u (
|
||||
//global clock
|
||||
.clk (clk), //cmos video pixel clock
|
||||
.rst_n (rst_n), //global reset
|
||||
|
||||
//Image data prepred to be processd
|
||||
.per_frame_vsync (post2_frame_vsync), //Prepared Image data vsync valid signal
|
||||
.per_frame_href (post2_frame_href), //Prepared Image data href vaild signal
|
||||
.per_img_Gray (post2_img_Gray), //Prepared Image brightness input
|
||||
|
||||
//Image data has been processd
|
||||
.post_frame_vsync (post3_frame_vsync), //Processed Image data vsync valid signal
|
||||
.post_frame_href (post3_frame_href), //Processed Image data href vaild signal
|
||||
.post_img_Gray (post3_img_Gray) //Processed Image brightness output
|
||||
);
|
||||
end
|
||||
else if(GRAY_MEDIUM == "OFF") begin : GRAY_MEDIUM_OFF
|
||||
assign post3_frame_vsync = post2_frame_vsync;
|
||||
assign post3_frame_href = post2_frame_href;
|
||||
assign post3_img_Gray = post2_img_Gray;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
//--------------------------------------
|
||||
//Image edge detector with Sobel.
|
||||
wire post4_frame_vsync; //Processed Image data vsync valid signal
|
||||
wire post4_frame_href; //Processed Image data href vaild signal
|
||||
wire post4_img_Bit; //Processed Image Bit flag outout(1: Value, 0:inValid)
|
||||
wire [7:0] post4_img_Gray;
|
||||
generate if(GRAY_SOBEL == "ON") begin : GRAY_SOBEL_ON
|
||||
Sobel_Edge_Detector # (
|
||||
.IMG_HDISP (IMG_HDISP), //640*480
|
||||
.IMG_VDISP (IMG_VDISP)
|
||||
) Sobel_Edge_Detector_u (
|
||||
//global clock
|
||||
.clk (clk), //cmos video pixel clock
|
||||
.rst_n (rst_n), //global reset
|
||||
|
||||
//Image data prepred to be processd
|
||||
.per_frame_vsync (post3_frame_vsync), //Prepared Image data vsync valid signal
|
||||
.per_frame_href (post3_frame_href), //Prepared Image data href vaild signal
|
||||
.per_img_Gray (post3_img_Gray), //Prepared Image brightness input
|
||||
|
||||
//Image data has been processd
|
||||
.post_frame_vsync (post4_frame_vsync), //Processed Image data vsync valid signal
|
||||
.post_frame_href (post4_frame_href), //Processed Image data href vaild signal
|
||||
.post_img_Bit (post4_img_Bit), //Processed Image Bit flag outout(1: Value, 0:inValid)
|
||||
|
||||
//User interface
|
||||
.Sobel_Threshold (Sobel_Threshold) //Sobel Threshold for image edge detect
|
||||
);
|
||||
assign post4_img_Gray = {8{~post4_img_Bit}};
|
||||
end
|
||||
else if(GRAY_SOBEL == "OFF") begin : GRAY_SOBEL_OFF
|
||||
assign post4_frame_vsync = post3_frame_vsync;
|
||||
assign post4_frame_href = post3_frame_href;
|
||||
assign post4_img_Gray = post3_img_Gray;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
//--------------------------------------
|
||||
//Bit Image Process with Erosion before Dilation Detector.
|
||||
wire post5_frame_vsync; //Processed Image data vsync valid signal
|
||||
wire post5_frame_href; //Processed Image data href vaild signal
|
||||
wire post5_img_Bit; //Processed Image Bit flag outout(1: Value, 0:inValid)
|
||||
wire [7:0] post5_img_Gray;
|
||||
generate if(GRAY_EROSION == "ON") begin : GRAY_EROSION_ON
|
||||
Bit_Erosion_Detector # (
|
||||
.IMG_HDISP (IMG_HDISP), //640*480
|
||||
.IMG_VDISP (IMG_VDISP)
|
||||
) Bit_Erosion_Detector_u (
|
||||
//global clock
|
||||
.clk (clk), //cmos video pixel clock
|
||||
.rst_n (rst_n), //global reset
|
||||
|
||||
//Image data prepred to be processd
|
||||
.per_frame_vsync (post4_frame_vsync), //Prepared Image data vsync valid signal
|
||||
.per_frame_href (post4_frame_href), //Prepared Image data href vaild signal
|
||||
.per_img_Bit (post4_img_Gray[0]), //Processed Image Bit flag outout(1: Value, 0:inValid)
|
||||
|
||||
//Image data has been processd
|
||||
.post_frame_vsync (post5_frame_vsync), //Processed Image data vsync valid signal
|
||||
.post_frame_href (post5_frame_href), //Processed Image data href vaild signal
|
||||
.post_img_Bit (post5_img_Bit) //Processed Image Bit flag outout(1: Value, 0:inValid)
|
||||
);
|
||||
assign post5_img_Gray = {8{post5_img_Bit}};
|
||||
end
|
||||
else if(GRAY_EROSION == "OFF") begin : GRAY_EROSION_OFF
|
||||
assign post5_frame_vsync = post4_frame_vsync;
|
||||
assign post5_frame_href = post4_frame_href;
|
||||
assign post5_img_Gray = post4_img_Gray;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
//--------------------------------------
|
||||
//Bit Image Process with Dilation after Erosion Detector.
|
||||
wire post6_frame_vsync; //Processed Image data vsync valid signal
|
||||
wire post6_frame_href; //Processed Image data href vaild signal
|
||||
wire post6_img_Bit; //Processed Image Bit flag outout(1: Value, 0:inValid)
|
||||
wire [7:0] post6_img_Gray;
|
||||
generate if(GRAY_DILATION == "ON") begin : GRAY_DILATION_ON
|
||||
Bit_Dilation_Detector # (
|
||||
.IMG_HDISP (IMG_HDISP), //640*480
|
||||
.IMG_VDISP (IMG_VDISP)
|
||||
) Bit_Dilation_Detector_u (
|
||||
//global clock
|
||||
.clk (clk), //cmos video pixel clock
|
||||
.rst_n (rst_n), //global reset
|
||||
|
||||
//Image data prepred to be processd
|
||||
.per_frame_vsync (post5_frame_vsync), //Prepared Image data vsync valid signal
|
||||
.per_frame_href (post5_frame_href), //Prepared Image data href vaild signal
|
||||
.per_img_Bit (post5_img_Gray[0]), //Processed Image Bit flag outout(1: Value, 0:inValid)
|
||||
|
||||
//Image data has been processd
|
||||
.post_frame_vsync (post6_frame_vsync), //Processed Image data vsync valid signal
|
||||
.post_frame_href (post6_frame_href), //Processed Image data href vaild signal
|
||||
.post_img_Bit (post6_img_Bit) //Processed Image Bit flag outout(1: Value, 0:inValid)
|
||||
);
|
||||
assign post6_img_Gray = {8{post6_img_Bit}};
|
||||
end
|
||||
else if(GRAY_DILATION == "OFF") begin : GRAY_DILATION_OFF
|
||||
assign post6_frame_vsync = post5_frame_vsync;
|
||||
assign post6_frame_href = post5_frame_href;
|
||||
assign post6_img_Gray = post5_img_Gray;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign post_frame_vsync = post6_frame_vsync; //Processed Image data vsync valid signal
|
||||
assign post_frame_href = post6_frame_href; //Processed Image data href vaild signal
|
||||
assign post_img_Gray = post6_img_Gray; //Processed Image Gray output
|
||||
|
||||
endmodule
|
17
lib/common/Driver/ADC_driver/AD6645/AD6645.v
Normal file
17
lib/common/Driver/ADC_driver/AD6645/AD6645.v
Normal file
@ -0,0 +1,17 @@
|
||||
module AD6645
|
||||
(
|
||||
input clk_in,
|
||||
input rst_n,
|
||||
input [13:0] AD_data,
|
||||
output [13:0] wave_CH
|
||||
);
|
||||
reg [13:0] wave_CH_buf;
|
||||
always@(posedge clk_in or negedge rst_n)
|
||||
begin
|
||||
if(!rst_n)
|
||||
wave_CH_buf <= 14'd0;
|
||||
else
|
||||
wave_CH_buf <= AD_data;
|
||||
end
|
||||
assign wave_CH = wave_CH_buf - 14'd1700;
|
||||
endmodule
|
195
lib/common/Driver/ADC_driver/ADS412x_driver/ADC_CFG.vhd
Normal file
195
lib/common/Driver/ADC_driver/ADS412x_driver/ADC_CFG.vhd
Normal file
@ -0,0 +1,195 @@
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.STD_LOGIC_unsigned.ALL;
|
||||
|
||||
-- Uncomment the following library declaration if using
|
||||
-- arithmetic functions with Signed or Unsigned values
|
||||
--use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
-- Uncomment the following library declaration if instantiating
|
||||
-- any Xilinx leaf cells in this code.
|
||||
library UNISIM;
|
||||
use UNISIM.VComponents.all;
|
||||
|
||||
entity ADC_CFG is
|
||||
Port (
|
||||
clk : in std_logic;
|
||||
rstn : in std_logic;
|
||||
sclk : out std_logic;
|
||||
sdata : out std_logic;
|
||||
sen : out std_logic;
|
||||
adc_rst : out std_logic;
|
||||
cfg_done : out std_logic
|
||||
);
|
||||
end ADC_CFG;
|
||||
|
||||
architecture Behavioral of ADC_CFG iimage.pngsimage.png
|
||||
image.png
|
||||
component CFG_INT
|
||||
Port (
|
||||
CLK : in STD_LOGIC;--100mhz
|
||||
RSTn : in STD_LOGIC;
|
||||
TRIG : in STD_LOGIC;
|
||||
ADDR : in STD_LOGIC_VECTOR (7 downto 0);
|
||||
DATA : in STD_LOGIC_VECTOR (7 downto 0);
|
||||
SCLK : out STD_LOGIC;
|
||||
SDATA : out STD_LOGIC;
|
||||
SEN : out STD_LOGIC;
|
||||
BUSY : out STD_LOGIC
|
||||
);
|
||||
end component;
|
||||
|
||||
type array_reg is array (0 to 25) of std_logic_vector(7 downto 0);
|
||||
signal addr_reg : array_reg :=( x"42", --
|
||||
x"00", --bit0 readout ; --bit1 reset
|
||||
x"01",
|
||||
x"03",
|
||||
x"25",
|
||||
x"29",
|
||||
x"2b",
|
||||
x"3d",
|
||||
x"3f",
|
||||
x"40",
|
||||
x"41",
|
||||
x"42",
|
||||
x"45",
|
||||
x"4a",
|
||||
x"58",
|
||||
x"bf",
|
||||
x"c1",
|
||||
x"cf",
|
||||
x"ef",
|
||||
x"f1",
|
||||
x"f2",
|
||||
x"02",
|
||||
x"d5",
|
||||
x"d7",
|
||||
x"db",
|
||||
x"00" --the last byte no meaning
|
||||
);
|
||||
constant data_reg : array_reg :=( x"08", --
|
||||
x"00", --bit0 readout ; --bit1 reset
|
||||
x"00",
|
||||
x"03",
|
||||
x"00",
|
||||
x"00",
|
||||
x"00",
|
||||
x"00",
|
||||
x"00",
|
||||
x"00",
|
||||
x"03",
|
||||
x"08",
|
||||
x"00",
|
||||
x"01",
|
||||
x"01",
|
||||
x"00",
|
||||
x"00",
|
||||
x"00",
|
||||
x"00",
|
||||
x"03",
|
||||
x"00",
|
||||
x"40",
|
||||
x"18",
|
||||
x"0c",
|
||||
x"20",
|
||||
x"00" --the last byte no meaning
|
||||
);
|
||||
signal trig : std_logic;
|
||||
signal busy : std_logic;
|
||||
signal busy_r : std_logic;
|
||||
signal busy_rr : std_logic;
|
||||
signal busy_rrr : std_logic;
|
||||
signal resetn : std_logic;
|
||||
signal busy_pulse : std_logic;
|
||||
signal cfg_done_i : std_logic;
|
||||
signal byte_count : std_logic_vector(7 downto 0);
|
||||
signal addr : std_logic_vector(7 downto 0);
|
||||
signal data : std_logic_vector(7 downto 0);
|
||||
signal rst_count : std_logic_vector(11 downto 0);
|
||||
signal clkIbuf : std_logic;
|
||||
signal clkIbufG : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
clkIbufG <= clk;
|
||||
|
||||
CFG_INT_inst : CFG_INT
|
||||
Port map(
|
||||
CLK => clkIbufG ,--: in STD_LOGIC;--100mhz
|
||||
RSTn => rstn ,--: in STD_LOGIC;
|
||||
TRIG => trig ,--: in STD_LOGIC;
|
||||
ADDR => addr ,--: in STD_LOGIC_VECTOR (7 downto 0);
|
||||
DATA => data ,--: in STD_LOGIC_VECTOR (7 downto 0);
|
||||
SCLK => sclk ,--: out STD_LOGIC;
|
||||
SDATA => sdata ,--: out STD_LOGIC;
|
||||
SEN => sen ,--: out STD_LOGIC;
|
||||
BUSY => busy --: out STD_LOGIC
|
||||
);
|
||||
|
||||
process(clkIbufG,rstn)
|
||||
begin
|
||||
if rstn='0' then
|
||||
rst_count<=(others=>'0');
|
||||
elsif rising_edge(clkIbufG) then
|
||||
if rst_count=x"2ff" then
|
||||
rst_count<=rst_count;
|
||||
else
|
||||
rst_count<=rst_count+1;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
adc_rst<=not rst_count(9);
|
||||
|
||||
resetn<='1' when rstn='1' and rst_count(9)='1' else '0';
|
||||
|
||||
process(clkIbufG,resetn)
|
||||
begin
|
||||
if resetn='0' then busy_r<='0';
|
||||
busy_rr<='0';
|
||||
busy_rrr<='0';
|
||||
elsif rising_edge(clkIbufG) then
|
||||
busy_r<=busy;
|
||||
busy_rr<=busy_r;
|
||||
busy_rrr<=busy_rr;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
busy_pulse<='1' when busy_r='0' and busy_rr='1' else '0';
|
||||
|
||||
process(clkIbufG,resetn)
|
||||
begin
|
||||
if resetn='0' then byte_count<=(others=>'0');
|
||||
cfg_done_i<='0';
|
||||
elsif rising_edge(clkIbufG) then
|
||||
cfg_done_i<='0';
|
||||
if byte_count=x"10" then
|
||||
byte_count<=byte_count;
|
||||
cfg_done_i<='1';
|
||||
elsif busy_pulse='1' then
|
||||
byte_count<=byte_count+1;
|
||||
else
|
||||
byte_count<=byte_count;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cfg_done<=cfg_done_i;
|
||||
|
||||
addr<=addr_reg(conv_integer(byte_count));
|
||||
data<=data_reg(conv_integer(byte_count));
|
||||
|
||||
process(clkIbufG,resetn)
|
||||
begin
|
||||
if resetn='0' then
|
||||
trig<='0';
|
||||
elsif rising_edge(clkIbufG) then
|
||||
if byte_count/=x"10" and busy_rrr='0' then
|
||||
trig<='1';
|
||||
else
|
||||
trig<='0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
51
lib/common/Driver/ADC_driver/ADS412x_driver/ADS412x_driver.v
Normal file
51
lib/common/Driver/ADC_driver/ADS412x_driver/ADS412x_driver.v
Normal file
@ -0,0 +1,51 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module ADS412x_driver(
|
||||
// input sys_rst_n,
|
||||
input user_clk,
|
||||
output [11:0] user_rd_data,
|
||||
|
||||
output adc_sclk, // sclk
|
||||
output adc_sdata, // sda
|
||||
output adc_reset,
|
||||
output adc_sen,
|
||||
input [11:0] adc_data,
|
||||
input adc_clk,
|
||||
output adc_samp_clk
|
||||
);
|
||||
|
||||
wire sys_rst_n;
|
||||
assign sys_rst_n = 1;
|
||||
|
||||
wire adc_config_done;
|
||||
wire rst_n;
|
||||
reg [11:0] adc_data_r;
|
||||
reg [11:0] adc_data_rr;
|
||||
|
||||
assign adc_samp_clk=user_clk;
|
||||
assign rst_n = ((adc_config_done == 1'b1) && (sys_rst_n == 1'b1)) ? 1'b1 : 1'b0;
|
||||
|
||||
assign user_rd_data=adc_data_rr;////
|
||||
|
||||
ADC_CFG u_ADS4128_CFG(
|
||||
.clk ( user_clk ),
|
||||
.rstn ( sys_rst_n ),
|
||||
.sclk ( adc_sclk ),
|
||||
.sdata ( adc_sdata ),
|
||||
.sen ( adc_sen ),
|
||||
.adc_rst ( adc_reset ),
|
||||
.cfg_done ( adc_config_done )
|
||||
);
|
||||
|
||||
always @ (posedge adc_clk) begin
|
||||
if (rst_n == 1'b0) begin
|
||||
adc_data_r <= 12'h000;
|
||||
adc_data_rr <= 12'h000;
|
||||
end
|
||||
else begin
|
||||
adc_data_r <= adc_data;
|
||||
adc_data_rr <= adc_data_r + 12'b1000_0000_0000;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
250
lib/common/Driver/ADC_driver/ADS412x_driver/CFG_INT.vhd
Normal file
250
lib/common/Driver/ADC_driver/ADS412x_driver/CFG_INT.vhd
Normal file
@ -0,0 +1,250 @@
|
||||
----------------------------------------------------------------------------------
|
||||
-- Company:
|
||||
-- Engineer:
|
||||
--
|
||||
-- Create Date: 2016/04/06 13:55:20
|
||||
-- Design Name:
|
||||
-- Module Name: CFG_INT - Behavioral
|
||||
-- Project Name:
|
||||
-- Target Devices:
|
||||
-- Tool Versions:
|
||||
-- Description:
|
||||
--
|
||||
-- Dependencies:
|
||||
--
|
||||
-- Revision:
|
||||
-- Revision 0.01 - File Created
|
||||
-- Additional Comments:
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.STD_LOGIC_unsigned.ALL;
|
||||
|
||||
-- Uncomment the following library declaration if using
|
||||
-- arithmetic functions with Signed or Unsigned values
|
||||
--use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
-- Uncomment the following library declaration if instantiating
|
||||
-- any Xilinx leaf cells in this code.
|
||||
--library UNISIM;
|
||||
--use UNISIM.VComponents.all;
|
||||
|
||||
entity CFG_INT is
|
||||
Port (
|
||||
CLK : in STD_LOGIC;--100mhz
|
||||
RSTn : in STD_LOGIC;
|
||||
TRIG : in STD_LOGIC;
|
||||
ADDR : in STD_LOGIC_VECTOR(7 downto 0);
|
||||
DATA : in STD_LOGIC_VECTOR(7 downto 0);
|
||||
SCLK : out STD_LOGIC;
|
||||
SDATA : out STD_LOGIC;
|
||||
SEN : out STD_LOGIC;
|
||||
BUSY : out STD_LOGIC
|
||||
);
|
||||
end CFG_INT;
|
||||
|
||||
architecture Behavioral of CFG_INT is
|
||||
|
||||
type state_type is (idle,start,wr_addr,wr_data,done);
|
||||
signal state : state_type;
|
||||
signal freq_div : std_logic_vector(3 downto 0);
|
||||
signal trig_r : std_logic;
|
||||
signal trig_rr : std_logic;
|
||||
signal trigger : std_logic;
|
||||
signal addr_i : std_logic_vector(7 downto 0);
|
||||
signal addr_r : std_logic_vector(7 downto 0);
|
||||
signal data_i : std_logic_vector(7 downto 0);
|
||||
signal data_r : std_logic_vector(7 downto 0);
|
||||
signal sen_i : std_logic;
|
||||
signal bit_count : std_logic_vector(3 downto 0);
|
||||
signal sclk_r : std_logic;
|
||||
signal sclk_f : std_logic;
|
||||
signal sclk_flag : std_logic;
|
||||
signal sclk_i : std_logic;
|
||||
signal sdata_i : std_logic;
|
||||
signal busy_i : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
process(clk,rstn)
|
||||
begin
|
||||
if rstn='0' then
|
||||
trig_r<='0';
|
||||
trig_rr<='0';
|
||||
elsif rising_edge(clk) then
|
||||
trig_r<=trig;
|
||||
trig_rr<=trig_r;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
trigger<='1' when trig_r='1' and trig_rr='0' else '0';
|
||||
|
||||
process(clk,rstn)
|
||||
begin
|
||||
if rstn='0' then addr_i<=(others=>'0');
|
||||
data_i<=(others=>'0');
|
||||
elsif rising_edge(clk) then
|
||||
if trigger='1' then
|
||||
addr_i<=addr;
|
||||
data_i<=data;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process(clk,rstn)
|
||||
begin
|
||||
if rstn='0' then state<=idle;
|
||||
sen_i<='1';
|
||||
busy_i<='0';
|
||||
sclk_flag<='0';
|
||||
elsif rising_edge(clk) then
|
||||
case state is
|
||||
when idle =>
|
||||
if trigger='1' then
|
||||
state<=start;
|
||||
busy_i<='1';
|
||||
else
|
||||
state<=idle;
|
||||
end if;
|
||||
when start =>
|
||||
state<=wr_addr;
|
||||
when wr_addr =>
|
||||
sclk_flag<='1';
|
||||
sen_i<='0';
|
||||
if bit_count=x"8" then
|
||||
state<=wr_data;
|
||||
else
|
||||
state<=wr_addr;
|
||||
end if;
|
||||
when wr_data =>
|
||||
if bit_count=x"8" then
|
||||
state<=done;
|
||||
else
|
||||
state<=wr_data;
|
||||
end if;
|
||||
when done =>
|
||||
if sclk_r='1' then state<=idle;
|
||||
sen_i<='1';
|
||||
sclk_flag<='0';
|
||||
busy_i<='0';
|
||||
else
|
||||
state<=done;
|
||||
end if;
|
||||
when others=> state<=idle;
|
||||
end case;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
sen<=sen_i;
|
||||
busy<=busy_i;
|
||||
|
||||
process(clk,rstn)
|
||||
begin
|
||||
if rstn='0' then
|
||||
freq_div<=(others=>'0');
|
||||
elsif rising_edge(clk) then
|
||||
if sclk_flag='1' then
|
||||
if freq_div=x"9" then
|
||||
freq_div<=(others=>'0');
|
||||
else
|
||||
freq_div<=freq_div+'1';
|
||||
end if;
|
||||
else
|
||||
freq_div<=(others=>'0');
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process(clk,rstn)
|
||||
begin
|
||||
if rstn='0' then
|
||||
sclk_r<='0';
|
||||
sclk_f<='0';
|
||||
elsif rising_edge(clk) then
|
||||
sclk_r<='0';
|
||||
sclk_f<='0';
|
||||
if sclk_flag='1' then
|
||||
if freq_div=x"0" then
|
||||
sclk_r<='1';
|
||||
elsif freq_div=x"5" then
|
||||
sclk_f<='1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process(clk,rstn)
|
||||
begin
|
||||
if rstn='0' then
|
||||
sclk_i<='1';
|
||||
elsif rising_edge(clk) then
|
||||
if sclk_flag='1' then
|
||||
if sclk_r='1' then
|
||||
sclk_i<='1';
|
||||
elsif sclk_f='1' then
|
||||
sclk_i<='0';
|
||||
else
|
||||
sclk_i<=sclk_i;
|
||||
end if;
|
||||
else
|
||||
sclk_i<='1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
sclk<=sclk_i;
|
||||
|
||||
process(clk,rstn)
|
||||
begin
|
||||
if rstn='0' then
|
||||
bit_count<=(others=>'0');
|
||||
elsif rising_edge(clk) then
|
||||
if bit_count=8 then
|
||||
bit_count<=(others=>'0');
|
||||
elsif sclk_f='1' then
|
||||
bit_count<=bit_count+1;
|
||||
else
|
||||
bit_count<=bit_count;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process(clk,rstn)
|
||||
begin
|
||||
if rstn='0' then
|
||||
addr_r<=(others=>'0');
|
||||
data_r<=(others=>'0');
|
||||
sdata_i<='0';
|
||||
elsif rising_edge(clk) then
|
||||
if state=start then
|
||||
addr_r<=addr_i;
|
||||
data_r<=data_i;
|
||||
elsif state=wr_addr then
|
||||
if sclk_r='1' then
|
||||
sdata_i<=addr_r(7);
|
||||
addr_r<=addr_r(6 downto 0) & '0';
|
||||
else
|
||||
sdata_i<=sdata_i;
|
||||
addr_r<=addr_r;
|
||||
end if;
|
||||
elsif state=wr_data then
|
||||
if sclk_r='1' then
|
||||
sdata_i<=data_r(7);
|
||||
data_r<=data_r(6 downto 0) & '0';
|
||||
else
|
||||
sdata_i<=sdata_i;
|
||||
data_r<=data_r;
|
||||
end if;
|
||||
elsif state=done then
|
||||
sdata_i<=sdata_i;
|
||||
else
|
||||
sdata_i<='0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
sdata<=sdata_i;
|
||||
end Behavioral;
|
37
lib/common/Driver/ADC_driver/ADS9226_driver/AD9226_driver.v
Normal file
37
lib/common/Driver/ADC_driver/ADS9226_driver/AD9226_driver.v
Normal file
@ -0,0 +1,37 @@
|
||||
module AD9226_driver #
|
||||
(
|
||||
parameter signed CH_offset = 27
|
||||
)
|
||||
(
|
||||
input clk_in,
|
||||
input rst_n,
|
||||
input [11:0] AD_data,
|
||||
output AD_clk,
|
||||
output [11:0] wave_CH
|
||||
);
|
||||
|
||||
reg signed [11:0] wave_CH_buf;
|
||||
always@(posedge clk_in or negedge rst_n) begin
|
||||
if(!rst_n)
|
||||
wave_CH_buf <= 12'd0;
|
||||
else begin
|
||||
wave_CH_buf[11] <= AD_data[0];
|
||||
wave_CH_buf[10] <= AD_data[1];
|
||||
wave_CH_buf[9] <= AD_data[2];
|
||||
wave_CH_buf[8] <= AD_data[3];
|
||||
wave_CH_buf[7] <= AD_data[4];
|
||||
wave_CH_buf[6] <= AD_data[5];
|
||||
wave_CH_buf[5] <= AD_data[6];
|
||||
wave_CH_buf[4] <= AD_data[7];
|
||||
wave_CH_buf[3] <= AD_data[8];
|
||||
wave_CH_buf[2] <= AD_data[9];
|
||||
wave_CH_buf[1] <= AD_data[10];
|
||||
wave_CH_buf[0] <= AD_data[11];
|
||||
end
|
||||
end
|
||||
|
||||
assign wave_CH = $signed(wave_CH_buf) + $signed(CH_offset);
|
||||
assign AD_clk = clk_in;
|
||||
|
||||
endmodule
|
||||
|
65
lib/common/Driver/DAC_driver/DAC3162_driver/DAC3162_driver.v
Normal file
65
lib/common/Driver/DAC_driver/DAC3162_driver/DAC3162_driver.v
Normal file
@ -0,0 +1,65 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module DAC3162_driver (
|
||||
input clk_in,
|
||||
input clk_div,
|
||||
|
||||
input [11:0] DA3162_CH1,
|
||||
input [11:0] DA3162_CH2,
|
||||
/*DAC*/
|
||||
output [11:0] dac_data_p,
|
||||
output [11:0] dac_data_n,
|
||||
output dac_clk_p,
|
||||
output dac_clk_n,
|
||||
output dac_sleep
|
||||
);
|
||||
|
||||
assign dac_sleep = 1'd1;
|
||||
|
||||
reg [11:0] dac_a_int = 0;
|
||||
reg [11:0] dac_b_int = 0;
|
||||
reg [11:0] dac_a_intt = 0;
|
||||
reg [11:0] dac_b_intt = 0;
|
||||
|
||||
reg [1:0] cnt_clk = 0;
|
||||
reg [3:0] power_on_rst_cnt = 4'h0;
|
||||
reg power_on_rst = 1;
|
||||
|
||||
always @ (posedge clk_in) begin
|
||||
dac_a_int<=DA3162_CH1 + 12'b100000000000;
|
||||
dac_b_int<=DA3162_CH2 + 12'b100000000000;
|
||||
dac_a_intt<=dac_a_int;
|
||||
dac_b_intt<=dac_b_int;
|
||||
end
|
||||
|
||||
always @ (posedge clk_div) begin
|
||||
if (power_on_rst_cnt == 4'hf) begin
|
||||
power_on_rst_cnt <= power_on_rst_cnt;
|
||||
power_on_rst <= 0;
|
||||
end
|
||||
else begin
|
||||
power_on_rst_cnt <= power_on_rst_cnt + 1;
|
||||
power_on_rst <= 1;
|
||||
end
|
||||
end
|
||||
|
||||
LVDS_DDR_clk DAC3162_clk_u (
|
||||
.data_out_from_device ( 4'b0101 ), // input [3:0] data_out_from_device
|
||||
.data_out_to_pins_p ( dac_clk_p ), // output [0:0] data_out_to_pins_p
|
||||
.data_out_to_pins_n ( dac_clk_n ), // output [0:0] data_out_to_pins_n
|
||||
.clk_in ( clk_in ), // input clk_in
|
||||
.clk_div_in ( clk_div ), // input clk_div_in
|
||||
.io_reset ( power_on_rst ) // input io_reset
|
||||
);
|
||||
|
||||
// input [47:0] data_out_from_device
|
||||
LVDS_DDR_data DAC3162_data_u (
|
||||
.clk_in ( clk_in ), // input clk_in
|
||||
.clk_div_in ( clk_div ), // input clk_div_in
|
||||
.data_out_from_device ({dac_a_int,dac_b_int,dac_a_intt,dac_b_intt} ),
|
||||
.data_out_to_pins_p ( dac_data_p ), // output [11:0] data_out_to_pins_p
|
||||
.data_out_to_pins_n ( dac_data_n ), // output [11:0] data_out_to_pins_n
|
||||
.io_reset ( power_on_rst ) // input io_reset
|
||||
);
|
||||
|
||||
endmodule
|
108
lib/common/Driver/DAC_driver/DAC3162_driver/LVDS_DDR_clk.v
Normal file
108
lib/common/Driver/DAC_driver/DAC3162_driver/LVDS_DDR_clk.v
Normal file
@ -0,0 +1,108 @@
|
||||
`timescale 1ps/1ps
|
||||
|
||||
(* CORE_GENERATION_INFO = "LVDS_DDR_clk,selectio_wiz_v5_1_12,{component_name=LVDS_DDR_clk,bus_dir=OUTPUTS,bus_sig_type=DIFF,bus_io_std=DIFF_HSTL_I_18,use_serialization=true,use_phase_detector=false,serialization_factor=4,enable_bitslip=false,enable_train=false,system_data_width=1,bus_in_delay=NONE,bus_out_delay=NONE,clk_sig_type=SINGLE,clk_io_std=LVCMOS18,clk_buf=BUFIO2,active_edge=RISING,clk_delay=NONE,selio_bus_in_delay=NONE,selio_bus_out_delay=NONE,selio_clk_buf=MMCM,selio_active_edge=DDR,selio_ddr_alignment=SAME_EDGE_PIPELINED,selio_oddr_alignment=SAME_EDGE,ddr_alignment=C0,selio_interface_type=NETWORKING,interface_type=NETWORKING,selio_bus_in_tap=0,selio_bus_out_tap=0,selio_clk_io_std=DIFF_HSTL_I_18,selio_clk_sig_type=DIFF}" *)
|
||||
|
||||
module LVDS_DDR_clk
|
||||
// width of the data for the system
|
||||
#(parameter SYS_W = 1,
|
||||
// width of the data for the device
|
||||
parameter DEV_W = 4)
|
||||
(
|
||||
// From the device out to the system
|
||||
input [DEV_W-1:0] data_out_from_device,
|
||||
output [SYS_W-1:0] data_out_to_pins_p,
|
||||
output [SYS_W-1:0] data_out_to_pins_n,
|
||||
input clk_in, // Fast clock input from PLL/MMCM
|
||||
input clk_div_in, // Slow clock input from PLL/MMCM
|
||||
input io_reset);
|
||||
|
||||
localparam num_serial_bits = DEV_W/SYS_W;
|
||||
wire clock_enable = 1'b1;
|
||||
// Signal declarations
|
||||
////------------------------------
|
||||
// Before the buffer
|
||||
wire [SYS_W-1:0] data_out_to_pins_int;
|
||||
// Between the delay and serdes
|
||||
wire [SYS_W-1:0] data_out_to_pins_predelay;
|
||||
// Array to use intermediately from the serdes to the internal
|
||||
// devices. bus "0" is the leftmost bus
|
||||
wire [SYS_W-1:0] oserdes_d[0:13]; // fills in starting with 13
|
||||
// Create the clock logic
|
||||
|
||||
|
||||
// We have multiple bits- step over every bit, instantiating the required elements
|
||||
genvar pin_count;
|
||||
genvar slice_count;
|
||||
generate for (pin_count = 0; pin_count < SYS_W; pin_count = pin_count + 1) begin: pins
|
||||
// Instantiate the buffers
|
||||
////------------------------------
|
||||
// Instantiate a buffer for every bit of the data bus
|
||||
OBUFDS
|
||||
#(.IOSTANDARD ("DIFF_HSTL_I_18"))
|
||||
obufds_inst
|
||||
(.O (data_out_to_pins_p [pin_count]),
|
||||
.OB (data_out_to_pins_n [pin_count]),
|
||||
.I (data_out_to_pins_int[pin_count]));
|
||||
|
||||
// Pass through the delay
|
||||
////-------------------------------
|
||||
assign data_out_to_pins_int[pin_count] = data_out_to_pins_predelay[pin_count];
|
||||
|
||||
// Instantiate the serdes primitive
|
||||
////------------------------------
|
||||
|
||||
// declare the oserdes
|
||||
OSERDESE2
|
||||
# (
|
||||
.DATA_RATE_OQ ("DDR"),
|
||||
.DATA_RATE_TQ ("DDR"),
|
||||
.DATA_WIDTH (4),
|
||||
.TRISTATE_WIDTH (4),
|
||||
.SERDES_MODE ("MASTER"))
|
||||
oserdese2_master (
|
||||
.D1 (oserdes_d[13][pin_count]),
|
||||
.D2 (oserdes_d[12][pin_count]),
|
||||
.D3 (oserdes_d[11][pin_count]),
|
||||
.D4 (oserdes_d[10][pin_count]),
|
||||
.D5 (oserdes_d[9][pin_count]),
|
||||
.D6 (oserdes_d[8][pin_count]),
|
||||
.D7 (oserdes_d[7][pin_count]),
|
||||
.D8 (oserdes_d[6][pin_count]),
|
||||
.T1 (1'b0),
|
||||
.T2 (1'b0),
|
||||
.T3 (1'b0),
|
||||
.T4 (1'b0),
|
||||
.SHIFTIN1 (1'b0),
|
||||
.SHIFTIN2 (1'b0),
|
||||
.SHIFTOUT1 (),
|
||||
.SHIFTOUT2 (),
|
||||
.OCE (clock_enable),
|
||||
.CLK (clk_in),
|
||||
.CLKDIV (clk_div_in),
|
||||
.OQ (data_out_to_pins_predelay[pin_count]),
|
||||
.TQ (),
|
||||
.OFB (),
|
||||
.TFB (),
|
||||
.TBYTEIN (1'b0),
|
||||
.TBYTEOUT (),
|
||||
.TCE (1'b0),
|
||||
.RST (io_reset));
|
||||
|
||||
// Concatenate the serdes outputs together. Keep the timesliced
|
||||
// bits together, and placing the earliest bits on the right
|
||||
// ie, if data comes in 0, 1, 2, 3, 4, 5, 6, 7, ...
|
||||
// the output will be 3210, 7654, ...
|
||||
////---------------------------------------------------------
|
||||
for (slice_count = 0; slice_count < num_serial_bits; slice_count = slice_count + 1) begin: out_slices
|
||||
// This places the first data in time on the right
|
||||
assign oserdes_d[14-slice_count-1] =
|
||||
data_out_from_device[slice_count];
|
||||
// To place the first data in time on the left, use the
|
||||
// following code, instead
|
||||
// assign oserdes_d[slice_count] =
|
||||
// data_out_from_device[slice_count];
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
106
lib/common/Driver/DAC_driver/DAC3162_driver/LVDS_DDR_data.v
Normal file
106
lib/common/Driver/DAC_driver/DAC3162_driver/LVDS_DDR_data.v
Normal file
@ -0,0 +1,106 @@
|
||||
`timescale 1ps/1ps
|
||||
|
||||
(* CORE_GENERATION_INFO = "LVDS_DDR_data,selectio_wiz_v5_1_12,{component_name=LVDS_DDR_data,bus_dir=OUTPUTS,bus_sig_type=DIFF,bus_io_std=DIFF_HSTL_I_18,use_serialization=true,use_phase_detector=false,serialization_factor=4,enable_bitslip=false,enable_train=false,system_data_width=12,bus_in_delay=NONE,bus_out_delay=NONE,clk_sig_type=SINGLE,clk_io_std=LVCMOS18,clk_buf=BUFIO2,active_edge=RISING,clk_delay=NONE,selio_bus_in_delay=NONE,selio_bus_out_delay=NONE,selio_clk_buf=MMCM,selio_active_edge=DDR,selio_ddr_alignment=SAME_EDGE_PIPELINED,selio_oddr_alignment=SAME_EDGE,ddr_alignment=C0,selio_interface_type=NETWORKING,interface_type=NETWORKING,selio_bus_in_tap=0,selio_bus_out_tap=0,selio_clk_io_std=DIFF_HSTL_I_18,selio_clk_sig_type=DIFF}" *)
|
||||
|
||||
module LVDS_DDR_data
|
||||
// width of the data for the system
|
||||
#(parameter SYS_W = 12,
|
||||
// width of the data for the device
|
||||
parameter DEV_W = 48)
|
||||
(
|
||||
// From the device out to the system
|
||||
input [DEV_W-1:0] data_out_from_device,
|
||||
output [SYS_W-1:0] data_out_to_pins_p,
|
||||
output [SYS_W-1:0] data_out_to_pins_n,
|
||||
input clk_in, // Fast clock input from PLL/MMCM
|
||||
input clk_div_in, // Slow clock input from PLL/MMCM
|
||||
input io_reset);
|
||||
localparam num_serial_bits = DEV_W/SYS_W;
|
||||
wire clock_enable = 1'b1;
|
||||
// Signal declarations
|
||||
////------------------------------
|
||||
// Before the buffer
|
||||
wire [SYS_W-1:0] data_out_to_pins_int;
|
||||
// Between the delay and serdes
|
||||
wire [SYS_W-1:0] data_out_to_pins_predelay;
|
||||
// Array to use intermediately from the serdes to the internal
|
||||
// devices. bus "0" is the leftmost bus
|
||||
wire [SYS_W-1:0] oserdes_d[0:13]; // fills in starting with 13
|
||||
// Create the clock logic
|
||||
|
||||
|
||||
// We have multiple bits- step over every bit, instantiating the required elements
|
||||
genvar pin_count;
|
||||
genvar slice_count;
|
||||
generate for (pin_count = 0; pin_count < SYS_W; pin_count = pin_count + 1) begin: pins
|
||||
// Instantiate the buffers
|
||||
////------------------------------
|
||||
// Instantiate a buffer for every bit of the data bus
|
||||
OBUFDS
|
||||
#(.IOSTANDARD ("DIFF_HSTL_I_18"))
|
||||
obufds_inst
|
||||
(.O (data_out_to_pins_p [pin_count]),
|
||||
.OB (data_out_to_pins_n [pin_count]),
|
||||
.I (data_out_to_pins_int[pin_count]));
|
||||
|
||||
// Pass through the delay
|
||||
////-------------------------------
|
||||
assign data_out_to_pins_int[pin_count] = data_out_to_pins_predelay[pin_count];
|
||||
|
||||
// Instantiate the serdes primitive
|
||||
////------------------------------
|
||||
|
||||
// declare the oserdes
|
||||
OSERDESE2 # (
|
||||
.DATA_RATE_OQ ("DDR"),
|
||||
.DATA_RATE_TQ ("DDR"),
|
||||
.DATA_WIDTH (4),
|
||||
.TRISTATE_WIDTH (4),
|
||||
.SERDES_MODE ("MASTER"))
|
||||
oserdese2_master (
|
||||
.D1 (oserdes_d[13][pin_count]),
|
||||
.D2 (oserdes_d[12][pin_count]),
|
||||
.D3 (oserdes_d[11][pin_count]),
|
||||
.D4 (oserdes_d[10][pin_count]),
|
||||
.D5 (oserdes_d[9][pin_count]),
|
||||
.D6 (oserdes_d[8][pin_count]),
|
||||
.D7 (oserdes_d[7][pin_count]),
|
||||
.D8 (oserdes_d[6][pin_count]),
|
||||
.T1 (1'b0),
|
||||
.T2 (1'b0),
|
||||
.T3 (1'b0),
|
||||
.T4 (1'b0),
|
||||
.SHIFTIN1 (1'b0),
|
||||
.SHIFTIN2 (1'b0),
|
||||
.SHIFTOUT1 (),
|
||||
.SHIFTOUT2 (),
|
||||
.OCE (clock_enable),
|
||||
.CLK (clk_in),
|
||||
.CLKDIV (clk_div_in),
|
||||
.OQ (data_out_to_pins_predelay[pin_count]),
|
||||
.TQ (),
|
||||
.OFB (),
|
||||
.TFB (),
|
||||
.TBYTEIN (1'b0),
|
||||
.TBYTEOUT (),
|
||||
.TCE (1'b0),
|
||||
.RST (io_reset));
|
||||
|
||||
// Concatenate the serdes outputs together. Keep the timesliced
|
||||
// bits together, and placing the earliest bits on the right
|
||||
// ie, if data comes in 0, 1, 2, 3, 4, 5, 6, 7, ...
|
||||
// the output will be 3210, 7654, ...
|
||||
////---------------------------------------------------------
|
||||
for (slice_count = 0; slice_count < num_serial_bits; slice_count = slice_count + 1) begin: out_slices
|
||||
// This places the first data in time on the right
|
||||
assign oserdes_d[14-slice_count-1] =
|
||||
data_out_from_device[slice_count*SYS_W+:SYS_W];
|
||||
// To place the first data in time on the left, use the
|
||||
// following code, instead
|
||||
// assign oserdes_d[slice_count] =
|
||||
// data_out_from_device[slice_count*SYS_W+:SYS_W];
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
62
lib/common/Driver/DAC_driver/DAC9767_driver/DA9767.v
Normal file
62
lib/common/Driver/DAC_driver/DAC9767_driver/DA9767.v
Normal file
@ -0,0 +1,62 @@
|
||||
//============================================================================================
|
||||
/*
|
||||
* #Author : sterben(Duan)
|
||||
* #LastAuthor : sterben(Duan)
|
||||
* #Date : 2019-09-27 00:00:34
|
||||
* #lastTime : 2020-01-22 23:54:59
|
||||
* #FilePath : src\Driver\DAC_driver\DAC9767_driver\DA9767.v
|
||||
* #Description : port:
|
||||
*/
|
||||
//============================================================================================
|
||||
|
||||
module DA9767 #
|
||||
(
|
||||
parameter INPUT_WIDTH = 14,
|
||||
parameter INPUT_STYLE = "signed",
|
||||
parameter ALIGNED_STYLE = "LSB"
|
||||
)
|
||||
(
|
||||
input clk_in,
|
||||
input [INPUT_WIDTH - 1 : 0] DA_data,
|
||||
output DA_clk,
|
||||
output DA_wrt,
|
||||
output [13:0] DA_out
|
||||
);
|
||||
|
||||
generate if(INPUT_STYLE == "signed") begin : OUTPUT
|
||||
if (INPUT_WIDTH < 14) begin
|
||||
localparam DATA_WIDTH = 14 - INPUT_WIDTH;
|
||||
if (ALIGNED_STYLE == "LSB") begin
|
||||
assign DA_out = $signed({{DATA_WIDTH{DA_data[INPUT_WIDTH-1]}},DA_data})
|
||||
+ $signed(14'd8192);
|
||||
end
|
||||
else if(ALIGNED_STYLE == "MSB") begin
|
||||
reg [DATA_WIDTH - 1 : 0 ] data_buf = 0;
|
||||
assign DA_out = $signed({DA_data,data_buf}) + $signed(14'd8192);
|
||||
end
|
||||
end
|
||||
else begin
|
||||
assign DA_out = $signed(DA_data[INPUT_WIDTH - 1 : INPUT_WIDTH - 14]) + $signed(14'd8192);
|
||||
end
|
||||
end
|
||||
else if(INPUT_STYLE == "unsigned") begin
|
||||
if (INPUT_WIDTH < 14) begin
|
||||
localparam DATA_WIDTH = 14 - INPUT_WIDTH;
|
||||
if (ALIGNED_STYLE == "LSB") begin
|
||||
assign DA_out = {{DATA_WIDTH{DA_data[INPUT_WIDTH-1]}},DA_data};
|
||||
end
|
||||
else if(ALIGNED_STYLE == "MSB") begin
|
||||
reg [DATA_WIDTH - 1 : 0 ] data_buf = 0;
|
||||
assign DA_out = {DA_data,data_buf};
|
||||
end
|
||||
end
|
||||
else begin
|
||||
assign DA_out = DA_data[INPUT_WIDTH - 1 : INPUT_WIDTH - 14];
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign DA_clk = clk_in;
|
||||
assign DA_wrt = clk_in;
|
||||
|
||||
endmodule
|
35
lib/common/Driver/DAC_driver/DAC_PWM/DAC_PWM.v
Normal file
35
lib/common/Driver/DAC_driver/DAC_PWM/DAC_PWM.v
Normal file
@ -0,0 +1,35 @@
|
||||
module DAC_PWM #
|
||||
(
|
||||
parameter MAIN_FRE = 500,
|
||||
parameter PWM_FRE = 1000,
|
||||
parameter PHASE_WIDTH = 32
|
||||
)
|
||||
(
|
||||
input clk_in,
|
||||
input RST,
|
||||
output DAC_PWM,
|
||||
input [PHASE_WIDTH-1:0] data_in
|
||||
);
|
||||
|
||||
localparam [PHASE_WIDTH-1:0] DC_ADD = (2**(PHASE_WIDTH-1)) - 1;
|
||||
localparam [PHASE_WIDTH-1:0] FRE_WORD = (2**PHASE_WIDTH)*PWM_FRE/(MAIN_FRE*1000);
|
||||
|
||||
reg [PHASE_WIDTH-1:0] addr_r = 0;
|
||||
always @(posedge clk_in) begin
|
||||
if (RST)
|
||||
addr_r <= 0;
|
||||
else
|
||||
addr_r <= addr_r + FRE_WORD;
|
||||
end
|
||||
|
||||
reg [PHASE_WIDTH-1:0] duty_r = 0;
|
||||
always @(posedge clk_in) begin
|
||||
if (RST)
|
||||
duty_r <= 32'd0;
|
||||
else
|
||||
duty_r <= $signed(data_in) + DC_ADD;
|
||||
end
|
||||
|
||||
assign DAC_PWM = (addr_r <= duty_r) ? 1'b1 : 1'b0;
|
||||
|
||||
endmodule
|
124
lib/common/Driver/DDS_driver/ADF_driver.v
Normal file
124
lib/common/Driver/DDS_driver/ADF_driver.v
Normal file
@ -0,0 +1,124 @@
|
||||
module ADF_driver
|
||||
(
|
||||
input clk, //系统时钟
|
||||
input wrsig, //发送命令,上升沿有效
|
||||
input [8:0] datain, //需要发送的数据
|
||||
|
||||
output reg tx_idle, //线路状态指示,高为线路忙,低为线路空闲
|
||||
output reg tx, //发送数据信号
|
||||
output reg clkout,
|
||||
output reg LE
|
||||
);
|
||||
|
||||
reg tx_send=0;
|
||||
reg tx_wrsigbuf=0, tx_wrsigrise=0;
|
||||
reg[7:0] tx_cnt=0; //计数器
|
||||
//检测发送命令是否有效
|
||||
reg [15:0] clk_cnt=0;
|
||||
reg [31:0]dataint=0;
|
||||
reg [10:0]cnt_init=0;
|
||||
reg init=0;
|
||||
reg [4:0] cnt_wei=0;
|
||||
reg [15:0]int_v=0;
|
||||
reg [11:0]frac_v=0;
|
||||
|
||||
|
||||
parameter [31:0]R5=32'b00000000_00011_0000000000000000_101;
|
||||
parameter [31:0]R4=32'b00000000_1101_01100100_000000_111100;
|
||||
parameter [31:0]R3=32'b00000000_100000010_111111111111_011;
|
||||
parameter [31:0]R2=32'b00000000_0000000001_00000_001000010;
|
||||
parameter [31:0]R1=32'b00000_000000000000_000001100100_001;
|
||||
reg [31:0]R0=32'b0_00000000_10100000_000000000000_000;
|
||||
|
||||
always @(posedge clk) begin//分频进程 CLK/(1000000)
|
||||
if(clk_cnt == 16'd24) begin
|
||||
clkout <= 1'b1;
|
||||
clk_cnt <= clk_cnt + 16'd1;
|
||||
end
|
||||
else if(clk_cnt == 16'd49) begin
|
||||
clkout <= 1'b0;
|
||||
clk_cnt <= 16'd0;
|
||||
end
|
||||
else begin
|
||||
clk_cnt <= clk_cnt + 16'd1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
always @(negedge clkout) begin
|
||||
int_v<=datain/7'd100;
|
||||
frac_v<=datain%7'd100;
|
||||
if(!init) begin
|
||||
cnt_init<=cnt_init+1'b1;
|
||||
case(cnt_init)
|
||||
11'd5: begin R0<=32'b0_00000000_10100000_000000000000_000; end
|
||||
11'd1010: begin tx_send <= 1'b1; dataint<=R5; end
|
||||
11'd1046: begin tx_send <= 1'b0; end
|
||||
11'd1110: begin tx_send <= 1'b1; dataint<=R4; end
|
||||
11'd1146: begin tx_send <= 1'b0; end
|
||||
11'd1210: begin tx_send <= 1'b1; dataint<=R3; end
|
||||
11'd1246: begin tx_send <= 1'b0; end
|
||||
11'd1310: begin tx_send <= 1'b1; dataint<=R2; end
|
||||
11'd1346: begin tx_send <= 1'b0; end
|
||||
11'd1410: begin tx_send <= 1'b1; dataint<=R1; end
|
||||
11'd1446: begin tx_send <= 1'b0; end
|
||||
11'd1510: begin tx_send <= 1'b1; dataint<=R0; end
|
||||
11'd1546: begin tx_send <= 1'b0; end
|
||||
11'd1610: begin tx_send <= 1'b1; dataint<=R3; end
|
||||
11'd1646: begin tx_send <= 1'b0; end
|
||||
11'd1650: begin init<=1'b1; end
|
||||
endcase
|
||||
end
|
||||
else begin
|
||||
tx_wrsigbuf <= wrsig;
|
||||
tx_wrsigrise <= (~tx_wrsigbuf) & wrsig;
|
||||
if (tx_wrsigrise && (~tx_idle)) begin
|
||||
tx_send <= 1'b1;
|
||||
R0[30:15]<=int_v;
|
||||
R0[14:3]<=frac_v;
|
||||
end
|
||||
else if(tx_cnt == 8'd36) begin
|
||||
tx_send <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(negedge clkout) begin
|
||||
if(tx_send == 1'b1) begin
|
||||
case(tx_cnt) //产生起始位
|
||||
8'd1: begin
|
||||
LE<=1'b0;
|
||||
tx <= dataint[31];
|
||||
cnt_wei<=5'd31;
|
||||
tx_idle <= 1'b1;
|
||||
tx_cnt <= tx_cnt + 8'd1;
|
||||
end
|
||||
8'd2,8'd3,8'd4,8'd5,8'd6,8'd7,8'd8,8'd9,8'd10,8'd11,8'd12,8'd13,8'd14,8'd15
|
||||
,8'd16,8'd17,8'd18,8'd19,8'd20,8'd21,8'd22,8'd23,8'd24,8'd25,8'd26,8'd27,
|
||||
8'd28,8'd29,8'd30,8'd31,8'd32,8'd33: begin
|
||||
tx <= dataint[cnt_wei]; //发送数据0 位
|
||||
cnt_wei<=cnt_wei-1'b1;
|
||||
tx_idle <= 1'b1;
|
||||
tx_cnt <= tx_cnt + 8'd1;
|
||||
end
|
||||
8'd34: begin
|
||||
tx <= 1'b1;
|
||||
LE<=1'b1;
|
||||
tx_idle <= 1'b0;
|
||||
tx_cnt <= tx_cnt + 8'd1;
|
||||
end
|
||||
default: begin
|
||||
tx_cnt <= tx_cnt + 8'd1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
else begin
|
||||
tx <= 1'b1;
|
||||
LE<=1'b1;
|
||||
cnt_wei<=5'd31;
|
||||
tx_cnt <= 8'd0;
|
||||
tx_idle <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
11
lib/common/Driver/HDMI_driver/HDMI_in.v
Normal file
11
lib/common/Driver/HDMI_driver/HDMI_in.v
Normal file
@ -0,0 +1,11 @@
|
||||
module HDMI_in #(
|
||||
parameter INPUT_WIDTH = 12,
|
||||
parameter OUTPUT_WIDTH = 12
|
||||
) (
|
||||
input clk_in,
|
||||
input rst_n,
|
||||
input [INPUT_WIDTH - 1 : 0] data_in,
|
||||
output [OUTPUT_WIDTH - 1 : 0] data_out
|
||||
);
|
||||
|
||||
endmodule //HDMI_in
|
11
lib/common/Driver/HDMI_driver/HDMI_out.v
Normal file
11
lib/common/Driver/HDMI_driver/HDMI_out.v
Normal file
@ -0,0 +1,11 @@
|
||||
module HDMI_out #(
|
||||
parameter INPUT_WIDTH = 12,
|
||||
parameter OUTPUT_WIDTH = 12
|
||||
) (
|
||||
input clk_in,
|
||||
input rst_n,
|
||||
input [INPUT_WIDTH - 1 : 0] data_in,
|
||||
output [OUTPUT_WIDTH - 1 : 0] data_out
|
||||
);
|
||||
|
||||
endmodule //HDMI_out
|
80
lib/common/Driver/KEY_driver/key_driver.v
Normal file
80
lib/common/Driver/KEY_driver/key_driver.v
Normal file
@ -0,0 +1,80 @@
|
||||
`timescale 1 ns / 100 ps
|
||||
module key_driver
|
||||
(
|
||||
input clk,
|
||||
input rst,
|
||||
input button_in,
|
||||
output reg button_posedge,
|
||||
output reg button_negedge,
|
||||
output reg button_out
|
||||
);
|
||||
//// ---------------- internal constants --------------
|
||||
parameter N = 32 ; // debounce timer bitwidth
|
||||
parameter FREQ = 60; //model clock :Mhz
|
||||
parameter MAX_TIME = 20; //ms
|
||||
localparam TIMER_MAX_VAL = MAX_TIME * 1000 * FREQ;
|
||||
////---------------- internal variables ---------------
|
||||
reg [N-1 : 0] q_reg; // timing regs
|
||||
reg [N-1 : 0] q_next;
|
||||
reg DFF1, DFF2; // input flip-flops
|
||||
wire q_add; // control flags
|
||||
wire q_reset;
|
||||
reg button_out_d0;
|
||||
//// ------------------------------------------------------
|
||||
|
||||
////contenious assignment for counter control
|
||||
assign q_reset = (DFF1 ^ DFF2); // xor input flip flops to look for level chage to reset counter
|
||||
assign q_add = ~(q_reg == TIMER_MAX_VAL); // add to counter when q_reg msb is equal to 0
|
||||
|
||||
//// combo counter to manage q_next
|
||||
always @ ( q_reset, q_add, q_reg) begin
|
||||
case( {q_reset , q_add})
|
||||
2'b00 :
|
||||
q_next <= q_reg;
|
||||
2'b01 :
|
||||
q_next <= q_reg + 1;
|
||||
default :
|
||||
q_next <= { N {1'b0} };
|
||||
endcase
|
||||
end
|
||||
|
||||
//// Flip flop inputs and q_reg update
|
||||
always @ ( posedge clk or posedge rst) begin
|
||||
if(rst == 1'b1) begin
|
||||
DFF1 <= 1'b0;
|
||||
DFF2 <= 1'b0;
|
||||
q_reg <= { N {1'b0} };
|
||||
end
|
||||
else begin
|
||||
DFF1 <= button_in;
|
||||
DFF2 <= DFF1;
|
||||
q_reg <= q_next;
|
||||
end
|
||||
end
|
||||
|
||||
//// counter control
|
||||
always @ ( posedge clk or posedge rst) begin
|
||||
if(rst == 1'b1)
|
||||
button_out <= 1'b1;
|
||||
else if(q_reg == TIMER_MAX_VAL)
|
||||
button_out <= DFF2;
|
||||
else
|
||||
button_out <= button_out;
|
||||
end
|
||||
|
||||
always @ ( posedge clk or posedge rst) begin
|
||||
if(rst == 1'b1) begin
|
||||
button_out_d0 <= 1'b1;
|
||||
button_posedge <= 1'b0;
|
||||
button_negedge <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
button_out_d0 <= button_out;
|
||||
button_posedge <= ~button_out_d0 & button_out;
|
||||
button_negedge <= button_out_d0 & ~button_out;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
112
lib/common/Driver/Motor_driver/Motor_driver.v
Normal file
112
lib/common/Driver/Motor_driver/Motor_driver.v
Normal file
@ -0,0 +1,112 @@
|
||||
/********************************************
|
||||
wire Motor_Control;
|
||||
Motor_driver Motor_driver_u(
|
||||
.clk_in(clk_50m),
|
||||
.rst_n(1'd1),
|
||||
.Trig(Trig),
|
||||
.Meter(16'd4),
|
||||
|
||||
.Motor_Control(Motor_Control)
|
||||
);
|
||||
********************************************/
|
||||
module Motor_driver (
|
||||
input clk_in,
|
||||
input rst_n,
|
||||
input Trig,
|
||||
input [15:0] Meter,
|
||||
|
||||
output reg Motor_Control
|
||||
);
|
||||
|
||||
parameter MAIN_FRE = 50000000;
|
||||
parameter MOTOR_FRE = 1000;
|
||||
parameter SET_TIME = MAIN_FRE/MOTOR_FRE/2;
|
||||
|
||||
/***************************************************/
|
||||
//define the data lock
|
||||
reg Trig_SIG = 0;
|
||||
reg Trig_SIG_buf = 0;
|
||||
wire Trig_SIG_pose = Trig_SIG & ~Trig_SIG_buf;
|
||||
wire Trig_SIG_nege = ~Trig_SIG & Trig_SIG_buf;
|
||||
|
||||
always@(posedge clk_in) begin
|
||||
Trig_SIG <= Trig;
|
||||
Trig_SIG_buf <= Trig_SIG;
|
||||
end
|
||||
/***************************************************/
|
||||
|
||||
/***************************************************/
|
||||
//define the time counter
|
||||
reg [15:0] cnt0 = 0;
|
||||
reg Motor_Control_r = 0;
|
||||
|
||||
always@(posedge clk_in) begin
|
||||
if (cnt0 == SET_TIME) begin
|
||||
cnt0 <= 15'd0;
|
||||
Motor_Control_r <= ~Motor_Control_r;
|
||||
end
|
||||
else
|
||||
cnt0 <= cnt0 + 1'd1;
|
||||
end
|
||||
/***************************************************/
|
||||
|
||||
/***************************************************/
|
||||
//define the data lock
|
||||
reg motor_sig = 0;
|
||||
reg motor_sig_buf = 0;
|
||||
wire motor_sig_pose = motor_sig & ~motor_sig_buf;
|
||||
wire motor_sig_nege = ~motor_sig & motor_sig_buf;
|
||||
always@(posedge clk_in) begin
|
||||
motor_sig <= Motor_Control_r;
|
||||
motor_sig_buf <= motor_sig;
|
||||
end
|
||||
/***************************************************/
|
||||
|
||||
/***************************************************/
|
||||
//define the time counter
|
||||
reg [15:0] cnt1 = 0;
|
||||
reg CNT_CE = 0;
|
||||
always@(posedge clk_in) begin
|
||||
if (Trig_SIG_pose) begin
|
||||
CNT_CE <= 1'd1;
|
||||
end
|
||||
else if(cnt1 == Meter) begin
|
||||
if (motor_sig_nege) begin
|
||||
CNT_CE <= 1'd0;
|
||||
end
|
||||
else begin
|
||||
CNT_CE <= CNT_CE;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
CNT_CE <= CNT_CE;
|
||||
end
|
||||
end
|
||||
/***************************************************/
|
||||
reg MOTOR_CE = 0;
|
||||
always @(posedge clk_in) begin
|
||||
if (CNT_CE) begin
|
||||
if (motor_sig_pose) begin
|
||||
cnt1 <= cnt1 + 1'd1; //cnt1 counter = cnt1 counter + 1
|
||||
MOTOR_CE <= 1'd1;
|
||||
end
|
||||
else begin
|
||||
MOTOR_CE <= MOTOR_CE;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
cnt1 <= 16'd0;
|
||||
MOTOR_CE <= 1'd0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
case (MOTOR_CE)
|
||||
1'b0 : begin Motor_Control <= 1'b0; end
|
||||
1'b1 : begin Motor_Control <= Motor_Control_r; end
|
||||
default : begin Motor_Control <= 1'b0; end
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
571
lib/common/Driver/SDRAM_driver/core/sdrc_bank_ctl.v
Normal file
571
lib/common/Driver/SDRAM_driver/core/sdrc_bank_ctl.v
Normal file
@ -0,0 +1,571 @@
|
||||
/*********************************************************************
|
||||
|
||||
SDRAM Controller Bank Controller
|
||||
|
||||
This file is part of the sdram controller project
|
||||
http://www.opencores.org/cores/sdr_ctrl/
|
||||
|
||||
Description:
|
||||
This module takes requests from sdrc_req_gen, checks for page hit/miss and
|
||||
issues precharge/activate commands and then passes the request to sdrc_xfr_ctl.
|
||||
|
||||
To Do:
|
||||
nothing
|
||||
|
||||
Author(s):
|
||||
- Dinesh Annayya, dinesha@opencores.org
|
||||
Version : 1.0 - 8th Jan 2012
|
||||
|
||||
|
||||
|
||||
Copyright (C) 2000 Authors and OPENCORES.ORG
|
||||
|
||||
This source file may be used and distributed without
|
||||
restriction provided that this copyright statement is not
|
||||
removed from the file and that any derivative work contains
|
||||
the original copyright notice and the associated disclaimer.
|
||||
|
||||
This source file is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU Lesser General
|
||||
Public License as published by the Free Software Foundation;
|
||||
either version 2.1 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
This source is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the GNU Lesser General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this source; if not, download it
|
||||
from http://www.opencores.org/lgpl.shtml
|
||||
|
||||
*******************************************************************/
|
||||
|
||||
|
||||
`include "sdrc_define.v"
|
||||
|
||||
module sdrc_bank_ctl (clk,
|
||||
reset_n,
|
||||
a2b_req_depth, // Number of requests we can buffer
|
||||
|
||||
/* Req from req_gen */
|
||||
r2b_req, // request
|
||||
r2b_req_id, // ID
|
||||
r2b_start, // First chunk of burst
|
||||
r2b_last, // Last chunk of burst
|
||||
r2b_wrap,
|
||||
r2b_ba, // bank address
|
||||
r2b_raddr, // row address
|
||||
r2b_caddr, // col address
|
||||
r2b_len, // length
|
||||
r2b_write, // write request
|
||||
b2r_arb_ok, // OK to arbitrate for next xfr
|
||||
b2r_ack,
|
||||
|
||||
/* Transfer request to xfr_ctl */
|
||||
b2x_idle, // All banks are idle
|
||||
b2x_req, // Request to xfr_ctl
|
||||
b2x_start, // first chunk of transfer
|
||||
b2x_last, // last chunk of transfer
|
||||
b2x_wrap,
|
||||
b2x_id, // Transfer ID
|
||||
b2x_ba, // bank address
|
||||
b2x_addr, // row/col address
|
||||
b2x_len, // transfer length
|
||||
b2x_cmd, // transfer command
|
||||
x2b_ack, // command accepted
|
||||
|
||||
/* Status to/from xfr_ctl */
|
||||
b2x_tras_ok, // TRAS OK for all banks
|
||||
x2b_refresh, // We did a refresh
|
||||
x2b_pre_ok, // OK to do a precharge (per bank)
|
||||
x2b_act_ok, // OK to do an activate
|
||||
x2b_rdok, // OK to do a read
|
||||
x2b_wrok, // OK to do a write
|
||||
|
||||
/* xfr msb address */
|
||||
xfr_bank_sel,
|
||||
sdr_req_norm_dma_last,
|
||||
|
||||
/* SDRAM Timing */
|
||||
tras_delay, // Active to precharge delay
|
||||
trp_delay, // Precharge to active delay
|
||||
trcd_delay); // Active to R/W delay
|
||||
|
||||
parameter SDR_DW = 16; // SDR Data Width
|
||||
parameter SDR_BW = 2; // SDR Byte Width
|
||||
input clk, reset_n;
|
||||
|
||||
input [1:0] a2b_req_depth;
|
||||
|
||||
/* Req from bank_ctl */
|
||||
input r2b_req, r2b_start, r2b_last,
|
||||
r2b_write, r2b_wrap;
|
||||
input [`SDR_REQ_ID_W-1:0] r2b_req_id;
|
||||
input [1:0] r2b_ba;
|
||||
input [12:0] r2b_raddr;
|
||||
input [12:0] r2b_caddr;
|
||||
input [`REQ_BW-1:0] r2b_len;
|
||||
output b2r_arb_ok, b2r_ack;
|
||||
input sdr_req_norm_dma_last;
|
||||
|
||||
/* Req to xfr_ctl */
|
||||
output b2x_idle, b2x_req, b2x_start, b2x_last,
|
||||
b2x_tras_ok, b2x_wrap;
|
||||
output [`SDR_REQ_ID_W-1:0] b2x_id;
|
||||
output [1:0] b2x_ba;
|
||||
output [12:0] b2x_addr;
|
||||
output [`REQ_BW-1:0] b2x_len;
|
||||
output [1:0] b2x_cmd;
|
||||
input x2b_ack;
|
||||
|
||||
/* Status from xfr_ctl */
|
||||
input [3:0] x2b_pre_ok;
|
||||
input x2b_refresh, x2b_act_ok, x2b_rdok,
|
||||
x2b_wrok;
|
||||
|
||||
input [3:0] tras_delay, trp_delay, trcd_delay;
|
||||
|
||||
input [1:0] xfr_bank_sel;
|
||||
|
||||
/****************************************************************************/
|
||||
// Internal Nets
|
||||
|
||||
wire [3:0] r2i_req, i2r_ack, i2x_req,
|
||||
i2x_start, i2x_last, i2x_wrap, tras_ok;
|
||||
wire [12:0] i2x_addr0, i2x_addr1, i2x_addr2, i2x_addr3;
|
||||
wire [`REQ_BW-1:0] i2x_len0, i2x_len1, i2x_len2, i2x_len3;
|
||||
wire [1:0] i2x_cmd0, i2x_cmd1, i2x_cmd2, i2x_cmd3;
|
||||
wire [`SDR_REQ_ID_W-1:0] i2x_id0, i2x_id1, i2x_id2, i2x_id3;
|
||||
|
||||
reg b2x_req;
|
||||
wire b2x_idle, b2x_start, b2x_last, b2x_wrap;
|
||||
wire [`SDR_REQ_ID_W-1:0] b2x_id;
|
||||
wire [12:0] b2x_addr;
|
||||
wire [`REQ_BW-1:0] b2x_len;
|
||||
wire [1:0] b2x_cmd;
|
||||
wire [3:0] x2i_ack;
|
||||
reg [1:0] b2x_ba;
|
||||
|
||||
reg [`SDR_REQ_ID_W-1:0] curr_id;
|
||||
|
||||
wire [1:0] xfr_ba;
|
||||
wire xfr_ba_last;
|
||||
wire [3:0] xfr_ok;
|
||||
|
||||
// This 8 bit register stores the bank addresses for upto 4 requests.
|
||||
reg [7:0] rank_ba;
|
||||
reg [3:0] rank_ba_last;
|
||||
// This 3 bit counter counts the number of requests we have
|
||||
// buffered so far, legal values are 0, 1, 2, 3, or 4.
|
||||
reg [2:0] rank_cnt;
|
||||
wire [3:0] rank_req, rank_wr_sel;
|
||||
wire rank_fifo_wr, rank_fifo_rd;
|
||||
wire rank_fifo_full, rank_fifo_mt;
|
||||
|
||||
wire [12:0] bank0_row, bank1_row, bank2_row, bank3_row;
|
||||
|
||||
assign b2x_tras_ok = &tras_ok;
|
||||
|
||||
|
||||
// Distribute the request from req_gen
|
||||
|
||||
assign r2i_req[0] = (r2b_ba == 2'b00) ? r2b_req & ~rank_fifo_full : 1'b0;
|
||||
assign r2i_req[1] = (r2b_ba == 2'b01) ? r2b_req & ~rank_fifo_full : 1'b0;
|
||||
assign r2i_req[2] = (r2b_ba == 2'b10) ? r2b_req & ~rank_fifo_full : 1'b0;
|
||||
assign r2i_req[3] = (r2b_ba == 2'b11) ? r2b_req & ~rank_fifo_full : 1'b0;
|
||||
|
||||
/******************
|
||||
Modified the Better FPGA Timing Purpose
|
||||
assign b2r_ack = (r2b_ba == 2'b00) ? i2r_ack[0] :
|
||||
(r2b_ba == 2'b01) ? i2r_ack[1] :
|
||||
(r2b_ba == 2'b10) ? i2r_ack[2] :
|
||||
(r2b_ba == 2'b11) ? i2r_ack[3] : 1'b0;
|
||||
********************/
|
||||
// Assumption: Only one Ack Will be asserted at a time.
|
||||
assign b2r_ack =|i2r_ack;
|
||||
|
||||
assign b2r_arb_ok = ~rank_fifo_full;
|
||||
|
||||
// Put the requests from the 4 bank_fsms into a 4 deep shift
|
||||
// register file. The earliest request is prioritized over the
|
||||
// later requests. Also the number of requests we are allowed to
|
||||
// buffer is limited by a 2 bit external input
|
||||
|
||||
// Mux the req/cmd to xfr_ctl. Allow RD/WR commands from the request in
|
||||
// rank0, allow only PR/ACT commands from the requests in other ranks
|
||||
// If the rank_fifo is empty, send the request from the bank addressed by
|
||||
// r2b_ba
|
||||
|
||||
// In FPGA Mode, to improve the timing, also send the rank_ba
|
||||
assign xfr_ba = (`TARGET_DESIGN == `FPGA) ? rank_ba[1:0]:
|
||||
((rank_fifo_mt) ? r2b_ba : rank_ba[1:0]);
|
||||
assign xfr_ba_last = (`TARGET_DESIGN == `FPGA) ? rank_ba_last[0]:
|
||||
((rank_fifo_mt) ? sdr_req_norm_dma_last : rank_ba_last[0]);
|
||||
|
||||
assign rank_req[0] = i2x_req[xfr_ba]; // each rank generates requests
|
||||
|
||||
assign rank_req[1] = (rank_cnt < 3'h2) ? 1'b0 :
|
||||
(rank_ba[3:2] == 2'b00) ? i2x_req[0] & ~i2x_cmd0[1] :
|
||||
(rank_ba[3:2] == 2'b01) ? i2x_req[1] & ~i2x_cmd1[1] :
|
||||
(rank_ba[3:2] == 2'b10) ? i2x_req[2] & ~i2x_cmd2[1] :
|
||||
i2x_req[3] & ~i2x_cmd3[1];
|
||||
|
||||
assign rank_req[2] = (rank_cnt < 3'h3) ? 1'b0 :
|
||||
(rank_ba[5:4] == 2'b00) ? i2x_req[0] & ~i2x_cmd0[1] :
|
||||
(rank_ba[5:4] == 2'b01) ? i2x_req[1] & ~i2x_cmd1[1] :
|
||||
(rank_ba[5:4] == 2'b10) ? i2x_req[2] & ~i2x_cmd2[1] :
|
||||
i2x_req[3] & ~i2x_cmd3[1];
|
||||
|
||||
assign rank_req[3] = (rank_cnt < 3'h4) ? 1'b0 :
|
||||
(rank_ba[7:6] == 2'b00) ? i2x_req[0] & ~i2x_cmd0[1] :
|
||||
(rank_ba[7:6] == 2'b01) ? i2x_req[1] & ~i2x_cmd1[1] :
|
||||
(rank_ba[7:6] == 2'b10) ? i2x_req[2] & ~i2x_cmd2[1] :
|
||||
i2x_req[3] & ~i2x_cmd3[1];
|
||||
|
||||
always @ (*) begin
|
||||
b2x_req = 1'b0;
|
||||
b2x_ba = xfr_ba;
|
||||
|
||||
if(`TARGET_DESIGN == `ASIC) begin // Support Multiple Rank request only on ASIC
|
||||
if (rank_req[0]) begin
|
||||
b2x_req = 1'b1;
|
||||
b2x_ba = xfr_ba;
|
||||
end // if (rank_req[0])
|
||||
else if (rank_req[1]) begin
|
||||
b2x_req = 1'b1;
|
||||
b2x_ba = rank_ba[3:2];
|
||||
end // if (rank_req[1])
|
||||
else if (rank_req[2]) begin
|
||||
b2x_req = 1'b1;
|
||||
b2x_ba = rank_ba[5:4];
|
||||
end // if (rank_req[2])
|
||||
else if (rank_req[3]) begin
|
||||
b2x_req = 1'b1;
|
||||
b2x_ba = rank_ba[7:6];
|
||||
end // if (rank_req[3])
|
||||
end else begin // If FPGA
|
||||
if (rank_req[0]) begin
|
||||
b2x_req = 1'b1;
|
||||
end
|
||||
end
|
||||
end // always @ (rank_req or rank_fifo_mt or r2b_ba or rank_ba)
|
||||
|
||||
assign b2x_idle = rank_fifo_mt;
|
||||
assign b2x_start = i2x_start[b2x_ba];
|
||||
assign b2x_last = i2x_last[b2x_ba];
|
||||
assign b2x_wrap = i2x_wrap[b2x_ba];
|
||||
|
||||
assign b2x_addr = (b2x_ba == 2'b11) ? i2x_addr3 :
|
||||
(b2x_ba == 2'b10) ? i2x_addr2 :
|
||||
(b2x_ba == 2'b01) ? i2x_addr1 : i2x_addr0;
|
||||
|
||||
assign b2x_len = (b2x_ba == 2'b11) ? i2x_len3 :
|
||||
(b2x_ba == 2'b10) ? i2x_len2 :
|
||||
(b2x_ba == 2'b01) ? i2x_len1 : i2x_len0;
|
||||
|
||||
assign b2x_cmd = (b2x_ba == 2'b11) ? i2x_cmd3 :
|
||||
(b2x_ba == 2'b10) ? i2x_cmd2 :
|
||||
(b2x_ba == 2'b01) ? i2x_cmd1 : i2x_cmd0;
|
||||
|
||||
assign b2x_id = (b2x_ba == 2'b11) ? i2x_id3 :
|
||||
(b2x_ba == 2'b10) ? i2x_id2 :
|
||||
(b2x_ba == 2'b01) ? i2x_id1 : i2x_id0;
|
||||
|
||||
assign x2i_ack[0] = (b2x_ba == 2'b00) ? x2b_ack : 1'b0;
|
||||
assign x2i_ack[1] = (b2x_ba == 2'b01) ? x2b_ack : 1'b0;
|
||||
assign x2i_ack[2] = (b2x_ba == 2'b10) ? x2b_ack : 1'b0;
|
||||
assign x2i_ack[3] = (b2x_ba == 2'b11) ? x2b_ack : 1'b0;
|
||||
|
||||
// Rank Fifo
|
||||
// On a write write to selected rank and increment rank_cnt
|
||||
// On a read shift rank_ba right 2 bits and decrement rank_cnt
|
||||
|
||||
assign rank_fifo_wr = b2r_ack;
|
||||
|
||||
assign rank_fifo_rd = b2x_req & b2x_cmd[1] & x2b_ack;
|
||||
|
||||
assign rank_wr_sel[0] = (rank_cnt == 3'h0) ? rank_fifo_wr :
|
||||
(rank_cnt == 3'h1) ? rank_fifo_wr & rank_fifo_rd :
|
||||
1'b0;
|
||||
|
||||
assign rank_wr_sel[1] = (rank_cnt == 3'h1) ? rank_fifo_wr & ~rank_fifo_rd :
|
||||
(rank_cnt == 3'h2) ? rank_fifo_wr & rank_fifo_rd :
|
||||
1'b0;
|
||||
|
||||
assign rank_wr_sel[2] = (rank_cnt == 3'h2) ? rank_fifo_wr & ~rank_fifo_rd :
|
||||
(rank_cnt == 3'h3) ? rank_fifo_wr & rank_fifo_rd :
|
||||
1'b0;
|
||||
|
||||
assign rank_wr_sel[3] = (rank_cnt == 3'h3) ? rank_fifo_wr & ~rank_fifo_rd :
|
||||
(rank_cnt == 3'h4) ? rank_fifo_wr & rank_fifo_rd :
|
||||
1'b0;
|
||||
|
||||
assign rank_fifo_mt = (rank_cnt == 3'b0) ? 1'b1 : 1'b0;
|
||||
|
||||
assign rank_fifo_full = (rank_cnt[2]) ? 1'b1 :
|
||||
(rank_cnt[1:0] == a2b_req_depth) ? 1'b1 : 1'b0;
|
||||
|
||||
// FIFO Check
|
||||
|
||||
// synopsys translate_off
|
||||
|
||||
always @ (posedge clk) begin
|
||||
|
||||
if (~rank_fifo_wr & rank_fifo_rd && rank_cnt == 3'h0) begin
|
||||
$display ("%t: %m: ERROR!!! Read from empty Fifo", $time);
|
||||
$stop;
|
||||
end // if (rank_fifo_rd && rank_cnt == 3'h0)
|
||||
|
||||
if (rank_fifo_wr && ~rank_fifo_rd && rank_cnt == 3'h4) begin
|
||||
$display ("%t: %m: ERROR!!! Write to full Fifo", $time);
|
||||
$stop;
|
||||
end // if (rank_fifo_wr && ~rank_fifo_rd && rank_cnt == 3'h4)
|
||||
|
||||
end // always @ (posedge clk)
|
||||
|
||||
// synopsys translate_on
|
||||
|
||||
always @ (posedge clk)
|
||||
if (~reset_n) begin
|
||||
rank_cnt <= 3'b0;
|
||||
rank_ba <= 8'b0;
|
||||
rank_ba_last <= 4'b0;
|
||||
|
||||
end // if (~reset_n)
|
||||
else begin
|
||||
|
||||
rank_cnt <= (rank_fifo_wr & ~rank_fifo_rd) ? rank_cnt + 3'b1 :
|
||||
(~rank_fifo_wr & rank_fifo_rd) ? rank_cnt - 3'b1 :
|
||||
rank_cnt;
|
||||
|
||||
rank_ba[1:0] <= (rank_wr_sel[0]) ? r2b_ba :
|
||||
(rank_fifo_rd) ? rank_ba[3:2] : rank_ba[1:0];
|
||||
|
||||
rank_ba[3:2] <= (rank_wr_sel[1]) ? r2b_ba :
|
||||
(rank_fifo_rd) ? rank_ba[5:4] : rank_ba[3:2];
|
||||
|
||||
rank_ba[5:4] <= (rank_wr_sel[2]) ? r2b_ba :
|
||||
(rank_fifo_rd) ? rank_ba[7:6] : rank_ba[5:4];
|
||||
|
||||
rank_ba[7:6] <= (rank_wr_sel[3]) ? r2b_ba :
|
||||
(rank_fifo_rd) ? 2'b00 : rank_ba[7:6];
|
||||
|
||||
if(`TARGET_DESIGN == `ASIC) begin // This Logic is implemented for ASIC Only
|
||||
// Note: Currenly top-level does not generate the
|
||||
// sdr_req_norm_dma_last signal and can be tied zero at top-level
|
||||
rank_ba_last[0] <= (rank_wr_sel[0]) ? sdr_req_norm_dma_last :
|
||||
(rank_fifo_rd) ? rank_ba_last[1] : rank_ba_last[0];
|
||||
|
||||
rank_ba_last[1] <= (rank_wr_sel[1]) ? sdr_req_norm_dma_last :
|
||||
(rank_fifo_rd) ? rank_ba_last[2] : rank_ba_last[1];
|
||||
|
||||
rank_ba_last[2] <= (rank_wr_sel[2]) ? sdr_req_norm_dma_last :
|
||||
(rank_fifo_rd) ? rank_ba_last[3] : rank_ba_last[2];
|
||||
|
||||
rank_ba_last[3] <= (rank_wr_sel[3]) ? sdr_req_norm_dma_last :
|
||||
(rank_fifo_rd) ? 1'b0 : rank_ba_last[3];
|
||||
end
|
||||
|
||||
end // else: !if(~reset_n)
|
||||
|
||||
assign xfr_ok[0] = (xfr_ba == 2'b00) ? 1'b1 : 1'b0;
|
||||
assign xfr_ok[1] = (xfr_ba == 2'b01) ? 1'b1 : 1'b0;
|
||||
assign xfr_ok[2] = (xfr_ba == 2'b10) ? 1'b1 : 1'b0;
|
||||
assign xfr_ok[3] = (xfr_ba == 2'b11) ? 1'b1 : 1'b0;
|
||||
|
||||
/****************************************************************************/
|
||||
// Instantiate Bank Ctl FSM 0
|
||||
|
||||
sdrc_bank_fsm bank0_fsm (.clk (clk),
|
||||
.reset_n (reset_n),
|
||||
|
||||
/* Req from req_gen */
|
||||
.r2b_req (r2i_req[0]),
|
||||
.r2b_req_id (r2b_req_id),
|
||||
.r2b_start (r2b_start),
|
||||
.r2b_last (r2b_last),
|
||||
.r2b_wrap (r2b_wrap),
|
||||
.r2b_raddr (r2b_raddr),
|
||||
.r2b_caddr (r2b_caddr),
|
||||
.r2b_len (r2b_len),
|
||||
.r2b_write (r2b_write),
|
||||
.b2r_ack (i2r_ack[0]),
|
||||
.sdr_dma_last(rank_ba_last[0]),
|
||||
|
||||
/* Transfer request to xfr_ctl */
|
||||
.b2x_req (i2x_req[0]),
|
||||
.b2x_start (i2x_start[0]),
|
||||
.b2x_last (i2x_last[0]),
|
||||
.b2x_wrap (i2x_wrap[0]),
|
||||
.b2x_id (i2x_id0),
|
||||
.b2x_addr (i2x_addr0),
|
||||
.b2x_len (i2x_len0),
|
||||
.b2x_cmd (i2x_cmd0),
|
||||
.x2b_ack (x2i_ack[0]),
|
||||
|
||||
/* Status to/from xfr_ctl */
|
||||
.tras_ok (tras_ok[0]),
|
||||
.xfr_ok (xfr_ok[0]),
|
||||
.x2b_refresh (x2b_refresh),
|
||||
.x2b_pre_ok (x2b_pre_ok[0]),
|
||||
.x2b_act_ok (x2b_act_ok),
|
||||
.x2b_rdok (x2b_rdok),
|
||||
.x2b_wrok (x2b_wrok),
|
||||
|
||||
.bank_row(bank0_row),
|
||||
|
||||
/* SDRAM Timing */
|
||||
.tras_delay (tras_delay),
|
||||
.trp_delay (trp_delay),
|
||||
.trcd_delay (trcd_delay));
|
||||
|
||||
/****************************************************************************/
|
||||
// Instantiate Bank Ctl FSM 1
|
||||
|
||||
sdrc_bank_fsm bank1_fsm (.clk (clk),
|
||||
.reset_n (reset_n),
|
||||
|
||||
/* Req from req_gen */
|
||||
.r2b_req (r2i_req[1]),
|
||||
.r2b_req_id (r2b_req_id),
|
||||
.r2b_start (r2b_start),
|
||||
.r2b_last (r2b_last),
|
||||
.r2b_wrap (r2b_wrap),
|
||||
.r2b_raddr (r2b_raddr),
|
||||
.r2b_caddr (r2b_caddr),
|
||||
.r2b_len (r2b_len),
|
||||
.r2b_write (r2b_write),
|
||||
.b2r_ack (i2r_ack[1]),
|
||||
.sdr_dma_last(rank_ba_last[1]),
|
||||
|
||||
/* Transfer request to xfr_ctl */
|
||||
.b2x_req (i2x_req[1]),
|
||||
.b2x_start (i2x_start[1]),
|
||||
.b2x_last (i2x_last[1]),
|
||||
.b2x_wrap (i2x_wrap[1]),
|
||||
.b2x_id (i2x_id1),
|
||||
.b2x_addr (i2x_addr1),
|
||||
.b2x_len (i2x_len1),
|
||||
.b2x_cmd (i2x_cmd1),
|
||||
.x2b_ack (x2i_ack[1]),
|
||||
|
||||
/* Status to/from xfr_ctl */
|
||||
.tras_ok (tras_ok[1]),
|
||||
.xfr_ok (xfr_ok[1]),
|
||||
.x2b_refresh (x2b_refresh),
|
||||
.x2b_pre_ok (x2b_pre_ok[1]),
|
||||
.x2b_act_ok (x2b_act_ok),
|
||||
.x2b_rdok (x2b_rdok),
|
||||
.x2b_wrok (x2b_wrok),
|
||||
|
||||
.bank_row(bank1_row),
|
||||
|
||||
/* SDRAM Timing */
|
||||
.tras_delay (tras_delay),
|
||||
.trp_delay (trp_delay),
|
||||
.trcd_delay (trcd_delay));
|
||||
|
||||
/****************************************************************************/
|
||||
// Instantiate Bank Ctl FSM 2
|
||||
|
||||
sdrc_bank_fsm bank2_fsm (.clk (clk),
|
||||
.reset_n (reset_n),
|
||||
|
||||
/* Req from req_gen */
|
||||
.r2b_req (r2i_req[2]),
|
||||
.r2b_req_id (r2b_req_id),
|
||||
.r2b_start (r2b_start),
|
||||
.r2b_last (r2b_last),
|
||||
.r2b_wrap (r2b_wrap),
|
||||
.r2b_raddr (r2b_raddr),
|
||||
.r2b_caddr (r2b_caddr),
|
||||
.r2b_len (r2b_len),
|
||||
.r2b_write (r2b_write),
|
||||
.b2r_ack (i2r_ack[2]),
|
||||
.sdr_dma_last(rank_ba_last[2]),
|
||||
|
||||
/* Transfer request to xfr_ctl */
|
||||
.b2x_req (i2x_req[2]),
|
||||
.b2x_start (i2x_start[2]),
|
||||
.b2x_last (i2x_last[2]),
|
||||
.b2x_wrap (i2x_wrap[2]),
|
||||
.b2x_id (i2x_id2),
|
||||
.b2x_addr (i2x_addr2),
|
||||
.b2x_len (i2x_len2),
|
||||
.b2x_cmd (i2x_cmd2),
|
||||
.x2b_ack (x2i_ack[2]),
|
||||
|
||||
/* Status to/from xfr_ctl */
|
||||
.tras_ok (tras_ok[2]),
|
||||
.xfr_ok (xfr_ok[2]),
|
||||
.x2b_refresh (x2b_refresh),
|
||||
.x2b_pre_ok (x2b_pre_ok[2]),
|
||||
.x2b_act_ok (x2b_act_ok),
|
||||
.x2b_rdok (x2b_rdok),
|
||||
.x2b_wrok (x2b_wrok),
|
||||
|
||||
.bank_row(bank2_row),
|
||||
|
||||
/* SDRAM Timing */
|
||||
.tras_delay (tras_delay),
|
||||
.trp_delay (trp_delay),
|
||||
.trcd_delay (trcd_delay));
|
||||
|
||||
/****************************************************************************/
|
||||
// Instantiate Bank Ctl FSM 3
|
||||
|
||||
sdrc_bank_fsm bank3_fsm (.clk (clk),
|
||||
.reset_n (reset_n),
|
||||
|
||||
/* Req from req_gen */
|
||||
.r2b_req (r2i_req[3]),
|
||||
.r2b_req_id (r2b_req_id),
|
||||
.r2b_start (r2b_start),
|
||||
.r2b_last (r2b_last),
|
||||
.r2b_wrap (r2b_wrap),
|
||||
.r2b_raddr (r2b_raddr),
|
||||
.r2b_caddr (r2b_caddr),
|
||||
.r2b_len (r2b_len),
|
||||
.r2b_write (r2b_write),
|
||||
.b2r_ack (i2r_ack[3]),
|
||||
.sdr_dma_last(rank_ba_last[3]),
|
||||
|
||||
/* Transfer request to xfr_ctl */
|
||||
.b2x_req (i2x_req[3]),
|
||||
.b2x_start (i2x_start[3]),
|
||||
.b2x_last (i2x_last[3]),
|
||||
.b2x_wrap (i2x_wrap[3]),
|
||||
.b2x_id (i2x_id3),
|
||||
.b2x_addr (i2x_addr3),
|
||||
.b2x_len (i2x_len3),
|
||||
.b2x_cmd (i2x_cmd3),
|
||||
.x2b_ack (x2i_ack[3]),
|
||||
|
||||
/* Status to/from xfr_ctl */
|
||||
.tras_ok (tras_ok[3]),
|
||||
.xfr_ok (xfr_ok[3]),
|
||||
.x2b_refresh (x2b_refresh),
|
||||
.x2b_pre_ok (x2b_pre_ok[3]),
|
||||
.x2b_act_ok (x2b_act_ok),
|
||||
.x2b_rdok (x2b_rdok),
|
||||
.x2b_wrok (x2b_wrok),
|
||||
|
||||
.bank_row(bank3_row),
|
||||
|
||||
/* SDRAM Timing */
|
||||
.tras_delay (tras_delay),
|
||||
.trp_delay (trp_delay),
|
||||
.trcd_delay (trcd_delay));
|
||||
|
||||
|
||||
/* address for current xfr, debug only */
|
||||
wire [12:0] cur_row = (xfr_bank_sel==3) ? bank3_row:
|
||||
(xfr_bank_sel==2) ? bank2_row:
|
||||
(xfr_bank_sel==1) ? bank1_row: bank0_row;
|
||||
|
||||
|
||||
|
||||
endmodule // sdr_bank_ctl
|
371
lib/common/Driver/SDRAM_driver/core/sdrc_bank_fsm.v
Normal file
371
lib/common/Driver/SDRAM_driver/core/sdrc_bank_fsm.v
Normal file
@ -0,0 +1,371 @@
|
||||
/*********************************************************************
|
||||
|
||||
SDRAM Controller Bank Controller
|
||||
|
||||
This file is part of the sdram controller project
|
||||
http://www.opencores.org/cores/sdr_ctrl/
|
||||
|
||||
Description:
|
||||
This module takes requests from sdrc_req_gen, checks for page hit/miss and
|
||||
issues precharge/activate commands and then passes the request to sdrc_xfr_ctl.
|
||||
|
||||
To Do:
|
||||
nothing
|
||||
|
||||
Author(s):
|
||||
- Dinesh Annayya, dinesha@opencores.org
|
||||
Version : 1.0 - 8th Jan 2012
|
||||
|
||||
|
||||
|
||||
Copyright (C) 2000 Authors and OPENCORES.ORG
|
||||
|
||||
This source file may be used and distributed without
|
||||
restriction provided that this copyright statement is not
|
||||
removed from the file and that any derivative work contains
|
||||
the original copyright notice and the associated disclaimer.
|
||||
|
||||
This source file is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU Lesser General
|
||||
Public License as published by the Free Software Foundation;
|
||||
either version 2.1 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
This source is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the GNU Lesser General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this source; if not, download it
|
||||
from http://www.opencores.org/lgpl.shtml
|
||||
|
||||
*******************************************************************/
|
||||
|
||||
|
||||
`include "sdrc_define.v"
|
||||
|
||||
module sdrc_bank_fsm (clk,
|
||||
reset_n,
|
||||
|
||||
/* Req from req_gen */
|
||||
r2b_req, // request
|
||||
r2b_req_id, // ID
|
||||
r2b_start, // First chunk of burst
|
||||
r2b_last, // Last chunk of burst
|
||||
r2b_wrap,
|
||||
r2b_raddr, // row address
|
||||
r2b_caddr, // col address
|
||||
r2b_len, // length
|
||||
r2b_write, // write request
|
||||
b2r_ack,
|
||||
sdr_dma_last,
|
||||
|
||||
/* Transfer request to xfr_ctl */
|
||||
b2x_req, // Request to xfr_ctl
|
||||
b2x_start, // first chunk of transfer
|
||||
b2x_last, // last chunk of transfer
|
||||
b2x_wrap,
|
||||
b2x_id, // Transfer ID
|
||||
b2x_addr, // row/col address
|
||||
b2x_len, // transfer length
|
||||
b2x_cmd, // transfer command
|
||||
x2b_ack, // command accepted
|
||||
|
||||
/* Status to/from xfr_ctl */
|
||||
tras_ok, // TRAS OK for this bank
|
||||
xfr_ok,
|
||||
x2b_refresh, // We did a refresh
|
||||
x2b_pre_ok, // OK to do a precharge (per bank)
|
||||
x2b_act_ok, // OK to do an activate
|
||||
x2b_rdok, // OK to do a read
|
||||
x2b_wrok, // OK to do a write
|
||||
|
||||
/* current xfr row address of the bank */
|
||||
bank_row,
|
||||
|
||||
/* SDRAM Timing */
|
||||
tras_delay, // Active to precharge delay
|
||||
trp_delay, // Precharge to active delay
|
||||
trcd_delay); // Active to R/W delay
|
||||
|
||||
|
||||
parameter SDR_DW = 16; // SDR Data Width
|
||||
parameter SDR_BW = 2; // SDR Byte Width
|
||||
|
||||
input clk, reset_n;
|
||||
|
||||
/* Req from bank_ctl */
|
||||
input r2b_req, r2b_start, r2b_last,
|
||||
r2b_write, r2b_wrap;
|
||||
input [`SDR_REQ_ID_W-1:0] r2b_req_id;
|
||||
input [12:0] r2b_raddr;
|
||||
input [12:0] r2b_caddr;
|
||||
input [`REQ_BW-1:0] r2b_len;
|
||||
output b2r_ack;
|
||||
input sdr_dma_last;
|
||||
|
||||
/* Req to xfr_ctl */
|
||||
output b2x_req, b2x_start, b2x_last,
|
||||
tras_ok, b2x_wrap;
|
||||
output [`SDR_REQ_ID_W-1:0] b2x_id;
|
||||
output [12:0] b2x_addr;
|
||||
output [`REQ_BW-1:0] b2x_len;
|
||||
output [1:0] b2x_cmd;
|
||||
input x2b_ack;
|
||||
|
||||
/* Status from xfr_ctl */
|
||||
input x2b_refresh, x2b_act_ok, x2b_rdok,
|
||||
x2b_wrok, x2b_pre_ok, xfr_ok;
|
||||
|
||||
input [3:0] tras_delay, trp_delay, trcd_delay;
|
||||
|
||||
output [12:0] bank_row;
|
||||
|
||||
/****************************************************************************/
|
||||
// Internal Nets
|
||||
|
||||
`define BANK_IDLE 3'b000
|
||||
`define BANK_PRE 3'b001
|
||||
`define BANK_ACT 3'b010
|
||||
`define BANK_XFR 3'b011
|
||||
`define BANK_DMA_LAST_PRE 3'b100
|
||||
|
||||
reg [2:0] bank_st, next_bank_st;
|
||||
wire b2x_start, b2x_last;
|
||||
reg l_start, l_last;
|
||||
reg b2x_req, b2r_ack;
|
||||
wire [`SDR_REQ_ID_W-1:0] b2x_id;
|
||||
reg [`SDR_REQ_ID_W-1:0] l_id;
|
||||
reg [12:0] b2x_addr;
|
||||
reg [`REQ_BW-1:0] l_len;
|
||||
wire [`REQ_BW-1:0] b2x_len;
|
||||
reg [1:0] b2x_cmd_t;
|
||||
reg bank_valid;
|
||||
reg [12:0] bank_row;
|
||||
reg [3:0] tras_cntr, timer0;
|
||||
reg l_wrap, l_write;
|
||||
wire b2x_wrap;
|
||||
reg [12:0] l_raddr;
|
||||
reg [12:0] l_caddr;
|
||||
reg l_sdr_dma_last;
|
||||
reg bank_prech_page_closed;
|
||||
|
||||
wire tras_ok_internal, tras_ok, activate_bank;
|
||||
|
||||
wire page_hit, timer0_tc_t, ld_trp, ld_trcd;
|
||||
|
||||
/*** Timing Break Logic Added for FPGA - Start ****/
|
||||
reg x2b_wrok_r, xfr_ok_r , x2b_rdok_r;
|
||||
reg [1:0] b2x_cmd_r,timer0_tc_r,tras_ok_r,x2b_pre_ok_r,x2b_act_ok_r;
|
||||
always @ (posedge clk)
|
||||
if (~reset_n) begin
|
||||
x2b_wrok_r <= 1'b0;
|
||||
xfr_ok_r <= 1'b0;
|
||||
x2b_rdok_r <= 1'b0;
|
||||
b2x_cmd_r <= 2'b0;
|
||||
timer0_tc_r <= 1'b0;
|
||||
tras_ok_r <= 1'b0;
|
||||
x2b_pre_ok_r <= 1'b0;
|
||||
x2b_act_ok_r <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
x2b_wrok_r <= x2b_wrok;
|
||||
xfr_ok_r <= xfr_ok;
|
||||
x2b_rdok_r <= x2b_rdok;
|
||||
b2x_cmd_r <= b2x_cmd_t;
|
||||
timer0_tc_r <= (ld_trp | ld_trcd) ? 1'b0 : timer0_tc_t;
|
||||
tras_ok_r <= tras_ok_internal;
|
||||
x2b_pre_ok_r <= x2b_pre_ok;
|
||||
x2b_act_ok_r <= x2b_act_ok;
|
||||
end
|
||||
|
||||
wire x2b_wrok_t = (`TARGET_DESIGN == `FPGA) ? x2b_wrok_r : x2b_wrok;
|
||||
wire xfr_ok_t = (`TARGET_DESIGN == `FPGA) ? xfr_ok_r : xfr_ok;
|
||||
wire x2b_rdok_t = (`TARGET_DESIGN == `FPGA) ? x2b_rdok_r : x2b_rdok;
|
||||
wire [1:0] b2x_cmd = (`TARGET_DESIGN == `FPGA) ? b2x_cmd_r : b2x_cmd_t;
|
||||
wire timer0_tc = (`TARGET_DESIGN == `FPGA) ? timer0_tc_r : timer0_tc_t;
|
||||
assign tras_ok = (`TARGET_DESIGN == `FPGA) ? tras_ok_r : tras_ok_internal;
|
||||
wire x2b_pre_ok_t = (`TARGET_DESIGN == `FPGA) ? x2b_pre_ok_r : x2b_pre_ok;
|
||||
wire x2b_act_ok_t = (`TARGET_DESIGN == `FPGA) ? x2b_act_ok_r : x2b_act_ok;
|
||||
|
||||
/*** Timing Break Logic Added for FPGA - End****/
|
||||
|
||||
|
||||
always @ (posedge clk)
|
||||
if (~reset_n) begin
|
||||
bank_valid <= 1'b0;
|
||||
tras_cntr <= 4'b0;
|
||||
timer0 <= 4'b0;
|
||||
bank_st <= `BANK_IDLE;
|
||||
end // if (~reset_n)
|
||||
|
||||
else begin
|
||||
|
||||
bank_valid <= (x2b_refresh || bank_prech_page_closed) ? 1'b0 : // force the bank status to be invalid
|
||||
(activate_bank) ? 1'b1 : bank_valid;
|
||||
|
||||
tras_cntr <= (activate_bank) ? tras_delay :
|
||||
(~tras_ok_internal) ? tras_cntr - 4'b1 : 4'b0;
|
||||
|
||||
timer0 <= (ld_trp) ? trp_delay :
|
||||
(ld_trcd) ? trcd_delay :
|
||||
(timer0 != 'h0) ? timer0 - 4'b1 : timer0;
|
||||
|
||||
bank_st <= next_bank_st;
|
||||
|
||||
end // else: !if(~reset_n)
|
||||
|
||||
always @ (posedge clk) begin
|
||||
|
||||
bank_row <= (bank_st == `BANK_ACT) ? b2x_addr : bank_row;
|
||||
|
||||
if (~reset_n) begin
|
||||
l_start <= 1'b0;
|
||||
l_last <= 1'b0;
|
||||
l_id <= 1'b0;
|
||||
l_len <= 1'b0;
|
||||
l_wrap <= 1'b0;
|
||||
l_write <= 1'b0;
|
||||
l_raddr <= 1'b0;
|
||||
l_caddr <= 1'b0;
|
||||
l_sdr_dma_last <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
if (b2r_ack) begin
|
||||
l_start <= r2b_start;
|
||||
l_last <= r2b_last;
|
||||
l_id <= r2b_req_id;
|
||||
l_len <= r2b_len;
|
||||
l_wrap <= r2b_wrap;
|
||||
l_write <= r2b_write;
|
||||
l_raddr <= r2b_raddr;
|
||||
l_caddr <= r2b_caddr;
|
||||
l_sdr_dma_last <= sdr_dma_last;
|
||||
end // if (b2r_ack)
|
||||
end
|
||||
|
||||
end // always @ (posedge clk)
|
||||
|
||||
assign tras_ok_internal = ~|tras_cntr;
|
||||
|
||||
assign activate_bank = (b2x_cmd == `OP_ACT) & x2b_ack;
|
||||
|
||||
assign page_hit = (r2b_raddr == bank_row) ? bank_valid : 1'b0; // its a hit only if bank is valid
|
||||
|
||||
assign timer0_tc_t = ~|timer0;
|
||||
|
||||
assign ld_trp = (b2x_cmd == `OP_PRE) ? x2b_ack : 1'b0;
|
||||
|
||||
assign ld_trcd = (b2x_cmd == `OP_ACT) ? x2b_ack : 1'b0;
|
||||
|
||||
|
||||
|
||||
always @ (*) begin
|
||||
|
||||
bank_prech_page_closed = 1'b0;
|
||||
b2x_req = 1'b0;
|
||||
b2x_cmd_t = 2'bx;
|
||||
b2r_ack = 1'b0;
|
||||
b2x_addr = 13'bx;
|
||||
next_bank_st = bank_st;
|
||||
|
||||
case (bank_st)
|
||||
|
||||
`BANK_IDLE : begin
|
||||
if(`TARGET_DESIGN == `FPGA) begin // To break the timing, b2x request are generated delayed
|
||||
if (~r2b_req) begin
|
||||
next_bank_st = `BANK_IDLE;
|
||||
end // if (~r2b_req)
|
||||
else if (page_hit) begin
|
||||
b2r_ack = 1'b1;
|
||||
b2x_cmd_t = (r2b_write) ? `OP_WR : `OP_RD;
|
||||
next_bank_st = `BANK_XFR;
|
||||
end // if (page_hit)
|
||||
else begin // page_miss
|
||||
b2r_ack = 1'b1;
|
||||
b2x_cmd_t = `OP_PRE;
|
||||
next_bank_st = `BANK_PRE; // bank was precharged on l_sdr_dma_last
|
||||
end // else: !if(page_hit)
|
||||
end else begin // ASIC
|
||||
if (~r2b_req) begin
|
||||
bank_prech_page_closed = 1'b0;
|
||||
b2x_req = 1'b0;
|
||||
b2x_cmd_t = 2'bx;
|
||||
b2r_ack = 1'b0;
|
||||
b2x_addr = 13'bx;
|
||||
next_bank_st = `BANK_IDLE;
|
||||
end // if (~r2b_req)
|
||||
else if (page_hit) begin
|
||||
b2x_req = (r2b_write) ? x2b_wrok_t & xfr_ok_t :
|
||||
x2b_rdok_t & xfr_ok_t;
|
||||
b2x_cmd_t = (r2b_write) ? `OP_WR : `OP_RD;
|
||||
b2r_ack = 1'b1;
|
||||
b2x_addr = r2b_caddr;
|
||||
next_bank_st = (x2b_ack) ? `BANK_IDLE : `BANK_XFR; // in case of hit, stay here till xfr sm acks
|
||||
end // if (page_hit)
|
||||
else begin // page_miss
|
||||
b2x_req = tras_ok & x2b_pre_ok_t;
|
||||
b2x_cmd_t = `OP_PRE;
|
||||
b2r_ack = 1'b1;
|
||||
b2x_addr = r2b_raddr & 13'hBFF; // Dont want to pre all banks!
|
||||
next_bank_st = (l_sdr_dma_last) ? `BANK_PRE : (x2b_ack) ? `BANK_ACT : `BANK_PRE; // bank was precharged on l_sdr_dma_last
|
||||
end // else: !if(page_hit)
|
||||
end
|
||||
end // case: `BANK_IDLE
|
||||
|
||||
`BANK_PRE : begin
|
||||
b2x_req = tras_ok & x2b_pre_ok_t;
|
||||
b2x_cmd_t = `OP_PRE;
|
||||
b2r_ack = 1'b0;
|
||||
b2x_addr = l_raddr & 13'hBFF; // Dont want to pre all banks!
|
||||
bank_prech_page_closed = 1'b0;
|
||||
next_bank_st = (x2b_ack) ? `BANK_ACT : `BANK_PRE;
|
||||
end // case: `BANK_PRE
|
||||
|
||||
`BANK_ACT : begin
|
||||
b2x_req = timer0_tc & x2b_act_ok_t;
|
||||
b2x_cmd_t = `OP_ACT;
|
||||
b2r_ack = 1'b0;
|
||||
b2x_addr = l_raddr;
|
||||
bank_prech_page_closed = 1'b0;
|
||||
next_bank_st = (x2b_ack) ? `BANK_XFR : `BANK_ACT;
|
||||
end // case: `BANK_ACT
|
||||
|
||||
`BANK_XFR : begin
|
||||
b2x_req = (l_write) ? timer0_tc & x2b_wrok_t & xfr_ok_t :
|
||||
timer0_tc & x2b_rdok_t & xfr_ok_t;
|
||||
b2x_cmd_t = (l_write) ? `OP_WR : `OP_RD;
|
||||
b2r_ack = 1'b0;
|
||||
b2x_addr = l_caddr;
|
||||
bank_prech_page_closed = 1'b0;
|
||||
next_bank_st = (x2b_refresh) ? `BANK_ACT :
|
||||
(x2b_ack & l_sdr_dma_last) ? `BANK_DMA_LAST_PRE :
|
||||
(x2b_ack) ? `BANK_IDLE : `BANK_XFR;
|
||||
end // case: `BANK_XFR
|
||||
|
||||
`BANK_DMA_LAST_PRE : begin
|
||||
b2x_req = tras_ok & x2b_pre_ok_t;
|
||||
b2x_cmd_t = `OP_PRE;
|
||||
b2r_ack = 1'b0;
|
||||
b2x_addr = l_raddr & 13'hBFF; // Dont want to pre all banks!
|
||||
bank_prech_page_closed = 1'b1;
|
||||
next_bank_st = (x2b_ack) ? `BANK_IDLE : `BANK_DMA_LAST_PRE;
|
||||
end // case: `BANK_DMA_LAST_PRE
|
||||
|
||||
endcase // case(bank_st)
|
||||
|
||||
end // always @ (bank_st or ...)
|
||||
|
||||
assign b2x_start = (bank_st == `BANK_IDLE) ? r2b_start : l_start;
|
||||
|
||||
assign b2x_last = (bank_st == `BANK_IDLE) ? r2b_last : l_last;
|
||||
|
||||
assign b2x_id = (bank_st == `BANK_IDLE) ? r2b_req_id : l_id;
|
||||
|
||||
assign b2x_len = (bank_st == `BANK_IDLE) ? r2b_len : l_len;
|
||||
|
||||
assign b2x_wrap = (bank_st == `BANK_IDLE) ? r2b_wrap : l_wrap;
|
||||
|
||||
endmodule // sdr_bank_fsm
|
228
lib/common/Driver/SDRAM_driver/core/sdrc_bs_convert.v
Normal file
228
lib/common/Driver/SDRAM_driver/core/sdrc_bs_convert.v
Normal file
@ -0,0 +1,228 @@
|
||||
/*********************************************************************
|
||||
|
||||
SDRAM Controller buswidth converter
|
||||
|
||||
This file is part of the sdram controller project
|
||||
http://www.opencores.org/cores/sdr_ctrl/
|
||||
|
||||
Description: SDRAM Controller Buswidth converter
|
||||
|
||||
This module does write/read data transalation between
|
||||
application data to SDRAM bus width
|
||||
|
||||
To Do:
|
||||
nothing
|
||||
|
||||
Author(s):
|
||||
- Dinesh Annayya, dinesha@opencores.org
|
||||
Version : 0.0 - 8th Jan 2012 - Initial structure
|
||||
0.2 - 2nd Feb 2012
|
||||
Improved the command pipe structure to accept up-to 4 command of different bank.
|
||||
0.3 - 6th Feb 2012
|
||||
Bug fix on read valid generation
|
||||
|
||||
|
||||
|
||||
Copyright (C) 2000 Authors and OPENCORES.ORG
|
||||
|
||||
This source file may be used and distributed without
|
||||
restriction provided that this copyright statement is not
|
||||
removed from the file and that any derivative work contains
|
||||
the original copyright notice and the associated disclaimer.
|
||||
|
||||
This source file is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU Lesser General
|
||||
Public License as published by the Free Software Foundation;
|
||||
either version 2.1 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
This source is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the GNU Lesser General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this source; if not, download it
|
||||
from http://www.opencores.org/lgpl.shtml
|
||||
|
||||
*******************************************************************/
|
||||
|
||||
`include "sdrc_define.v"
|
||||
module sdrc_bs_convert (
|
||||
clk ,
|
||||
reset_n ,
|
||||
sdr_width ,
|
||||
|
||||
/* Control Signal from xfr ctrl */
|
||||
x2a_rdstart ,
|
||||
x2a_wrstart ,
|
||||
x2a_rdlast ,
|
||||
x2a_wrlast ,
|
||||
x2a_rddt ,
|
||||
x2a_rdok ,
|
||||
a2x_wrdt ,
|
||||
a2x_wren_n ,
|
||||
x2a_wrnext ,
|
||||
|
||||
/* Control Signal from/to to application i/f */
|
||||
app_wr_data ,
|
||||
app_wr_en_n ,
|
||||
app_wr_next ,
|
||||
app_last_wr ,
|
||||
app_rd_data ,
|
||||
app_rd_valid ,
|
||||
app_last_rd
|
||||
);
|
||||
|
||||
|
||||
parameter APP_AW = 30; // Application Address Width
|
||||
parameter APP_DW = 32; // Application Data Width
|
||||
parameter APP_BW = 4; // Application Byte Width
|
||||
|
||||
parameter SDR_DW = 16; // SDR Data Width
|
||||
parameter SDR_BW = 2; // SDR Byte Width
|
||||
|
||||
input clk ;
|
||||
input reset_n ;
|
||||
input [1:0] sdr_width ; // 2'b00 - 32 Bit SDR, 2'b01 - 16 Bit SDR, 2'b1x - 8 Bit
|
||||
|
||||
/* Control Signal from xfr ctrl Read Transaction*/
|
||||
input x2a_rdstart ; // read start indication
|
||||
input x2a_rdlast ; // read last burst access
|
||||
input [SDR_DW-1:0] x2a_rddt ;
|
||||
input x2a_rdok ;
|
||||
|
||||
/* Control Signal from xfr ctrl Write Transaction*/
|
||||
input x2a_wrstart ; // writ start indication
|
||||
input x2a_wrlast ; // write last transfer
|
||||
input x2a_wrnext ;
|
||||
output [SDR_DW-1:0] a2x_wrdt ;
|
||||
output [SDR_BW-1:0] a2x_wren_n ;
|
||||
|
||||
// Application Write Transaction
|
||||
input [APP_DW-1:0] app_wr_data ;
|
||||
input [APP_BW-1:0] app_wr_en_n ;
|
||||
output app_wr_next ;
|
||||
output app_last_wr ; // Indicate last Write Transfer for a given burst size
|
||||
|
||||
// Application Read Transaction
|
||||
output [APP_DW-1:0] app_rd_data ;
|
||||
output app_rd_valid ;
|
||||
output app_last_rd ; // Indicate last Read Transfer for a given burst size
|
||||
|
||||
//----------------------------------------------
|
||||
// Local Decleration
|
||||
// ----------------------------------------
|
||||
|
||||
reg [APP_DW-1:0] app_rd_data ;
|
||||
reg app_rd_valid ;
|
||||
reg [SDR_DW-1:0] a2x_wrdt ;
|
||||
reg [SDR_BW-1:0] a2x_wren_n ;
|
||||
reg app_wr_next ;
|
||||
|
||||
reg [23:0] saved_rd_data ;
|
||||
reg [1:0] rd_xfr_count ;
|
||||
reg [1:0] wr_xfr_count ;
|
||||
|
||||
|
||||
assign app_last_wr = x2a_wrlast;
|
||||
assign app_last_rd = x2a_rdlast;
|
||||
|
||||
always @(*) begin
|
||||
if(sdr_width == 2'b00) // 32 Bit SDR Mode
|
||||
begin
|
||||
a2x_wrdt = app_wr_data;
|
||||
a2x_wren_n = app_wr_en_n;
|
||||
app_wr_next = x2a_wrnext;
|
||||
app_rd_data = x2a_rddt;
|
||||
app_rd_valid = x2a_rdok;
|
||||
end
|
||||
else if(sdr_width == 2'b01) // 16 Bit SDR Mode
|
||||
begin
|
||||
// Changed the address and length to match the 16 bit SDR Mode
|
||||
app_wr_next = (x2a_wrnext & wr_xfr_count[0]);
|
||||
app_rd_valid = (x2a_rdok & rd_xfr_count[0]);
|
||||
if(wr_xfr_count[0] == 1'b1)
|
||||
begin
|
||||
a2x_wren_n = app_wr_en_n[3:2];
|
||||
a2x_wrdt = app_wr_data[31:16];
|
||||
end
|
||||
else
|
||||
begin
|
||||
a2x_wren_n = app_wr_en_n[1:0];
|
||||
a2x_wrdt = app_wr_data[15:0];
|
||||
end
|
||||
|
||||
app_rd_data = {x2a_rddt,saved_rd_data[15:0]};
|
||||
end else // 8 Bit SDR Mode
|
||||
begin
|
||||
// Changed the address and length to match the 16 bit SDR Mode
|
||||
app_wr_next = (x2a_wrnext & (wr_xfr_count[1:0]== 2'b11));
|
||||
app_rd_valid = (x2a_rdok & (rd_xfr_count[1:0]== 2'b11));
|
||||
if(wr_xfr_count[1:0] == 2'b11)
|
||||
begin
|
||||
a2x_wren_n = app_wr_en_n[3];
|
||||
a2x_wrdt = app_wr_data[31:24];
|
||||
end
|
||||
else if(wr_xfr_count[1:0] == 2'b10)
|
||||
begin
|
||||
a2x_wren_n = app_wr_en_n[2];
|
||||
a2x_wrdt = app_wr_data[23:16];
|
||||
end
|
||||
else if(wr_xfr_count[1:0] == 2'b01)
|
||||
begin
|
||||
a2x_wren_n = app_wr_en_n[1];
|
||||
a2x_wrdt = app_wr_data[15:8];
|
||||
end
|
||||
else begin
|
||||
a2x_wren_n = app_wr_en_n[0];
|
||||
a2x_wrdt = app_wr_data[7:0];
|
||||
end
|
||||
|
||||
app_rd_data = {x2a_rddt,saved_rd_data[23:0]};
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if(!reset_n)
|
||||
begin
|
||||
rd_xfr_count <= 8'b0;
|
||||
wr_xfr_count <= 8'b0;
|
||||
saved_rd_data <= 24'h0;
|
||||
end
|
||||
else begin
|
||||
|
||||
// During Write Phase
|
||||
if(x2a_wrlast) begin
|
||||
wr_xfr_count <= 0;
|
||||
end
|
||||
else if(x2a_wrnext) begin
|
||||
wr_xfr_count <= wr_xfr_count + 1'b1;
|
||||
end
|
||||
|
||||
// During Read Phase
|
||||
if(x2a_rdlast) begin
|
||||
rd_xfr_count <= 0;
|
||||
end
|
||||
else if(x2a_rdok) begin
|
||||
rd_xfr_count <= rd_xfr_count + 1'b1;
|
||||
end
|
||||
|
||||
// Save Previous Data
|
||||
if(x2a_rdok) begin
|
||||
if(sdr_width == 2'b01) // 16 Bit SDR Mode
|
||||
saved_rd_data[15:0] <= x2a_rddt;
|
||||
else begin// 8 bit SDR Mode -
|
||||
if(rd_xfr_count[1:0] == 2'b00) saved_rd_data[7:0] <= x2a_rddt[7:0];
|
||||
else if(rd_xfr_count[1:0] == 2'b01) saved_rd_data[15:8] <= x2a_rddt[7:0];
|
||||
else if(rd_xfr_count[1:0] == 2'b10) saved_rd_data[23:16] <= x2a_rddt[7:0];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // sdr_bs_convert
|
477
lib/common/Driver/SDRAM_driver/core/sdrc_core.v
Normal file
477
lib/common/Driver/SDRAM_driver/core/sdrc_core.v
Normal file
@ -0,0 +1,477 @@
|
||||
/*********************************************************************
|
||||
|
||||
SDRAM Controller Core File
|
||||
|
||||
This file is part of the sdram controller project
|
||||
http://www.opencores.org/cores/sdr_ctrl/
|
||||
|
||||
Description: SDRAM Controller Core Module
|
||||
2 types of SDRAMs are supported, 1Mx16 2 bank, or 4Mx16 4 bank.
|
||||
This block integrate following sub modules
|
||||
|
||||
sdrc_bs_convert
|
||||
convert the system side 32 bit into equvailent 8/16/32 SDR format
|
||||
sdrc_req_gen
|
||||
This module takes requests from the app, chops them to burst booundaries
|
||||
if wrap=0, decodes the bank and passe the request to bank_ctl
|
||||
sdrc_xfr_ctl
|
||||
This module takes requests from sdr_bank_ctl, runs the transfer and
|
||||
controls data flow to/from the app. At the end of the transfer it issues a
|
||||
burst terminate if not at the end of a burst and another command to this
|
||||
bank is not available.
|
||||
|
||||
sdrc_bank_ctl
|
||||
This module takes requests from sdr_req_gen, checks for page hit/miss and
|
||||
issues precharge/activate commands and then passes the request to
|
||||
sdr_xfr_ctl.
|
||||
|
||||
|
||||
Assumption: SDRAM Pads should be placed near to this module. else
|
||||
user should add a FF near the pads
|
||||
|
||||
To Do:
|
||||
nothing
|
||||
|
||||
Author(s):
|
||||
- Dinesh Annayya, dinesha@opencores.org
|
||||
Version : 0.0 - 8th Jan 2012
|
||||
Initial version with 16/32 Bit SDRAM Support
|
||||
: 0.1 - 24th Jan 2012
|
||||
8 Bit SDRAM Support is added
|
||||
0.2 - 2nd Feb 2012
|
||||
Improved the command pipe structure to accept up-to
|
||||
4 command of different bank.
|
||||
0.3 - 7th Feb 2012
|
||||
Bug fix for parameter defination for request length has changed from 9 to 12
|
||||
0.4 - 26th April 2013
|
||||
SDRAM Address Bit is Extended by 12 bit to 13 bit to support higher SDRAM
|
||||
|
||||
|
||||
Copyright (C) 2000 Authors and OPENCORES.ORG
|
||||
|
||||
This source file may be used and distributed without
|
||||
restriction provided that this copyright statement is not
|
||||
removed from the file and that any derivative work contains
|
||||
the original copyright notice and the associated disclaimer.
|
||||
|
||||
This source file is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU Lesser General
|
||||
Public License as published by the Free Software Foundation;
|
||||
either version 2.1 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
This source is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the GNU Lesser General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this source; if not, download it
|
||||
from http://www.opencores.org/lgpl.shtml
|
||||
|
||||
*******************************************************************/
|
||||
|
||||
|
||||
`include "sdrc_define.v"
|
||||
module sdrc_core
|
||||
(
|
||||
clk,
|
||||
pad_clk,
|
||||
reset_n,
|
||||
sdr_width,
|
||||
cfg_colbits,
|
||||
|
||||
/* Request from app */
|
||||
app_req, // Transfer Request
|
||||
app_req_addr, // SDRAM Address
|
||||
app_req_len, // Burst Length (in 16 bit words)
|
||||
app_req_wrap, // Wrap mode request (xfr_len = 4)
|
||||
app_req_wr_n, // 0 => Write request, 1 => read req
|
||||
app_req_ack, // Request has been accepted
|
||||
cfg_req_depth, //how many req. buffer should hold
|
||||
|
||||
app_wr_data,
|
||||
app_wr_en_n,
|
||||
app_last_wr,
|
||||
|
||||
app_rd_data,
|
||||
app_rd_valid,
|
||||
app_last_rd,
|
||||
app_wr_next_req,
|
||||
sdr_init_done,
|
||||
app_req_dma_last,
|
||||
|
||||
/* Interface to SDRAMs */
|
||||
sdr_cs_n,
|
||||
sdr_cke,
|
||||
sdr_ras_n,
|
||||
sdr_cas_n,
|
||||
sdr_we_n,
|
||||
sdr_dqm,
|
||||
sdr_ba,
|
||||
sdr_addr,
|
||||
pad_sdr_din,
|
||||
sdr_dout,
|
||||
sdr_den_n,
|
||||
|
||||
/* Parameters */
|
||||
cfg_sdr_en,
|
||||
cfg_sdr_mode_reg,
|
||||
cfg_sdr_tras_d,
|
||||
cfg_sdr_trp_d,
|
||||
cfg_sdr_trcd_d,
|
||||
cfg_sdr_cas,
|
||||
cfg_sdr_trcar_d,
|
||||
cfg_sdr_twr_d,
|
||||
cfg_sdr_rfsh,
|
||||
cfg_sdr_rfmax);
|
||||
|
||||
parameter APP_AW = 26; // Application Address Width
|
||||
parameter APP_DW = 32; // Application Data Width
|
||||
parameter APP_BW = 4; // Application Byte Width
|
||||
parameter APP_RW = 9; // Application Request Width
|
||||
|
||||
parameter SDR_DW = 16; // SDR Data Width
|
||||
parameter SDR_BW = 2; // SDR Byte Width
|
||||
|
||||
|
||||
//-----------------------------------------------
|
||||
// Global Variable
|
||||
// ----------------------------------------------
|
||||
input clk ; // SDRAM Clock
|
||||
input pad_clk ; // SDRAM Clock from Pad, used for registering Read Data
|
||||
input reset_n ; // Reset Signal
|
||||
input [1:0] sdr_width ; // 2'b00 - 32 Bit SDR, 2'b01 - 16 Bit SDR, 2'b1x - 8 Bit
|
||||
input [1:0] cfg_colbits ; // 2'b00 - 8 Bit column address, 2'b01 - 9 Bit, 10 - 10 bit, 11 - 11Bits
|
||||
|
||||
|
||||
//------------------------------------------------
|
||||
// Request from app
|
||||
//------------------------------------------------
|
||||
input app_req ; // Application Request
|
||||
input [APP_AW-1:0] app_req_addr ; // Address
|
||||
input app_req_wr_n ; // 0 - Write, 1 - Read
|
||||
input app_req_wrap ; // Address Wrap
|
||||
output app_req_ack ; // Application Request Ack
|
||||
|
||||
input [APP_DW-1:0] app_wr_data ; // Write Data
|
||||
output app_wr_next_req ; // Next Write Data Request
|
||||
input [APP_BW-1:0] app_wr_en_n ; // Byte wise Write Enable
|
||||
output app_last_wr ; // Last Write trannsfer of a given Burst
|
||||
output [APP_DW-1:0] app_rd_data ; // Read Data
|
||||
output app_rd_valid ; // Read Valid
|
||||
output app_last_rd ; // Last Read Transfer of a given Burst
|
||||
|
||||
//------------------------------------------------
|
||||
// Interface to SDRAMs
|
||||
//------------------------------------------------
|
||||
output sdr_cke ; // SDRAM CKE
|
||||
output sdr_cs_n ; // SDRAM Chip Select
|
||||
output sdr_ras_n ; // SDRAM ras
|
||||
output sdr_cas_n ; // SDRAM cas
|
||||
output sdr_we_n ; // SDRAM write enable
|
||||
output [SDR_BW-1:0] sdr_dqm ; // SDRAM Data Mask
|
||||
output [1:0] sdr_ba ; // SDRAM Bank Enable
|
||||
output [12:0] sdr_addr ; // SDRAM Address
|
||||
input [SDR_DW-1:0] pad_sdr_din ; // SDRA Data Input
|
||||
output [SDR_DW-1:0] sdr_dout ; // SDRAM Data Output
|
||||
output [SDR_BW-1:0] sdr_den_n ; // SDRAM Data Output enable
|
||||
|
||||
//------------------------------------------------
|
||||
// Configuration Parameter
|
||||
//------------------------------------------------
|
||||
output sdr_init_done ; // Indicate SDRAM Initialisation Done
|
||||
input [3:0] cfg_sdr_tras_d ; // Active to precharge delay
|
||||
input [3:0] cfg_sdr_trp_d ; // Precharge to active delay
|
||||
input [3:0] cfg_sdr_trcd_d ; // Active to R/W delay
|
||||
input cfg_sdr_en ; // Enable SDRAM controller
|
||||
input [1:0] cfg_req_depth ; // Maximum Request accepted by SDRAM controller
|
||||
input [APP_RW-1:0] app_req_len ; // Application Burst Request length in 32 bit
|
||||
input [12:0] cfg_sdr_mode_reg ;
|
||||
input [2:0] cfg_sdr_cas ; // SDRAM CAS Latency
|
||||
input [3:0] cfg_sdr_trcar_d ; // Auto-refresh period
|
||||
input [3:0] cfg_sdr_twr_d ; // Write recovery delay
|
||||
input [`SDR_RFSH_TIMER_W-1 : 0] cfg_sdr_rfsh;
|
||||
input [`SDR_RFSH_ROW_CNT_W -1 : 0] cfg_sdr_rfmax;
|
||||
input app_req_dma_last; // this signal should close the bank
|
||||
|
||||
/****************************************************************************/
|
||||
// Internal Nets
|
||||
|
||||
// SDR_REQ_GEN
|
||||
wire [`SDR_REQ_ID_W-1:0]r2b_req_id;
|
||||
wire [1:0] r2b_ba;
|
||||
wire [12:0] r2b_raddr;
|
||||
wire [12:0] r2b_caddr;
|
||||
wire [`REQ_BW-1:0] r2b_len;
|
||||
|
||||
// SDR BANK CTL
|
||||
wire [`SDR_REQ_ID_W-1:0]b2x_id;
|
||||
wire [1:0] b2x_ba;
|
||||
wire [12:0] b2x_addr;
|
||||
wire [`REQ_BW-1:0] b2x_len;
|
||||
wire [1:0] b2x_cmd;
|
||||
|
||||
// SDR_XFR_CTL
|
||||
wire [3:0] x2b_pre_ok;
|
||||
wire [`SDR_REQ_ID_W-1:0]xfr_id;
|
||||
wire [APP_DW-1:0] app_rd_data;
|
||||
wire sdr_cs_n, sdr_cke, sdr_ras_n, sdr_cas_n, sdr_we_n;
|
||||
wire [SDR_BW-1:0] sdr_dqm;
|
||||
wire [1:0] sdr_ba;
|
||||
wire [12:0] sdr_addr;
|
||||
wire [SDR_DW-1:0] sdr_dout;
|
||||
wire [SDR_DW-1:0] sdr_dout_int;
|
||||
wire [SDR_BW-1:0] sdr_den_n;
|
||||
wire [SDR_BW-1:0] sdr_den_n_int;
|
||||
|
||||
wire [1:0] xfr_bank_sel;
|
||||
|
||||
wire [APP_AW-1:0] app_req_addr;
|
||||
wire [APP_RW-1:0] app_req_len;
|
||||
|
||||
wire [APP_DW-1:0] app_wr_data;
|
||||
wire [SDR_DW-1:0] a2x_wrdt ;
|
||||
wire [APP_BW-1:0] app_wr_en_n;
|
||||
wire [SDR_BW-1:0] a2x_wren_n;
|
||||
|
||||
//wire [31:0] app_rd_data;
|
||||
wire [SDR_DW-1:0] x2a_rddt;
|
||||
|
||||
|
||||
// synopsys translate_off
|
||||
wire [3:0] sdr_cmd;
|
||||
assign sdr_cmd = {sdr_cs_n, sdr_ras_n, sdr_cas_n, sdr_we_n};
|
||||
// synopsys translate_on
|
||||
|
||||
assign sdr_den_n = sdr_den_n_int ;
|
||||
assign sdr_dout = sdr_dout_int ;
|
||||
|
||||
|
||||
// To meet the timing at read path, read data is registered w.r.t pad_sdram_clock and register back to sdram_clk
|
||||
// assumption, pad_sdram_clk is synhronous and delayed clock of sdram_clk.
|
||||
// register w.r.t pad sdram clk
|
||||
reg [SDR_DW-1:0] pad_sdr_din1;
|
||||
reg [SDR_DW-1:0] pad_sdr_din2;
|
||||
always@(posedge pad_clk) begin
|
||||
pad_sdr_din1 <= pad_sdr_din;
|
||||
end
|
||||
|
||||
always@(posedge clk) begin
|
||||
pad_sdr_din2 <= pad_sdr_din1;
|
||||
end
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
// Instantiate sdr_req_gen
|
||||
// This module takes requests from the app, chops them to burst booundaries
|
||||
// if wrap=0, decodes the bank and passe the request to bank_ctl
|
||||
|
||||
sdrc_req_gen #(.SDR_DW(SDR_DW) , .SDR_BW(SDR_BW)) u_req_gen (
|
||||
.clk (clk ),
|
||||
.reset_n (reset_n ),
|
||||
.cfg_colbits (cfg_colbits ),
|
||||
.sdr_width (sdr_width ),
|
||||
|
||||
/* Req to xfr_ctl */
|
||||
.r2x_idle (r2x_idle ),
|
||||
|
||||
/* Request from app */
|
||||
.req (app_req ),
|
||||
.req_id (4'b0 ),
|
||||
.req_addr (app_req_addr ),
|
||||
.req_len (app_req_len ),
|
||||
.req_wrap (app_req_wrap ),
|
||||
.req_wr_n (app_req_wr_n ),
|
||||
.req_ack (app_req_ack ),
|
||||
|
||||
/* Req to bank_ctl */
|
||||
.r2b_req (r2b_req ),
|
||||
.r2b_req_id (r2b_req_id ),
|
||||
.r2b_start (r2b_start ),
|
||||
.r2b_last (r2b_last ),
|
||||
.r2b_wrap (r2b_wrap ),
|
||||
.r2b_ba (r2b_ba ),
|
||||
.r2b_raddr (r2b_raddr ),
|
||||
.r2b_caddr (r2b_caddr ),
|
||||
.r2b_len (r2b_len ),
|
||||
.r2b_write (r2b_write ),
|
||||
.b2r_ack (b2r_ack ),
|
||||
.b2r_arb_ok (b2r_arb_ok )
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
// Instantiate sdr_bank_ctl
|
||||
// This module takes requests from sdr_req_gen, checks for page hit/miss and
|
||||
// issues precharge/activate commands and then passes the request to
|
||||
// sdr_xfr_ctl.
|
||||
|
||||
sdrc_bank_ctl #(.SDR_DW(SDR_DW) , .SDR_BW(SDR_BW)) u_bank_ctl (
|
||||
.clk (clk ),
|
||||
.reset_n (reset_n ),
|
||||
.a2b_req_depth (cfg_req_depth ),
|
||||
|
||||
/* Req from req_gen */
|
||||
.r2b_req (r2b_req ),
|
||||
.r2b_req_id (r2b_req_id ),
|
||||
.r2b_start (r2b_start ),
|
||||
.r2b_last (r2b_last ),
|
||||
.r2b_wrap (r2b_wrap ),
|
||||
.r2b_ba (r2b_ba ),
|
||||
.r2b_raddr (r2b_raddr ),
|
||||
.r2b_caddr (r2b_caddr ),
|
||||
.r2b_len (r2b_len ),
|
||||
.r2b_write (r2b_write ),
|
||||
.b2r_arb_ok (b2r_arb_ok ),
|
||||
.b2r_ack (b2r_ack ),
|
||||
|
||||
/* Transfer request to xfr_ctl */
|
||||
.b2x_idle (b2x_idle ),
|
||||
.b2x_req (b2x_req ),
|
||||
.b2x_start (b2x_start ),
|
||||
.b2x_last (b2x_last ),
|
||||
.b2x_wrap (b2x_wrap ),
|
||||
.b2x_id (b2x_id ),
|
||||
.b2x_ba (b2x_ba ),
|
||||
.b2x_addr (b2x_addr ),
|
||||
.b2x_len (b2x_len ),
|
||||
.b2x_cmd (b2x_cmd ),
|
||||
.x2b_ack (x2b_ack ),
|
||||
|
||||
/* Status from xfr_ctl */
|
||||
.b2x_tras_ok (b2x_tras_ok ),
|
||||
.x2b_refresh (x2b_refresh ),
|
||||
.x2b_pre_ok (x2b_pre_ok ),
|
||||
.x2b_act_ok (x2b_act_ok ),
|
||||
.x2b_rdok (x2b_rdok ),
|
||||
.x2b_wrok (x2b_wrok ),
|
||||
|
||||
/* for generate cuurent xfr address msb */
|
||||
.sdr_req_norm_dma_last(app_req_dma_last),
|
||||
.xfr_bank_sel (xfr_bank_sel ),
|
||||
|
||||
/* SDRAM Timing */
|
||||
.tras_delay (cfg_sdr_tras_d ),
|
||||
.trp_delay (cfg_sdr_trp_d ),
|
||||
.trcd_delay (cfg_sdr_trcd_d )
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
// Instantiate sdr_xfr_ctl
|
||||
// This module takes requests from sdr_bank_ctl, runs the transfer and
|
||||
// controls data flow to/from the app. At the end of the transfer it issues a
|
||||
// burst terminate if not at the end of a burst and another command to this
|
||||
// bank is not available.
|
||||
|
||||
sdrc_xfr_ctl #(.SDR_DW(SDR_DW) , .SDR_BW(SDR_BW)) u_xfr_ctl (
|
||||
.clk (clk ),
|
||||
.reset_n (reset_n ),
|
||||
|
||||
/* Transfer request from bank_ctl */
|
||||
.r2x_idle (r2x_idle ),
|
||||
.b2x_idle (b2x_idle ),
|
||||
.b2x_req (b2x_req ),
|
||||
.b2x_start (b2x_start ),
|
||||
.b2x_last (b2x_last ),
|
||||
.b2x_wrap (b2x_wrap ),
|
||||
.b2x_id (b2x_id ),
|
||||
.b2x_ba (b2x_ba ),
|
||||
.b2x_addr (b2x_addr ),
|
||||
.b2x_len (b2x_len ),
|
||||
.b2x_cmd (b2x_cmd ),
|
||||
.x2b_ack (x2b_ack ),
|
||||
|
||||
/* Status to bank_ctl, req_gen */
|
||||
.b2x_tras_ok (b2x_tras_ok ),
|
||||
.x2b_refresh (x2b_refresh ),
|
||||
.x2b_pre_ok (x2b_pre_ok ),
|
||||
.x2b_act_ok (x2b_act_ok ),
|
||||
.x2b_rdok (x2b_rdok ),
|
||||
.x2b_wrok (x2b_wrok ),
|
||||
|
||||
/* SDRAM I/O */
|
||||
.sdr_cs_n (sdr_cs_n ),
|
||||
.sdr_cke (sdr_cke ),
|
||||
.sdr_ras_n (sdr_ras_n ),
|
||||
.sdr_cas_n (sdr_cas_n ),
|
||||
.sdr_we_n (sdr_we_n ),
|
||||
.sdr_dqm (sdr_dqm ),
|
||||
.sdr_ba (sdr_ba ),
|
||||
.sdr_addr (sdr_addr ),
|
||||
.sdr_din (pad_sdr_din2 ),
|
||||
.sdr_dout (sdr_dout_int ),
|
||||
.sdr_den_n (sdr_den_n_int ),
|
||||
/* Data Flow to the app */
|
||||
.x2a_rdstart (x2a_rdstart ),
|
||||
.x2a_wrstart (x2a_wrstart ),
|
||||
.x2a_id (xfr_id ),
|
||||
.x2a_rdlast (x2a_rdlast ),
|
||||
.x2a_wrlast (x2a_wrlast ),
|
||||
.a2x_wrdt (a2x_wrdt ),
|
||||
.a2x_wren_n (a2x_wren_n ),
|
||||
.x2a_wrnext (x2a_wrnext ),
|
||||
.x2a_rddt (x2a_rddt ),
|
||||
.x2a_rdok (x2a_rdok ),
|
||||
.sdr_init_done (sdr_init_done ),
|
||||
|
||||
/* SDRAM Parameters */
|
||||
.sdram_enable (cfg_sdr_en ),
|
||||
.sdram_mode_reg (cfg_sdr_mode_reg ),
|
||||
|
||||
/* current xfr bank */
|
||||
.xfr_bank_sel (xfr_bank_sel ),
|
||||
|
||||
/* SDRAM Timing */
|
||||
.cas_latency (cfg_sdr_cas ),
|
||||
.trp_delay (cfg_sdr_trp_d ),
|
||||
.trcar_delay (cfg_sdr_trcar_d ),
|
||||
.twr_delay (cfg_sdr_twr_d ),
|
||||
.rfsh_time (cfg_sdr_rfsh ),
|
||||
.rfsh_rmax (cfg_sdr_rfmax )
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
// Instantiate sdr_bs_convert
|
||||
// This model handle the bus with transaltion from application layer to
|
||||
// 8/16/32 SDRAM Memory format
|
||||
// During Write Phase, this block split the data as per SDRAM Width
|
||||
// During Read Phase, This block does the re-packing based on SDRAM
|
||||
// Width
|
||||
//---------------------------------------------------------------------------
|
||||
sdrc_bs_convert #(.SDR_DW(SDR_DW) , .SDR_BW(SDR_BW)) u_bs_convert (
|
||||
.clk (clk ),
|
||||
.reset_n (reset_n ),
|
||||
.sdr_width (sdr_width ),
|
||||
|
||||
/* Control Signal from xfr ctrl */
|
||||
// Read Interface Inputs
|
||||
.x2a_rdstart (x2a_rdstart ),
|
||||
.x2a_rdlast (x2a_rdlast ),
|
||||
.x2a_rdok (x2a_rdok ),
|
||||
// Read Interface outputs
|
||||
.x2a_rddt (x2a_rddt ),
|
||||
|
||||
// Write Interface, Inputs
|
||||
.x2a_wrstart (x2a_wrstart ),
|
||||
.x2a_wrlast (x2a_wrlast ),
|
||||
.x2a_wrnext (x2a_wrnext ),
|
||||
|
||||
// Write Interface, Outputs
|
||||
.a2x_wrdt (a2x_wrdt ),
|
||||
.a2x_wren_n (a2x_wren_n ),
|
||||
|
||||
/* Control Signal from sdrc_bank_ctl */
|
||||
|
||||
/* Control Signal from/to to application i/f */
|
||||
.app_wr_data (app_wr_data ),
|
||||
.app_wr_en_n (app_wr_en_n ),
|
||||
.app_wr_next (app_wr_next_req ),
|
||||
.app_last_wr (app_last_wr ),
|
||||
.app_rd_data (app_rd_data ),
|
||||
.app_rd_valid (app_rd_valid ),
|
||||
.app_last_rd (app_last_rd )
|
||||
|
||||
);
|
||||
|
||||
endmodule // sdrc_core
|
31
lib/common/Driver/SDRAM_driver/core/sdrc_define.v
Normal file
31
lib/common/Driver/SDRAM_driver/core/sdrc_define.v
Normal file
@ -0,0 +1,31 @@
|
||||
|
||||
`define SDR_REQ_ID_W 4
|
||||
|
||||
`define SDR_RFSH_TIMER_W 12
|
||||
`define SDR_RFSH_ROW_CNT_W 3
|
||||
|
||||
// B2X Command
|
||||
|
||||
`define OP_PRE 2'b00
|
||||
`define OP_ACT 2'b01
|
||||
`define OP_RD 2'b10
|
||||
`define OP_WR 2'b11
|
||||
|
||||
// SDRAM Commands (CS_N, RAS_N, CAS_N, WE_N)
|
||||
|
||||
`define SDR_DESEL 4'b1111
|
||||
`define SDR_NOOP 4'b0111
|
||||
`define SDR_ACTIVATE 4'b0011
|
||||
`define SDR_READ 4'b0101
|
||||
`define SDR_WRITE 4'b0100
|
||||
`define SDR_BT 4'b0110
|
||||
`define SDR_PRECHARGE 4'b0010
|
||||
`define SDR_REFRESH 4'b0001
|
||||
`define SDR_MODE 4'b0000
|
||||
|
||||
`define ASIC 1'b1
|
||||
`define FPGA 1'b0
|
||||
`define TARGET_DESIGN `FPGA
|
||||
// 12 bit subtractor is not feasibile for FPGA, so changed to 6 bits
|
||||
`define REQ_BW (`TARGET_DESIGN == `FPGA) ? 6 : 12 // Request Width
|
||||
|
340
lib/common/Driver/SDRAM_driver/core/sdrc_req_gen.v
Normal file
340
lib/common/Driver/SDRAM_driver/core/sdrc_req_gen.v
Normal file
@ -0,0 +1,340 @@
|
||||
/*********************************************************************
|
||||
|
||||
SDRAM Controller Request Generation
|
||||
|
||||
This file is part of the sdram controller project
|
||||
http://www.opencores.org/cores/sdr_ctrl/
|
||||
|
||||
Description: SDRAM Controller Reguest Generation
|
||||
|
||||
Address Generation Based on cfg_colbits
|
||||
cfg_colbits= 2'b00
|
||||
Address[7:0] - Column Address
|
||||
Address[9:8] - Bank Address
|
||||
Address[22:10] - Row Address
|
||||
cfg_colbits= 2'b01
|
||||
Address[8:0] - Column Address
|
||||
Address[10:9] - Bank Address
|
||||
Address[23:11] - Row Address
|
||||
cfg_colbits= 2'b10
|
||||
Address[9:0] - Column Address
|
||||
Address[11:10] - Bank Address
|
||||
Address[24:12] - Row Address
|
||||
cfg_colbits= 2'b11
|
||||
Address[10:0] - Column Address
|
||||
Address[12:11] - Bank Address
|
||||
Address[25:13] - Row Address
|
||||
|
||||
The SDRAMs are operated in 4 beat burst mode.
|
||||
|
||||
If Wrap = 0;
|
||||
If the current burst cross the page boundary, then this block split the request
|
||||
into two coressponding change in address and request length
|
||||
|
||||
if the current burst cross the page boundar.
|
||||
This module takes requests from the memory controller,
|
||||
chops them to page boundaries if wrap=0,
|
||||
and passes the request to bank_ctl
|
||||
|
||||
Note: With Wrap = 0, each request from Application layer will be splited into two request,
|
||||
if the current burst cross the page boundary.
|
||||
|
||||
To Do:
|
||||
nothing
|
||||
|
||||
Author(s):
|
||||
- Dinesh Annayya, dinesha@opencores.org
|
||||
Version : 0.0 - 8th Jan 2012
|
||||
0.1 - 5th Feb 2012, column/row/bank address are register to improve the timing issue in FPGA synthesis
|
||||
|
||||
|
||||
|
||||
Copyright (C) 2000 Authors and OPENCORES.ORG
|
||||
|
||||
This source file may be used and distributed without
|
||||
restriction provided that this copyright statement is not
|
||||
removed from the file and that any derivative work contains
|
||||
the original copyright notice and the associated disclaimer.
|
||||
|
||||
This source file is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU Lesser General
|
||||
Public License as published by the Free Software Foundation;
|
||||
either version 2.1 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
This source is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the GNU Lesser General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this source; if not, download it
|
||||
from http://www.opencores.org/lgpl.shtml
|
||||
|
||||
*******************************************************************/
|
||||
|
||||
`include "sdrc_define.v"
|
||||
|
||||
module sdrc_req_gen (clk,
|
||||
reset_n,
|
||||
cfg_colbits,
|
||||
sdr_width,
|
||||
|
||||
/* Request from app */
|
||||
req, // Transfer Request
|
||||
req_id, // ID for this transfer
|
||||
req_addr, // SDRAM Address
|
||||
req_len, // Burst Length (in 32 bit words)
|
||||
req_wrap, // Wrap mode request (xfr_len = 4)
|
||||
req_wr_n, // 0 => Write request, 1 => read req
|
||||
req_ack, // Request has been accepted
|
||||
|
||||
/* Req to xfr_ctl */
|
||||
r2x_idle,
|
||||
|
||||
/* Req to bank_ctl */
|
||||
r2b_req, // request
|
||||
r2b_req_id, // ID
|
||||
r2b_start, // First chunk of burst
|
||||
r2b_last, // Last chunk of burst
|
||||
r2b_wrap, // Wrap Mode
|
||||
r2b_ba, // bank address
|
||||
r2b_raddr, // row address
|
||||
r2b_caddr, // col address
|
||||
r2b_len, // length
|
||||
r2b_write, // write request
|
||||
b2r_ack,
|
||||
b2r_arb_ok
|
||||
);
|
||||
|
||||
parameter APP_AW = 26; // Application Address Width
|
||||
parameter APP_DW = 32; // Application Data Width
|
||||
parameter APP_BW = 4; // Application Byte Width
|
||||
parameter APP_RW = 9; // Application Request Width
|
||||
|
||||
parameter SDR_DW = 16; // SDR Data Width
|
||||
parameter SDR_BW = 2; // SDR Byte Width
|
||||
|
||||
|
||||
input clk ;
|
||||
input reset_n ;
|
||||
input [1:0] cfg_colbits ; // 2'b00 - 8 Bit column address, 2'b01 - 9 Bit, 10 - 10 bit, 11 - 11Bits
|
||||
|
||||
/* Request from app */
|
||||
input req ; // Request
|
||||
input [`SDR_REQ_ID_W-1:0] req_id ; // Request ID
|
||||
input [APP_AW-1:0] req_addr ; // Request Address
|
||||
input [APP_RW-1:0] req_len ; // Request length
|
||||
input req_wr_n ; // 0 -Write, 1 - Read
|
||||
input req_wrap ; // 1 - Wrap the Address on page boundary
|
||||
output req_ack ; // Request Ack
|
||||
|
||||
/* Req to bank_ctl */
|
||||
output r2x_idle ;
|
||||
output r2b_req ; // Request
|
||||
output r2b_start ; // First Junk of the Burst Access
|
||||
output r2b_last ; // Last Junk of the Burst Access
|
||||
output r2b_write ; // 1 - Write, 0 - Read
|
||||
output r2b_wrap ; // 1 - Wrap the Address at the page boundary.
|
||||
output [`SDR_REQ_ID_W-1:0] r2b_req_id;
|
||||
output [1:0] r2b_ba ; // Bank Address
|
||||
output [12:0] r2b_raddr ; // Row Address
|
||||
output [12:0] r2b_caddr ; // Column Address
|
||||
output [`REQ_BW-1:0] r2b_len ; // Burst Length
|
||||
input b2r_ack ; // Request Ack
|
||||
input b2r_arb_ok ; // Bank controller fifo is not full and ready to accept the command
|
||||
//
|
||||
input [1:0] sdr_width; // 2'b00 - 32 Bit, 2'b01 - 16 Bit, 2'b1x - 8Bit
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
// Internal Nets
|
||||
|
||||
`define REQ_IDLE 2'b00
|
||||
`define REQ_ACTIVE 2'b01
|
||||
`define REQ_PAGE_WRAP 2'b10
|
||||
|
||||
reg [1:0] req_st, next_req_st;
|
||||
reg r2x_idle, req_ack, r2b_req, r2b_start,
|
||||
r2b_write, req_idle, req_ld, lcl_wrap;
|
||||
reg [`SDR_REQ_ID_W-1:0] r2b_req_id;
|
||||
reg [`REQ_BW-1:0] lcl_req_len;
|
||||
|
||||
wire r2b_last, page_ovflw;
|
||||
reg page_ovflw_r;
|
||||
wire [`REQ_BW-1:0] r2b_len, next_req_len;
|
||||
wire [12:0] max_r2b_len;
|
||||
reg [12:0] max_r2b_len_r;
|
||||
|
||||
reg [1:0] r2b_ba;
|
||||
reg [12:0] r2b_raddr;
|
||||
reg [12:0] r2b_caddr;
|
||||
|
||||
reg [APP_AW-1:0] curr_sdr_addr ;
|
||||
wire [APP_AW-1:0] next_sdr_addr ;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Generate the internal Adress and Burst length Based on sdram width
|
||||
//--------------------------------------------------------------------
|
||||
reg [APP_AW:0] req_addr_int;
|
||||
reg [APP_RW-1:0] req_len_int;
|
||||
|
||||
always @(*) begin
|
||||
if(sdr_width == 2'b00) begin // 32 Bit SDR Mode
|
||||
req_addr_int = {1'b0,req_addr};
|
||||
req_len_int = req_len;
|
||||
end else if(sdr_width == 2'b01) begin // 16 Bit SDR Mode
|
||||
// Changed the address and length to match the 16 bit SDR Mode
|
||||
req_addr_int = {req_addr,1'b0};
|
||||
req_len_int = {req_len,1'b0};
|
||||
end else begin // 8 Bit SDR Mode
|
||||
// Changed the address and length to match the 16 bit SDR Mode
|
||||
req_addr_int = {req_addr,2'b0};
|
||||
req_len_int = {req_len,2'b0};
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// Identify the page over flow.
|
||||
// Find the Maximum Burst length allowed from the selected column
|
||||
// address, If the requested burst length is more than the allowed Maximum
|
||||
// burst length, then we need to handle the bank cross over case and we
|
||||
// need to split the reuest.
|
||||
//
|
||||
assign max_r2b_len = (cfg_colbits == 2'b00) ? (12'h100 - {4'b0, req_addr_int[7:0]}) :
|
||||
(cfg_colbits == 2'b01) ? (12'h200 - {3'b0, req_addr_int[8:0]}) :
|
||||
(cfg_colbits == 2'b10) ? (12'h400 - {2'b0, req_addr_int[9:0]}) : (12'h800 - {1'b0, req_addr_int[10:0]});
|
||||
|
||||
|
||||
// If the wrap = 0 and current application burst length is crossing the page boundary,
|
||||
// then request will be split into two with corresponding change in request address and request length.
|
||||
//
|
||||
// If the wrap = 0 and current burst length is not crossing the page boundary,
|
||||
// then request from application layer will be transparently passed on the bank control block.
|
||||
|
||||
//
|
||||
// if the wrap = 1, then this block will not modify the request address and length.
|
||||
// The wrapping functionality will be handle by the bank control module and
|
||||
// column address will rewind back as follows XX -> FF ? 00 ? 1
|
||||
//
|
||||
// Note: With Wrap = 0, each request from Application layer will be spilited into two request,
|
||||
// if the current burst cross the page boundary.
|
||||
assign page_ovflw = ({1'b0, req_len_int} > max_r2b_len) ? ~r2b_wrap : 1'b0;
|
||||
|
||||
assign r2b_len = r2b_start ? ((page_ovflw_r) ? max_r2b_len_r : lcl_req_len) :
|
||||
lcl_req_len;
|
||||
|
||||
assign next_req_len = lcl_req_len - r2b_len;
|
||||
|
||||
assign next_sdr_addr = curr_sdr_addr + r2b_len;
|
||||
|
||||
|
||||
assign r2b_wrap = lcl_wrap;
|
||||
|
||||
assign r2b_last = (r2b_start & !page_ovflw_r) | (req_st == `REQ_PAGE_WRAP);
|
||||
//
|
||||
//
|
||||
//
|
||||
always @ (posedge clk) begin
|
||||
|
||||
page_ovflw_r <= (req_ack) ? page_ovflw: 'h0;
|
||||
|
||||
max_r2b_len_r <= (req_ack) ? max_r2b_len: 'h0;
|
||||
r2b_start <= (req_ack) ? 1'b1 :
|
||||
(b2r_ack) ? 1'b0 : r2b_start;
|
||||
|
||||
r2b_write <= (req_ack) ? ~req_wr_n : r2b_write;
|
||||
|
||||
r2b_req_id <= (req_ack) ? req_id : r2b_req_id;
|
||||
|
||||
lcl_wrap <= (req_ack) ? req_wrap : lcl_wrap;
|
||||
|
||||
lcl_req_len <= (req_ack) ? req_len_int :
|
||||
(req_ld) ? next_req_len : lcl_req_len;
|
||||
|
||||
curr_sdr_addr <= (req_ack) ? req_addr_int :
|
||||
(req_ld) ? next_sdr_addr : curr_sdr_addr;
|
||||
|
||||
end // always @ (posedge clk)
|
||||
|
||||
always @ (*) begin
|
||||
r2x_idle = 1'b0;
|
||||
req_idle = 1'b0;
|
||||
req_ack = 1'b0;
|
||||
req_ld = 1'b0;
|
||||
r2b_req = 1'b0;
|
||||
next_req_st = `REQ_IDLE;
|
||||
|
||||
case (req_st) // synopsys full_case parallel_case
|
||||
|
||||
`REQ_IDLE : begin
|
||||
r2x_idle = ~req;
|
||||
req_idle = 1'b1;
|
||||
req_ack = req & b2r_arb_ok;
|
||||
req_ld = 1'b0;
|
||||
r2b_req = 1'b0;
|
||||
next_req_st = (req & b2r_arb_ok) ? `REQ_ACTIVE : `REQ_IDLE;
|
||||
end // case: `REQ_IDLE
|
||||
|
||||
`REQ_ACTIVE : begin
|
||||
r2x_idle = 1'b0;
|
||||
req_idle = 1'b0;
|
||||
req_ack = 1'b0;
|
||||
req_ld = b2r_ack;
|
||||
r2b_req = 1'b1; // req_gen to bank_req
|
||||
next_req_st = (b2r_ack ) ? ((page_ovflw_r) ? `REQ_PAGE_WRAP :`REQ_IDLE) : `REQ_ACTIVE;
|
||||
end // case: `REQ_ACTIVE
|
||||
`REQ_PAGE_WRAP : begin
|
||||
r2x_idle = 1'b0;
|
||||
req_idle = 1'b0;
|
||||
req_ack = 1'b0;
|
||||
req_ld = b2r_ack;
|
||||
r2b_req = 1'b1; // req_gen to bank_req
|
||||
next_req_st = (b2r_ack) ? `REQ_IDLE : `REQ_PAGE_WRAP;
|
||||
end // case: `REQ_ACTIVE
|
||||
|
||||
endcase // case(req_st)
|
||||
|
||||
end // always @ (req_st or ....)
|
||||
|
||||
always @ (posedge clk)
|
||||
if (~reset_n) begin
|
||||
req_st <= `REQ_IDLE;
|
||||
end // if (~reset_n)
|
||||
else begin
|
||||
req_st <= next_req_st;
|
||||
end // else: !if(~reset_n)
|
||||
//
|
||||
// addrs bits for the bank, row and column
|
||||
//
|
||||
// Register row/column/bank to improve fpga timing issue
|
||||
wire [APP_AW-1:0] map_address ;
|
||||
|
||||
assign map_address = (req_ack) ? req_addr_int :
|
||||
(req_ld) ? next_sdr_addr : curr_sdr_addr;
|
||||
|
||||
always @ (posedge clk) begin
|
||||
// Bank Bits are always - 2 Bits
|
||||
r2b_ba <= (cfg_colbits == 2'b00) ? {map_address[9:8]} :
|
||||
(cfg_colbits == 2'b01) ? {map_address[10:9]} :
|
||||
(cfg_colbits == 2'b10) ? {map_address[11:10]} : map_address[12:11];
|
||||
|
||||
/********************
|
||||
* Colbits Mapping:
|
||||
* 2'b00 - 8 Bit
|
||||
* 2'b01 - 16 Bit
|
||||
* 2'b10 - 10 Bit
|
||||
* 2'b11 - 11 Bits
|
||||
************************/
|
||||
r2b_caddr <= (cfg_colbits == 2'b00) ? {5'b0, map_address[7:0]} :
|
||||
(cfg_colbits == 2'b01) ? {4'b0, map_address[8:0]} :
|
||||
(cfg_colbits == 2'b10) ? {3'b0, map_address[9:0]} : {2'b0, map_address[10:0]};
|
||||
|
||||
r2b_raddr <= (cfg_colbits == 2'b00) ? map_address[22:10] :
|
||||
(cfg_colbits == 2'b01) ? map_address[23:11] :
|
||||
(cfg_colbits == 2'b10) ? map_address[24:12] : map_address[25:13];
|
||||
end
|
||||
|
||||
endmodule // sdr_req_gen
|
772
lib/common/Driver/SDRAM_driver/core/sdrc_xfr_ctl.v
Normal file
772
lib/common/Driver/SDRAM_driver/core/sdrc_xfr_ctl.v
Normal file
@ -0,0 +1,772 @@
|
||||
/*********************************************************************
|
||||
|
||||
SDRAM Controller Transfer control
|
||||
|
||||
This file is part of the sdram controller project
|
||||
http://www.opencores.org/cores/sdr_ctrl/
|
||||
|
||||
Description: SDRAM Controller Transfer control
|
||||
|
||||
This module takes requests from sdrc_bank_ctl and runs the
|
||||
transfer. The input request is guaranteed to be in a bank that is
|
||||
precharged and activated. This block runs the transfer until a
|
||||
burst boundary is reached, then issues another read/write command
|
||||
to sequentially step thru memory if wrap=0, until the transfer is
|
||||
completed.
|
||||
|
||||
if a read transfer finishes and the caddr is not at a burst boundary
|
||||
a burst terminate command is issued unless another read/write or
|
||||
precharge to the same bank is pending.
|
||||
|
||||
if a write transfer finishes and the caddr is not at a burst boundary
|
||||
a burst terminate command is issued unless a read/write is pending.
|
||||
|
||||
If a refresh request is made, the bank_ctl will be held off until
|
||||
the number of refreshes requested are completed.
|
||||
|
||||
This block also handles SDRAM initialization.
|
||||
|
||||
|
||||
To Do:
|
||||
nothing
|
||||
|
||||
Author(s):
|
||||
- Dinesh Annayya, dinesha@opencores.org
|
||||
Version : 1.0 - 8th Jan 2012
|
||||
|
||||
|
||||
|
||||
Copyright (C) 2000 Authors and OPENCORES.ORG
|
||||
|
||||
This source file may be used and distributed without
|
||||
restriction provided that this copyright statement is not
|
||||
removed from the file and that any derivative work contains
|
||||
the original copyright notice and the associated disclaimer.
|
||||
|
||||
This source file is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU Lesser General
|
||||
Public License as published by the Free Software Foundation;
|
||||
either version 2.1 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
This source is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the GNU Lesser General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this source; if not, download it
|
||||
from http://www.opencores.org/lgpl.shtml
|
||||
|
||||
*******************************************************************/
|
||||
|
||||
`include "sdrc_define.v"
|
||||
|
||||
module sdrc_xfr_ctl (clk,
|
||||
reset_n,
|
||||
|
||||
/* Transfer request from bank_ctl */
|
||||
r2x_idle, // Req is idle
|
||||
b2x_idle, // All banks are idle
|
||||
b2x_req, // Req from bank_ctl
|
||||
b2x_start, // first chunk of transfer
|
||||
b2x_last, // last chunk of transfer
|
||||
b2x_id, // Transfer ID
|
||||
b2x_ba, // bank address
|
||||
b2x_addr, // row/col address
|
||||
b2x_len, // transfer length
|
||||
b2x_cmd, // transfer command
|
||||
b2x_wrap, // Wrap mode transfer
|
||||
x2b_ack, // command accepted
|
||||
|
||||
/* Status to bank_ctl, req_gen */
|
||||
b2x_tras_ok, // Tras for all banks expired
|
||||
x2b_refresh, // We did a refresh
|
||||
x2b_pre_ok, // OK to do a precharge (per bank)
|
||||
x2b_act_ok, // OK to do an activate
|
||||
x2b_rdok, // OK to do a read
|
||||
x2b_wrok, // OK to do a write
|
||||
|
||||
/* SDRAM I/O */
|
||||
sdr_cs_n,
|
||||
sdr_cke,
|
||||
sdr_ras_n,
|
||||
sdr_cas_n,
|
||||
sdr_we_n,
|
||||
sdr_dqm,
|
||||
sdr_ba,
|
||||
sdr_addr,
|
||||
sdr_din,
|
||||
sdr_dout,
|
||||
sdr_den_n,
|
||||
|
||||
/* Data Flow to the app */
|
||||
x2a_rdstart,
|
||||
x2a_wrstart,
|
||||
x2a_rdlast,
|
||||
x2a_wrlast,
|
||||
x2a_id,
|
||||
a2x_wrdt,
|
||||
a2x_wren_n,
|
||||
x2a_wrnext,
|
||||
x2a_rddt,
|
||||
x2a_rdok,
|
||||
sdr_init_done,
|
||||
|
||||
/* SDRAM Parameters */
|
||||
sdram_enable,
|
||||
sdram_mode_reg,
|
||||
|
||||
/* output for generate row address of the transfer */
|
||||
xfr_bank_sel,
|
||||
|
||||
/* SDRAM Timing */
|
||||
cas_latency,
|
||||
trp_delay, // Precharge to refresh delay
|
||||
trcar_delay, // Auto-refresh period
|
||||
twr_delay, // Write recovery delay
|
||||
rfsh_time, // time per row (31.25 or 15.6125 uS)
|
||||
rfsh_rmax); // Number of rows to rfsh at a time (<120uS)
|
||||
|
||||
parameter SDR_DW = 16; // SDR Data Width
|
||||
parameter SDR_BW = 2; // SDR Byte Width
|
||||
|
||||
|
||||
input clk, reset_n;
|
||||
|
||||
/* Req from bank_ctl */
|
||||
input b2x_req, b2x_start, b2x_last, b2x_tras_ok,
|
||||
b2x_wrap, r2x_idle, b2x_idle;
|
||||
input [`SDR_REQ_ID_W-1:0] b2x_id;
|
||||
input [1:0] b2x_ba;
|
||||
input [12:0] b2x_addr;
|
||||
input [`REQ_BW-1:0] b2x_len;
|
||||
input [1:0] b2x_cmd;
|
||||
output x2b_ack;
|
||||
|
||||
/* Status to bank_ctl */
|
||||
output [3:0] x2b_pre_ok;
|
||||
output x2b_refresh, x2b_act_ok, x2b_rdok,
|
||||
x2b_wrok;
|
||||
/* Data Flow to the app */
|
||||
output x2a_rdstart, x2a_wrstart, x2a_rdlast, x2a_wrlast;
|
||||
output [`SDR_REQ_ID_W-1:0] x2a_id;
|
||||
|
||||
input [SDR_DW-1:0] a2x_wrdt;
|
||||
input [SDR_BW-1:0] a2x_wren_n;
|
||||
output [SDR_DW-1:0] x2a_rddt;
|
||||
output x2a_wrnext, x2a_rdok, sdr_init_done;
|
||||
|
||||
/* Interface to SDRAMs */
|
||||
output sdr_cs_n, sdr_cke, sdr_ras_n, sdr_cas_n,
|
||||
sdr_we_n;
|
||||
output [SDR_BW-1:0] sdr_dqm;
|
||||
output [1:0] sdr_ba;
|
||||
output [12:0] sdr_addr;
|
||||
input [SDR_DW-1:0] sdr_din;
|
||||
output [SDR_DW-1:0] sdr_dout;
|
||||
output [SDR_BW-1:0] sdr_den_n;
|
||||
|
||||
output [1:0] xfr_bank_sel;
|
||||
|
||||
input sdram_enable;
|
||||
input [12:0] sdram_mode_reg;
|
||||
input [2:0] cas_latency;
|
||||
input [3:0] trp_delay, trcar_delay, twr_delay;
|
||||
input [`SDR_RFSH_TIMER_W-1 : 0] rfsh_time;
|
||||
input [`SDR_RFSH_ROW_CNT_W-1:0] rfsh_rmax;
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
// Internal Nets
|
||||
|
||||
`define XFR_IDLE 2'b00
|
||||
`define XFR_WRITE 2'b01
|
||||
`define XFR_READ 2'b10
|
||||
`define XFR_RDWT 2'b11
|
||||
|
||||
reg [1:0] xfr_st, next_xfr_st;
|
||||
reg [12:0] xfr_caddr;
|
||||
wire last_burst;
|
||||
wire x2a_rdstart, x2a_wrstart, x2a_rdlast, x2a_wrlast;
|
||||
reg l_start, l_last, l_wrap;
|
||||
wire [`SDR_REQ_ID_W-1:0] x2a_id;
|
||||
reg [`SDR_REQ_ID_W-1:0] l_id;
|
||||
wire [1:0] xfr_ba;
|
||||
reg [1:0] l_ba;
|
||||
wire [12:0] xfr_addr;
|
||||
wire [`REQ_BW-1:0] xfr_len, next_xfr_len;
|
||||
reg [`REQ_BW-1:0] l_len;
|
||||
|
||||
reg mgmt_idle, mgmt_req;
|
||||
reg [3:0] mgmt_cmd;
|
||||
reg [12:0] mgmt_addr;
|
||||
reg [1:0] mgmt_ba;
|
||||
|
||||
reg sel_mgmt, sel_b2x;
|
||||
reg cb_pre_ok, rdok, wrok, wr_next,
|
||||
rd_next, sdr_init_done, act_cmd, d_act_cmd;
|
||||
wire [3:0] b2x_sdr_cmd, xfr_cmd;
|
||||
reg [3:0] i_xfr_cmd;
|
||||
wire mgmt_ack, x2b_ack, b2x_read, b2x_write,
|
||||
b2x_prechg, d_rd_next, dt_next, xfr_end,
|
||||
rd_pipe_mt, ld_xfr, rd_last, d_rd_last,
|
||||
wr_last, l_xfr_end, rd_start, d_rd_start,
|
||||
wr_start, page_hit, burst_bdry, xfr_wrap,
|
||||
b2x_prechg_hit;
|
||||
reg [6:0] l_rd_next, l_rd_start, l_rd_last;
|
||||
|
||||
assign b2x_read = (b2x_cmd == `OP_RD) ? 1'b1 : 1'b0;
|
||||
|
||||
assign b2x_write = (b2x_cmd == `OP_WR) ? 1'b1 : 1'b0;
|
||||
|
||||
assign b2x_prechg = (b2x_cmd == `OP_PRE) ? 1'b1 : 1'b0;
|
||||
|
||||
assign b2x_sdr_cmd = (b2x_cmd == `OP_PRE) ? `SDR_PRECHARGE :
|
||||
(b2x_cmd == `OP_ACT) ? `SDR_ACTIVATE :
|
||||
(b2x_cmd == `OP_RD) ? `SDR_READ :
|
||||
(b2x_cmd == `OP_WR) ? `SDR_WRITE : `SDR_DESEL;
|
||||
|
||||
assign page_hit = (b2x_ba == l_ba) ? 1'b1 : 1'b0;
|
||||
|
||||
assign b2x_prechg_hit = b2x_prechg & page_hit;
|
||||
|
||||
assign xfr_cmd = (sel_mgmt) ? mgmt_cmd :
|
||||
(sel_b2x) ? b2x_sdr_cmd : i_xfr_cmd;
|
||||
|
||||
assign xfr_addr = (sel_mgmt) ? mgmt_addr :
|
||||
(sel_b2x) ? b2x_addr : xfr_caddr+1;
|
||||
|
||||
assign mgmt_ack = sel_mgmt;
|
||||
|
||||
assign x2b_ack = sel_b2x;
|
||||
|
||||
assign ld_xfr = sel_b2x & (b2x_read | b2x_write);
|
||||
|
||||
assign xfr_len = (ld_xfr) ? b2x_len : l_len;
|
||||
|
||||
//assign next_xfr_len = (l_xfr_end && !ld_xfr) ? l_len : xfr_len - 1;
|
||||
assign next_xfr_len = (ld_xfr) ? b2x_len :
|
||||
(l_xfr_end) ? l_len: l_len - 1;
|
||||
|
||||
assign d_rd_next = (cas_latency == 3'b001) ? l_rd_next[2] :
|
||||
(cas_latency == 3'b010) ? l_rd_next[3] :
|
||||
(cas_latency == 3'b011) ? l_rd_next[4] :
|
||||
(cas_latency == 3'b100) ? l_rd_next[5] :
|
||||
l_rd_next[6];
|
||||
|
||||
assign d_rd_last = (cas_latency == 3'b001) ? l_rd_last[2] :
|
||||
(cas_latency == 3'b010) ? l_rd_last[3] :
|
||||
(cas_latency == 3'b011) ? l_rd_last[4] :
|
||||
(cas_latency == 3'b100) ? l_rd_last[5] :
|
||||
l_rd_last[6];
|
||||
|
||||
assign d_rd_start = (cas_latency == 3'b001) ? l_rd_start[2] :
|
||||
(cas_latency == 3'b010) ? l_rd_start[3] :
|
||||
(cas_latency == 3'b011) ? l_rd_start[4] :
|
||||
(cas_latency == 3'b100) ? l_rd_start[5] :
|
||||
l_rd_start[6];
|
||||
|
||||
assign rd_pipe_mt = (cas_latency == 3'b001) ? ~|l_rd_next[1:0] :
|
||||
(cas_latency == 3'b010) ? ~|l_rd_next[2:0] :
|
||||
(cas_latency == 3'b011) ? ~|l_rd_next[3:0] :
|
||||
(cas_latency == 3'b100) ? ~|l_rd_next[4:0] :
|
||||
~|l_rd_next[5:0];
|
||||
|
||||
assign dt_next = wr_next | d_rd_next;
|
||||
|
||||
assign xfr_end = ~|xfr_len;
|
||||
|
||||
assign l_xfr_end = ~|(l_len-1);
|
||||
|
||||
assign rd_start = ld_xfr & b2x_read & b2x_start;
|
||||
|
||||
assign wr_start = ld_xfr & b2x_write & b2x_start;
|
||||
|
||||
assign rd_last = rd_next & last_burst & ~|xfr_len[`REQ_BW-1:1];
|
||||
|
||||
//assign wr_last = wr_next & last_burst & ~|xfr_len[APP_RW-1:1];
|
||||
|
||||
assign wr_last = last_burst & ~|xfr_len[`REQ_BW-1:1];
|
||||
|
||||
//assign xfr_ba = (ld_xfr) ? b2x_ba : l_ba;
|
||||
assign xfr_ba = (sel_mgmt) ? mgmt_ba :
|
||||
(sel_b2x) ? b2x_ba : l_ba;
|
||||
|
||||
assign xfr_wrap = (ld_xfr) ? b2x_wrap : l_wrap;
|
||||
|
||||
// assign burst_bdry = ~|xfr_caddr[2:0];
|
||||
wire [1:0] xfr_caddr_lsb = (xfr_caddr[1:0]+1);
|
||||
assign burst_bdry = ~|(xfr_caddr_lsb[1:0]);
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (~reset_n) begin
|
||||
xfr_caddr <= 13'b0;
|
||||
l_start <= 1'b0;
|
||||
l_last <= 1'b0;
|
||||
l_wrap <= 1'b0;
|
||||
l_id <= 0;
|
||||
l_ba <= 0;
|
||||
l_len <= 0;
|
||||
l_rd_next <= 7'b0;
|
||||
l_rd_start <= 7'b0;
|
||||
l_rd_last <= 7'b0;
|
||||
act_cmd <= 1'b0;
|
||||
d_act_cmd <= 1'b0;
|
||||
xfr_st <= `XFR_IDLE;
|
||||
end // if (~reset_n)
|
||||
|
||||
else begin
|
||||
xfr_caddr <= (ld_xfr) ? b2x_addr :
|
||||
(rd_next | wr_next) ? xfr_caddr + 1 : xfr_caddr;
|
||||
l_start <= (dt_next) ? 1'b0 :
|
||||
(ld_xfr) ? b2x_start : l_start;
|
||||
l_last <= (ld_xfr) ? b2x_last : l_last;
|
||||
l_wrap <= (ld_xfr) ? b2x_wrap : l_wrap;
|
||||
l_id <= (ld_xfr) ? b2x_id : l_id;
|
||||
l_ba <= (ld_xfr) ? b2x_ba : l_ba;
|
||||
l_len <= next_xfr_len;
|
||||
l_rd_next <= {l_rd_next[5:0], rd_next};
|
||||
l_rd_start <= {l_rd_start[5:0], rd_start};
|
||||
l_rd_last <= {l_rd_last[5:0], rd_last};
|
||||
act_cmd <= (xfr_cmd == `SDR_ACTIVATE) ? 1'b1 : 1'b0;
|
||||
d_act_cmd <= act_cmd;
|
||||
xfr_st <= next_xfr_st;
|
||||
end // else: !if(~reset_n)
|
||||
|
||||
end // always @ (posedge clk)
|
||||
|
||||
|
||||
always @ (*) begin
|
||||
case (xfr_st)
|
||||
|
||||
`XFR_IDLE : begin
|
||||
|
||||
sel_mgmt = mgmt_req;
|
||||
sel_b2x = ~mgmt_req & sdr_init_done & b2x_req;
|
||||
i_xfr_cmd = `SDR_DESEL;
|
||||
rd_next = ~mgmt_req & sdr_init_done & b2x_req & b2x_read;
|
||||
wr_next = ~mgmt_req & sdr_init_done & b2x_req & b2x_write;
|
||||
rdok = ~mgmt_req;
|
||||
cb_pre_ok = 1'b1;
|
||||
wrok = ~mgmt_req;
|
||||
next_xfr_st = (mgmt_req | ~sdr_init_done) ? `XFR_IDLE :
|
||||
(~b2x_req) ? `XFR_IDLE :
|
||||
(b2x_read) ? `XFR_READ :
|
||||
(b2x_write) ? `XFR_WRITE : `XFR_IDLE;
|
||||
|
||||
end // case: `XFR_IDLE
|
||||
|
||||
`XFR_READ : begin
|
||||
rd_next = ~l_xfr_end |
|
||||
l_xfr_end & ~mgmt_req & b2x_req & b2x_read;
|
||||
wr_next = 1'b0;
|
||||
rdok = l_xfr_end & ~mgmt_req;
|
||||
// Break the timing path for FPGA Based Design
|
||||
cb_pre_ok = (`TARGET_DESIGN == `FPGA) ? 1'b0 : l_xfr_end;
|
||||
wrok = 1'b0;
|
||||
sel_mgmt = 1'b0;
|
||||
|
||||
if (l_xfr_end) begin // end of transfer
|
||||
|
||||
if (~l_wrap) begin
|
||||
// Current transfer was not wrap mode, may need BT
|
||||
// If next cmd is a R or W or PRE to same bank allow
|
||||
// it else issue BT
|
||||
// This is a little pessimistic since BT is issued
|
||||
// for non-wrap mode transfers even if the transfer
|
||||
// ends on a burst boundary, but is felt to be of
|
||||
// minimal performance impact.
|
||||
|
||||
i_xfr_cmd = `SDR_BT;
|
||||
sel_b2x = b2x_req & ~mgmt_req & (b2x_read | b2x_prechg_hit);
|
||||
|
||||
end // if (~l_wrap)
|
||||
|
||||
else begin
|
||||
// Wrap mode transfer, by definition is end of burst
|
||||
// boundary
|
||||
|
||||
i_xfr_cmd = `SDR_DESEL;
|
||||
sel_b2x = b2x_req & ~mgmt_req & ~b2x_write;
|
||||
|
||||
end // else: !if(~l_wrap)
|
||||
|
||||
next_xfr_st = (sdr_init_done) ? ((b2x_req & ~mgmt_req & b2x_read) ? `XFR_READ : `XFR_RDWT) : `XFR_IDLE;
|
||||
|
||||
end // if (l_xfr_end)
|
||||
|
||||
else begin
|
||||
// Not end of transfer
|
||||
// If current transfer was not wrap mode and we are at
|
||||
// the start of a burst boundary issue another R cmd to
|
||||
// step sequemtially thru memory, ELSE,
|
||||
// issue precharge/activate commands from the bank control
|
||||
|
||||
i_xfr_cmd = (burst_bdry & ~l_wrap) ? `SDR_READ : `SDR_DESEL;
|
||||
sel_b2x = ~(burst_bdry & ~l_wrap) & b2x_req;
|
||||
next_xfr_st = `XFR_READ;
|
||||
|
||||
end // else: !if(l_xfr_end)
|
||||
|
||||
end // case: `XFR_READ
|
||||
|
||||
`XFR_RDWT : begin
|
||||
rd_next = ~mgmt_req & b2x_req & b2x_read;
|
||||
wr_next = rd_pipe_mt & ~mgmt_req & b2x_req & b2x_write;
|
||||
rdok = ~mgmt_req;
|
||||
cb_pre_ok = 1'b1;
|
||||
wrok = rd_pipe_mt & ~mgmt_req;
|
||||
|
||||
sel_mgmt = mgmt_req;
|
||||
|
||||
sel_b2x = ~mgmt_req & b2x_req;
|
||||
|
||||
i_xfr_cmd = `SDR_DESEL;
|
||||
|
||||
next_xfr_st = (~mgmt_req & b2x_req & b2x_read) ? `XFR_READ :
|
||||
(~rd_pipe_mt) ? `XFR_RDWT :
|
||||
(~mgmt_req & b2x_req & b2x_write) ? `XFR_WRITE :
|
||||
`XFR_IDLE;
|
||||
|
||||
end // case: `XFR_RDWT
|
||||
|
||||
`XFR_WRITE : begin
|
||||
rd_next = l_xfr_end & ~mgmt_req & b2x_req & b2x_read;
|
||||
wr_next = ~l_xfr_end |
|
||||
l_xfr_end & ~mgmt_req & b2x_req & b2x_write;
|
||||
rdok = l_xfr_end & ~mgmt_req;
|
||||
cb_pre_ok = 1'b0;
|
||||
wrok = l_xfr_end & ~mgmt_req;
|
||||
sel_mgmt = 1'b0;
|
||||
|
||||
if (l_xfr_end) begin // End of transfer
|
||||
|
||||
if (~l_wrap) begin
|
||||
// Current transfer was not wrap mode, may need BT
|
||||
// If next cmd is a R or W allow it else issue BT
|
||||
// This is a little pessimistic since BT is issued
|
||||
// for non-wrap mode transfers even if the transfer
|
||||
// ends on a burst boundary, but is felt to be of
|
||||
// minimal performance impact.
|
||||
|
||||
|
||||
sel_b2x = b2x_req & ~mgmt_req & (b2x_read | b2x_write);
|
||||
i_xfr_cmd = `SDR_BT;
|
||||
end // if (~l_wrap)
|
||||
|
||||
else begin
|
||||
// Wrap mode transfer, by definition is end of burst
|
||||
// boundary
|
||||
|
||||
sel_b2x = b2x_req & ~mgmt_req & ~b2x_prechg_hit;
|
||||
i_xfr_cmd = `SDR_DESEL;
|
||||
end // else: !if(~l_wrap)
|
||||
|
||||
next_xfr_st = (~mgmt_req & b2x_req & b2x_read) ? `XFR_READ :
|
||||
(~mgmt_req & b2x_req & b2x_write) ? `XFR_WRITE :
|
||||
`XFR_IDLE;
|
||||
|
||||
end // if (l_xfr_end)
|
||||
|
||||
else begin
|
||||
// Not end of transfer
|
||||
// If current transfer was not wrap mode and we are at
|
||||
// the start of a burst boundary issue another R cmd to
|
||||
// step sequemtially thru memory, ELSE,
|
||||
// issue precharge/activate commands from the bank control
|
||||
|
||||
if (burst_bdry & ~l_wrap) begin
|
||||
sel_b2x = 1'b0;
|
||||
i_xfr_cmd = `SDR_WRITE;
|
||||
end // if (burst_bdry & ~l_wrap)
|
||||
|
||||
else begin
|
||||
sel_b2x = b2x_req & ~mgmt_req;
|
||||
i_xfr_cmd = `SDR_DESEL;
|
||||
end // else: !if(burst_bdry & ~l_wrap)
|
||||
|
||||
next_xfr_st = `XFR_WRITE;
|
||||
end // else: !if(l_xfr_end)
|
||||
|
||||
end // case: `XFR_WRITE
|
||||
|
||||
endcase // case(xfr_st)
|
||||
|
||||
end // always @ (xfr_st or ...)
|
||||
|
||||
// signals to bank_ctl (x2b_refresh, x2b_act_ok, x2b_rdok, x2b_wrok,
|
||||
// x2b_pre_ok[3:0]
|
||||
|
||||
assign x2b_refresh = (xfr_cmd == `SDR_REFRESH) ? 1'b1 : 1'b0;
|
||||
|
||||
assign x2b_act_ok = ~act_cmd & ~d_act_cmd;
|
||||
|
||||
assign x2b_rdok = rdok;
|
||||
|
||||
assign x2b_wrok = wrok;
|
||||
|
||||
//assign x2b_pre_ok[0] = (l_ba == 2'b00) ? cb_pre_ok : 1'b1;
|
||||
//assign x2b_pre_ok[1] = (l_ba == 2'b01) ? cb_pre_ok : 1'b1;
|
||||
//assign x2b_pre_ok[2] = (l_ba == 2'b10) ? cb_pre_ok : 1'b1;
|
||||
//assign x2b_pre_ok[3] = (l_ba == 2'b11) ? cb_pre_ok : 1'b1;
|
||||
|
||||
assign x2b_pre_ok[0] = cb_pre_ok;
|
||||
assign x2b_pre_ok[1] = cb_pre_ok;
|
||||
assign x2b_pre_ok[2] = cb_pre_ok;
|
||||
assign x2b_pre_ok[3] = cb_pre_ok;
|
||||
assign last_burst = (ld_xfr) ? b2x_last : l_last;
|
||||
|
||||
/************************************************************************/
|
||||
// APP Data I/F
|
||||
|
||||
wire [SDR_DW-1:0] x2a_rddt;
|
||||
|
||||
//assign x2a_start = (ld_xfr) ? b2x_start : l_start;
|
||||
assign x2a_rdstart = d_rd_start;
|
||||
assign x2a_wrstart = wr_start;
|
||||
|
||||
assign x2a_rdlast = d_rd_last;
|
||||
assign x2a_wrlast = wr_last;
|
||||
|
||||
assign x2a_id = (ld_xfr) ? b2x_id : l_id;
|
||||
|
||||
assign x2a_rddt = sdr_din;
|
||||
|
||||
assign x2a_wrnext = wr_next;
|
||||
|
||||
assign x2a_rdok = d_rd_next;
|
||||
|
||||
/************************************************************************/
|
||||
// SDRAM I/F
|
||||
|
||||
reg sdr_cs_n, sdr_cke, sdr_ras_n, sdr_cas_n,
|
||||
sdr_we_n;
|
||||
reg [SDR_BW-1:0] sdr_dqm;
|
||||
reg [1:0] sdr_ba;
|
||||
reg [12:0] sdr_addr;
|
||||
reg [SDR_DW-1:0] sdr_dout;
|
||||
reg [SDR_BW-1:0] sdr_den_n;
|
||||
|
||||
always @ (posedge clk)
|
||||
if (~reset_n) begin
|
||||
sdr_cs_n <= 1'b1;
|
||||
sdr_cke <= 1'b1;
|
||||
sdr_ras_n <= 1'b1;
|
||||
sdr_cas_n <= 1'b1;
|
||||
sdr_we_n <= 1'b1;
|
||||
sdr_dqm <= {SDR_BW{1'b1}};
|
||||
sdr_den_n <= {SDR_BW{1'b1}};
|
||||
end // if (~reset_n)
|
||||
else begin
|
||||
sdr_cs_n <= xfr_cmd[3];
|
||||
sdr_ras_n <= xfr_cmd[2];
|
||||
sdr_cas_n <= xfr_cmd[1];
|
||||
sdr_we_n <= xfr_cmd[0];
|
||||
sdr_cke <= (xfr_st != `XFR_IDLE) ? 1'b1 :
|
||||
~(mgmt_idle & b2x_idle & r2x_idle);
|
||||
sdr_dqm <= (wr_next) ? a2x_wren_n : {SDR_BW{1'b0}};
|
||||
sdr_den_n <= (wr_next) ? {SDR_BW{1'b0}} : {SDR_BW{1'b1}};
|
||||
end // else: !if(~reset_n)
|
||||
|
||||
always @ (posedge clk) begin
|
||||
|
||||
if (~xfr_cmd[3]) begin
|
||||
sdr_addr <= xfr_addr;
|
||||
sdr_ba <= xfr_ba;
|
||||
end // if (~xfr_cmd[3])
|
||||
|
||||
sdr_dout <= (wr_next) ? a2x_wrdt : sdr_dout;
|
||||
|
||||
end // always @ (posedge clk)
|
||||
|
||||
/************************************************************************/
|
||||
// Refresh and Initialization
|
||||
|
||||
`define MGM_POWERUP 3'b000
|
||||
`define MGM_PRECHARGE 3'b001
|
||||
`define MGM_PCHWT 3'b010
|
||||
`define MGM_REFRESH 3'b011
|
||||
`define MGM_REFWT 3'b100
|
||||
`define MGM_MODE_REG 3'b101
|
||||
`define MGM_MODE_WT 3'b110
|
||||
`define MGM_ACTIVE 3'b111
|
||||
|
||||
reg [2:0] mgmt_st, next_mgmt_st;
|
||||
reg [3:0] tmr0, tmr0_d;
|
||||
reg [3:0] cntr1, cntr1_d;
|
||||
wire tmr0_tc, cntr1_tc, rfsh_timer_tc, ref_req, precharge_ok;
|
||||
reg ld_tmr0, ld_cntr1, dec_cntr1, set_sdr_init_done;
|
||||
reg [`SDR_RFSH_TIMER_W-1 : 0] rfsh_timer;
|
||||
reg [`SDR_RFSH_ROW_CNT_W-1:0] rfsh_row_cnt;
|
||||
|
||||
always @ (posedge clk)
|
||||
if (~reset_n) begin
|
||||
mgmt_st <= `MGM_POWERUP;
|
||||
tmr0 <= 4'b0;
|
||||
cntr1 <= 4'h7;
|
||||
rfsh_timer <= 0;
|
||||
rfsh_row_cnt <= 0;
|
||||
sdr_init_done <= 1'b0;
|
||||
end // if (~reset_n)
|
||||
else begin
|
||||
mgmt_st <= next_mgmt_st;
|
||||
tmr0 <= (ld_tmr0) ? tmr0_d :
|
||||
(~tmr0_tc) ? tmr0 - 1 : tmr0;
|
||||
cntr1 <= (ld_cntr1) ? cntr1_d :
|
||||
(dec_cntr1) ? cntr1 - 1 : cntr1;
|
||||
sdr_init_done <= (set_sdr_init_done | sdr_init_done) & sdram_enable;
|
||||
rfsh_timer <= (rfsh_timer_tc) ? 0 : rfsh_timer + 1;
|
||||
rfsh_row_cnt <= (~set_sdr_init_done) ? 0 :
|
||||
(rfsh_timer_tc) ? rfsh_row_cnt + 1 : rfsh_row_cnt;
|
||||
end // else: !if(~reset_n)
|
||||
|
||||
assign tmr0_tc = ~|tmr0;
|
||||
|
||||
assign cntr1_tc = ~|cntr1;
|
||||
|
||||
assign rfsh_timer_tc = (rfsh_timer == rfsh_time) ? 1'b1 : 1'b0;
|
||||
|
||||
assign ref_req = (rfsh_row_cnt >= rfsh_rmax) ? 1'b1 : 1'b0;
|
||||
|
||||
assign precharge_ok = cb_pre_ok & b2x_tras_ok;
|
||||
|
||||
assign xfr_bank_sel = l_ba;
|
||||
|
||||
always @ (mgmt_st or sdram_enable or mgmt_ack or trp_delay or tmr0_tc or
|
||||
cntr1_tc or trcar_delay or rfsh_row_cnt or ref_req or sdr_init_done
|
||||
or precharge_ok or sdram_mode_reg) begin
|
||||
|
||||
case (mgmt_st) // synopsys full_case parallel_case
|
||||
|
||||
`MGM_POWERUP : begin
|
||||
mgmt_idle = 1'b0;
|
||||
mgmt_req = 1'b0;
|
||||
mgmt_cmd = `SDR_DESEL;
|
||||
mgmt_ba = 2'b0;
|
||||
mgmt_addr = 13'h400; // A10 = 1 => all banks
|
||||
ld_tmr0 = 1'b0;
|
||||
tmr0_d = 4'b0;
|
||||
dec_cntr1 = 1'b0;
|
||||
ld_cntr1 = 1'b1;
|
||||
cntr1_d = 4'hf; // changed for sdrams with higher refresh cycles during initialization
|
||||
set_sdr_init_done = 1'b0;
|
||||
next_mgmt_st = (sdram_enable) ? `MGM_PRECHARGE : `MGM_POWERUP;
|
||||
end // case: `MGM_POWERUP
|
||||
|
||||
`MGM_PRECHARGE : begin // Precharge all banks
|
||||
mgmt_idle = 1'b0;
|
||||
mgmt_req = 1'b1;
|
||||
mgmt_cmd = (precharge_ok) ? `SDR_PRECHARGE : `SDR_DESEL;
|
||||
mgmt_ba = 2'b0;
|
||||
mgmt_addr = 13'h400; // A10 = 1 => all banks
|
||||
ld_tmr0 = mgmt_ack;
|
||||
tmr0_d = trp_delay;
|
||||
ld_cntr1 = 1'b0;
|
||||
cntr1_d = 4'h7;
|
||||
dec_cntr1 = 1'b0;
|
||||
set_sdr_init_done = 1'b0;
|
||||
next_mgmt_st = (precharge_ok & mgmt_ack) ? `MGM_PCHWT : `MGM_PRECHARGE;
|
||||
end // case: `MGM_PRECHARGE
|
||||
|
||||
`MGM_PCHWT : begin // Wait for Trp
|
||||
mgmt_idle = 1'b0;
|
||||
mgmt_req = 1'b1;
|
||||
mgmt_cmd = `SDR_DESEL;
|
||||
mgmt_ba = 2'b0;
|
||||
mgmt_addr = 13'h400; // A10 = 1 => all banks
|
||||
ld_tmr0 = 1'b0;
|
||||
tmr0_d = trp_delay;
|
||||
ld_cntr1 = 1'b0;
|
||||
cntr1_d = 4'b0;
|
||||
dec_cntr1 = 1'b0;
|
||||
set_sdr_init_done = 1'b0;
|
||||
next_mgmt_st = (tmr0_tc) ? `MGM_REFRESH : `MGM_PCHWT;
|
||||
end // case: `MGM_PRECHARGE
|
||||
|
||||
`MGM_REFRESH : begin // Refresh
|
||||
mgmt_idle = 1'b0;
|
||||
mgmt_req = 1'b1;
|
||||
mgmt_cmd = `SDR_REFRESH;
|
||||
mgmt_ba = 2'b0;
|
||||
mgmt_addr = 13'h400; // A10 = 1 => all banks
|
||||
ld_tmr0 = mgmt_ack;
|
||||
tmr0_d = trcar_delay;
|
||||
dec_cntr1 = mgmt_ack;
|
||||
ld_cntr1 = 1'b0;
|
||||
cntr1_d = 4'h7;
|
||||
set_sdr_init_done = 1'b0;
|
||||
next_mgmt_st = (mgmt_ack) ? `MGM_REFWT : `MGM_REFRESH;
|
||||
end // case: `MGM_REFRESH
|
||||
|
||||
`MGM_REFWT : begin // Wait for trcar
|
||||
mgmt_idle = 1'b0;
|
||||
mgmt_req = 1'b1;
|
||||
mgmt_cmd = `SDR_DESEL;
|
||||
mgmt_ba = 2'b0;
|
||||
mgmt_addr = 13'h400; // A10 = 1 => all banks
|
||||
ld_tmr0 = 1'b0;
|
||||
tmr0_d = trcar_delay;
|
||||
dec_cntr1 = 1'b0;
|
||||
ld_cntr1 = 1'b0;
|
||||
cntr1_d = 4'h7;
|
||||
set_sdr_init_done = 1'b0;
|
||||
next_mgmt_st = (~tmr0_tc) ? `MGM_REFWT :
|
||||
(~cntr1_tc) ? `MGM_REFRESH :
|
||||
(sdr_init_done) ? `MGM_ACTIVE : `MGM_MODE_REG;
|
||||
end // case: `MGM_REFWT
|
||||
|
||||
`MGM_MODE_REG : begin // Program mode Register & wait for
|
||||
mgmt_idle = 1'b0;
|
||||
mgmt_req = 1'b1;
|
||||
mgmt_cmd = `SDR_MODE;
|
||||
mgmt_ba = {1'b0, sdram_mode_reg[11]};
|
||||
mgmt_addr = sdram_mode_reg;
|
||||
ld_tmr0 = mgmt_ack;
|
||||
tmr0_d = 4'h7;
|
||||
dec_cntr1 = 1'b0;
|
||||
ld_cntr1 = 1'b0;
|
||||
cntr1_d = 4'h7;
|
||||
set_sdr_init_done = 1'b0;
|
||||
next_mgmt_st = (mgmt_ack) ? `MGM_MODE_WT : `MGM_MODE_REG;
|
||||
end // case: `MGM_MODE_REG
|
||||
|
||||
`MGM_MODE_WT : begin // Wait for tMRD
|
||||
mgmt_idle = 1'b0;
|
||||
mgmt_req = 1'b1;
|
||||
mgmt_cmd = `SDR_DESEL;
|
||||
mgmt_ba = 2'bx;
|
||||
mgmt_addr = 13'bx;
|
||||
ld_tmr0 = 1'b0;
|
||||
tmr0_d = 4'h7;
|
||||
dec_cntr1 = 1'b0;
|
||||
ld_cntr1 = 1'b0;
|
||||
cntr1_d = 4'h7;
|
||||
set_sdr_init_done = 1'b0;
|
||||
next_mgmt_st = (~tmr0_tc) ? `MGM_MODE_WT : `MGM_ACTIVE;
|
||||
end // case: `MGM_MODE_WT
|
||||
|
||||
`MGM_ACTIVE : begin // Wait for ref_req
|
||||
mgmt_idle = ~ref_req;
|
||||
mgmt_req = 1'b0;
|
||||
mgmt_cmd = `SDR_DESEL;
|
||||
mgmt_ba = 2'bx;
|
||||
mgmt_addr = 13'bx;
|
||||
ld_tmr0 = 1'b0;
|
||||
tmr0_d = 4'h7;
|
||||
dec_cntr1 = 1'b0;
|
||||
ld_cntr1 = ref_req;
|
||||
cntr1_d = rfsh_row_cnt;
|
||||
set_sdr_init_done = 1'b1;
|
||||
next_mgmt_st = (~sdram_enable) ? `MGM_POWERUP :
|
||||
(ref_req) ? `MGM_PRECHARGE : `MGM_ACTIVE;
|
||||
end // case: `MGM_MODE_WT
|
||||
|
||||
endcase // case(mgmt_st)
|
||||
|
||||
end // always @ (mgmt_st or ....)
|
||||
|
||||
|
||||
|
||||
endmodule // sdr_xfr_ctl
|
1728
lib/common/Driver/SDRAM_driver/model/IS42VM16400K.V
Normal file
1728
lib/common/Driver/SDRAM_driver/model/IS42VM16400K.V
Normal file
File diff suppressed because it is too large
Load Diff
1096
lib/common/Driver/SDRAM_driver/model/mt48lc2m32b2.v
Normal file
1096
lib/common/Driver/SDRAM_driver/model/mt48lc2m32b2.v
Normal file
File diff suppressed because it is too large
Load Diff
1624
lib/common/Driver/SDRAM_driver/model/mt48lc4m16.v
Normal file
1624
lib/common/Driver/SDRAM_driver/model/mt48lc4m16.v
Normal file
File diff suppressed because it is too large
Load Diff
1976
lib/common/Driver/SDRAM_driver/model/mt48lc4m32b2.v
Normal file
1976
lib/common/Driver/SDRAM_driver/model/mt48lc4m32b2.v
Normal file
File diff suppressed because it is too large
Load Diff
963
lib/common/Driver/SDRAM_driver/model/mt48lc8m16a2.v
Normal file
963
lib/common/Driver/SDRAM_driver/model/mt48lc8m16a2.v
Normal file
@ -0,0 +1,963 @@
|
||||
/****************************************************************************************
|
||||
*
|
||||
* File Name: MT48LC8M16A2.V
|
||||
* Version: 0.0f
|
||||
* Date: July 8th, 1999
|
||||
* Model: BUS Functional
|
||||
* Simulator: Model Technology (PC version 5.2e PE)
|
||||
*
|
||||
* Dependencies: None
|
||||
*
|
||||
* Author: Son P. Huynh
|
||||
* Email: sphuynh@micron.com
|
||||
* Phone: (208) 368-3825
|
||||
* Company: Micron Technology, Inc.
|
||||
* Model: MT48LC8M16A2 (2Meg x 16 x 4 Banks)
|
||||
*
|
||||
* Description: Micron 128Mb SDRAM Verilog model
|
||||
*
|
||||
* Limitation: - Doesn't check for 4096 cycle refresh
|
||||
*
|
||||
* Note: - Set simulator resolution to "ps" accuracy
|
||||
* - Set Debug = 0 to disable $display messages
|
||||
*
|
||||
* Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY
|
||||
* WHATSOEVER AND MICRON SPECIFICALLY DISCLAIMS ANY
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
|
||||
* A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT.
|
||||
*
|
||||
* Copyright © 1998 Micron Semiconductor Products, Inc.
|
||||
* All rights researved
|
||||
*
|
||||
* Rev Author Phone Date Changes
|
||||
* ---- ---------------------------- ---------- ---------------------------------------
|
||||
* 0.0f Son Huynh 208-368-3825 07/08/1999 - Fix tWR = 1 Clk + 7.5 ns (Auto)
|
||||
* Micron Technology Inc. - Fix tWR = 15 ns (Manual)
|
||||
* - Fix tRP (Autoprecharge to AutoRefresh)
|
||||
*
|
||||
* 0.0a Son Huynh 208-368-3825 05/13/1998 - First Release (from 64Mb rev 0.0e)
|
||||
* Micron Technology Inc.
|
||||
****************************************************************************************/
|
||||
|
||||
`timescale 1ns / 100ps
|
||||
|
||||
module mt48lc8m16a2 (Dq, Addr, Ba, Clk, Cke, Cs_n, Ras_n, Cas_n, We_n, Dqm);
|
||||
|
||||
parameter addr_bits = 12;
|
||||
parameter data_bits = 16;
|
||||
parameter col_bits = 9;
|
||||
parameter mem_sizes = 2097151; // 2 Meg
|
||||
|
||||
inout [data_bits - 1 : 0] Dq;
|
||||
input [addr_bits - 1 : 0] Addr;
|
||||
input [1 : 0] Ba;
|
||||
input Clk;
|
||||
input Cke;
|
||||
input Cs_n;
|
||||
input Ras_n;
|
||||
input Cas_n;
|
||||
input We_n;
|
||||
input [1 : 0] Dqm;
|
||||
|
||||
reg [data_bits - 1 : 0] Bank0 [0 : mem_sizes];
|
||||
reg [data_bits - 1 : 0] Bank1 [0 : mem_sizes];
|
||||
reg [data_bits - 1 : 0] Bank2 [0 : mem_sizes];
|
||||
reg [data_bits - 1 : 0] Bank3 [0 : mem_sizes];
|
||||
|
||||
reg [1 : 0] Bank_addr [0 : 3]; // Bank Address Pipeline
|
||||
reg [col_bits - 1 : 0] Col_addr [0 : 3]; // Column Address Pipeline
|
||||
reg [3 : 0] Command [0 : 3]; // Command Operation Pipeline
|
||||
reg [1 : 0] Dqm_reg0, Dqm_reg1; // DQM Operation Pipeline
|
||||
reg [addr_bits - 1 : 0] B0_row_addr, B1_row_addr, B2_row_addr, B3_row_addr;
|
||||
|
||||
reg [addr_bits - 1 : 0] Mode_reg;
|
||||
reg [data_bits - 1 : 0] Dq_reg, Dq_dqm;
|
||||
reg [col_bits - 1 : 0] Col_temp, Burst_counter;
|
||||
|
||||
reg Act_b0, Act_b1, Act_b2, Act_b3; // Bank Activate
|
||||
reg Pc_b0, Pc_b1, Pc_b2, Pc_b3; // Bank Precharge
|
||||
|
||||
reg [1 : 0] Bank_precharge [0 : 3]; // Precharge Command
|
||||
reg A10_precharge [0 : 3]; // Addr[10] = 1 (All banks)
|
||||
reg Auto_precharge [0 : 3]; // RW AutoPrecharge (Bank)
|
||||
reg Read_precharge [0 : 3]; // R AutoPrecharge
|
||||
reg Write_precharge [0 : 3]; // W AutoPrecharge
|
||||
integer Count_precharge [0 : 3]; // RW AutoPrecharge (Counter)
|
||||
reg RW_interrupt_read [0 : 3]; // RW Interrupt Read with Auto Precharge
|
||||
reg RW_interrupt_write [0 : 3]; // RW Interrupt Write with Auto Precharge
|
||||
|
||||
reg Data_in_enable;
|
||||
reg Data_out_enable;
|
||||
|
||||
reg [1 : 0] Bank, Previous_bank;
|
||||
reg [addr_bits - 1 : 0] Row;
|
||||
reg [col_bits - 1 : 0] Col, Col_brst;
|
||||
|
||||
// Internal system clock
|
||||
reg CkeZ, Sys_clk;
|
||||
|
||||
// Commands Decode
|
||||
wire Active_enable = ~Cs_n & ~Ras_n & Cas_n & We_n;
|
||||
wire Aref_enable = ~Cs_n & ~Ras_n & ~Cas_n & We_n;
|
||||
wire Burst_term = ~Cs_n & Ras_n & Cas_n & ~We_n;
|
||||
wire Mode_reg_enable = ~Cs_n & ~Ras_n & ~Cas_n & ~We_n;
|
||||
wire Prech_enable = ~Cs_n & ~Ras_n & Cas_n & ~We_n;
|
||||
wire Read_enable = ~Cs_n & Ras_n & ~Cas_n & We_n;
|
||||
wire Write_enable = ~Cs_n & Ras_n & ~Cas_n & ~We_n;
|
||||
|
||||
// Burst Length Decode
|
||||
wire Burst_length_1 = ~Mode_reg[2] & ~Mode_reg[1] & ~Mode_reg[0];
|
||||
wire Burst_length_2 = ~Mode_reg[2] & ~Mode_reg[1] & Mode_reg[0];
|
||||
wire Burst_length_4 = ~Mode_reg[2] & Mode_reg[1] & ~Mode_reg[0];
|
||||
wire Burst_length_8 = ~Mode_reg[2] & Mode_reg[1] & Mode_reg[0];
|
||||
|
||||
// CAS Latency Decode
|
||||
wire Cas_latency_2 = ~Mode_reg[6] & Mode_reg[5] & ~Mode_reg[4];
|
||||
wire Cas_latency_3 = ~Mode_reg[6] & Mode_reg[5] & Mode_reg[4];
|
||||
|
||||
// Write Burst Mode
|
||||
wire Write_burst_mode = Mode_reg[9];
|
||||
|
||||
reg Debug; // Debug messages : 1 = On
|
||||
wire Dq_chk = Sys_clk & Data_in_enable; // Check setup/hold time for DQ
|
||||
|
||||
assign Dq = Dq_reg; // DQ buffer
|
||||
|
||||
// Commands Operation
|
||||
`define ACT 0
|
||||
`define NOP 1
|
||||
`define READ 2
|
||||
`define READ_A 3
|
||||
`define WRITE 4
|
||||
`define WRITE_A 5
|
||||
`define PRECH 6
|
||||
`define A_REF 7
|
||||
`define BST 8
|
||||
`define LMR 9
|
||||
|
||||
// Timing Parameters for -75 (PC133) and CAS Latency = 2
|
||||
parameter tAC = 6.0;
|
||||
parameter tHZ = 7.0;
|
||||
parameter tOH = 2.7;
|
||||
parameter tMRD = 2.0; // 2 Clk Cycles
|
||||
parameter tRAS = 44.0;
|
||||
parameter tRC = 66.0;
|
||||
parameter tRCD = 20.0;
|
||||
parameter tRP = 20.0;
|
||||
parameter tRRD = 15.0;
|
||||
parameter tWRa = 7.5; // A2 Version - Auto precharge mode only (1 Clk + 7.5 ns)
|
||||
parameter tWRp = 15.0; // A2 Version - Precharge mode only (15 ns)
|
||||
|
||||
// Timing Check variable
|
||||
integer MRD_chk;
|
||||
integer WR_counter [0 : 3];
|
||||
time WR_chk [0 : 3];
|
||||
time RC_chk, RRD_chk;
|
||||
time RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3;
|
||||
time RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3;
|
||||
time RP_chk0, RP_chk1, RP_chk2, RP_chk3;
|
||||
|
||||
initial begin
|
||||
Debug = 1'b0;
|
||||
|
||||
Dq_reg = {data_bits{1'bz}};
|
||||
{Data_in_enable, Data_out_enable} = 0;
|
||||
{Act_b0, Act_b1, Act_b2, Act_b3} = 4'b0000;
|
||||
{Pc_b0, Pc_b1, Pc_b2, Pc_b3} = 4'b0000;
|
||||
{WR_chk[0], WR_chk[1], WR_chk[2], WR_chk[3]} = 0;
|
||||
{WR_counter[0], WR_counter[1], WR_counter[2], WR_counter[3]} = 0;
|
||||
{RW_interrupt_read[0], RW_interrupt_read[1], RW_interrupt_read[2], RW_interrupt_read[3]} = 0;
|
||||
{RW_interrupt_write[0], RW_interrupt_write[1], RW_interrupt_write[2], RW_interrupt_write[3]} = 0;
|
||||
{MRD_chk, RC_chk, RRD_chk} = 0;
|
||||
{RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3} = 0;
|
||||
{RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3} = 0;
|
||||
{RP_chk0, RP_chk1, RP_chk2, RP_chk3} = 0;
|
||||
$timeformat (-9, 0, " ns", 12);
|
||||
//$readmemh("bank0.txt", Bank0);
|
||||
//$readmemh("bank1.txt", Bank1);
|
||||
//$readmemh("bank2.txt", Bank2);
|
||||
//$readmemh("bank3.txt", Bank3);
|
||||
end
|
||||
|
||||
// System clock generator
|
||||
always begin
|
||||
@ (posedge Clk) begin
|
||||
Sys_clk = CkeZ;
|
||||
CkeZ = Cke;
|
||||
end
|
||||
@ (negedge Clk) begin
|
||||
Sys_clk = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @ (posedge Sys_clk) begin
|
||||
// Internal Commamd Pipelined
|
||||
Command[0] = Command[1];
|
||||
Command[1] = Command[2];
|
||||
Command[2] = Command[3];
|
||||
Command[3] = `NOP;
|
||||
|
||||
Col_addr[0] = Col_addr[1];
|
||||
Col_addr[1] = Col_addr[2];
|
||||
Col_addr[2] = Col_addr[3];
|
||||
Col_addr[3] = {col_bits{1'b0}};
|
||||
|
||||
Bank_addr[0] = Bank_addr[1];
|
||||
Bank_addr[1] = Bank_addr[2];
|
||||
Bank_addr[2] = Bank_addr[3];
|
||||
Bank_addr[3] = 2'b0;
|
||||
|
||||
Bank_precharge[0] = Bank_precharge[1];
|
||||
Bank_precharge[1] = Bank_precharge[2];
|
||||
Bank_precharge[2] = Bank_precharge[3];
|
||||
Bank_precharge[3] = 2'b0;
|
||||
|
||||
A10_precharge[0] = A10_precharge[1];
|
||||
A10_precharge[1] = A10_precharge[2];
|
||||
A10_precharge[2] = A10_precharge[3];
|
||||
A10_precharge[3] = 1'b0;
|
||||
|
||||
// Dqm pipeline for Read
|
||||
Dqm_reg0 = Dqm_reg1;
|
||||
Dqm_reg1 = Dqm;
|
||||
|
||||
// Read or Write with Auto Precharge Counter
|
||||
if (Auto_precharge[0] == 1'b1) begin
|
||||
Count_precharge[0] = Count_precharge[0] + 1;
|
||||
end
|
||||
if (Auto_precharge[1] == 1'b1) begin
|
||||
Count_precharge[1] = Count_precharge[1] + 1;
|
||||
end
|
||||
if (Auto_precharge[2] == 1'b1) begin
|
||||
Count_precharge[2] = Count_precharge[2] + 1;
|
||||
end
|
||||
if (Auto_precharge[3] == 1'b1) begin
|
||||
Count_precharge[3] = Count_precharge[3] + 1;
|
||||
end
|
||||
|
||||
// tMRD Counter
|
||||
MRD_chk = MRD_chk + 1;
|
||||
|
||||
// tWR Counter for Write
|
||||
WR_counter[0] = WR_counter[0] + 1;
|
||||
WR_counter[1] = WR_counter[1] + 1;
|
||||
WR_counter[2] = WR_counter[2] + 1;
|
||||
WR_counter[3] = WR_counter[3] + 1;
|
||||
|
||||
// Auto Refresh
|
||||
if (Aref_enable == 1'b1) begin
|
||||
if (Debug) $display ("at time %t AREF : Auto Refresh", $time);
|
||||
// Auto Refresh to Auto Refresh
|
||||
if ($time - RC_chk < tRC) begin
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRC violation during Auto Refresh", $time);
|
||||
end
|
||||
// Precharge to Auto Refresh
|
||||
if ($time - RP_chk0 < tRP || $time - RP_chk1 < tRP || $time - RP_chk2 < tRP || $time - RP_chk3 < tRP) begin
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRP violation during Auto Refresh", $time);
|
||||
end
|
||||
// Precharge to Refresh
|
||||
if (Pc_b0 == 1'b0 || Pc_b1 == 1'b0 || Pc_b2 == 1'b0 || Pc_b3 == 1'b0) begin
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: All banks must be Precharge before Auto Refresh", $time);
|
||||
end
|
||||
// Record Current tRC time
|
||||
RC_chk = $time;
|
||||
end
|
||||
|
||||
// Load Mode Register
|
||||
if (Mode_reg_enable == 1'b1) begin
|
||||
// Decode CAS Latency, Burst Length, Burst Type, and Write Burst Mode
|
||||
if (Pc_b0 == 1'b1 && Pc_b1 == 1'b1 && Pc_b2 == 1'b1 && Pc_b3 == 1'b1) begin
|
||||
Mode_reg = Addr;
|
||||
if (Debug) begin
|
||||
$display ("at time %t LMR : Load Mode Register", $time);
|
||||
// CAS Latency
|
||||
if (Addr[6 : 4] == 3'b010)
|
||||
$display (" CAS Latency = 2");
|
||||
else if (Addr[6 : 4] == 3'b011)
|
||||
$display (" CAS Latency = 3");
|
||||
else
|
||||
$display (" CAS Latency = Reserved");
|
||||
// Burst Length
|
||||
if (Addr[2 : 0] == 3'b000)
|
||||
$display (" Burst Length = 1");
|
||||
else if (Addr[2 : 0] == 3'b001)
|
||||
$display (" Burst Length = 2");
|
||||
else if (Addr[2 : 0] == 3'b010)
|
||||
$display (" Burst Length = 4");
|
||||
else if (Addr[2 : 0] == 3'b011)
|
||||
$display (" Burst Length = 8");
|
||||
else if (Addr[3 : 0] == 4'b0111)
|
||||
$display (" Burst Length = Full");
|
||||
else
|
||||
$display (" Burst Length = Reserved");
|
||||
// Burst Type
|
||||
if (Addr[3] == 1'b0)
|
||||
$display (" Burst Type = Sequential");
|
||||
else if (Addr[3] == 1'b1)
|
||||
$display (" Burst Type = Interleaved");
|
||||
else
|
||||
$display (" Burst Type = Reserved");
|
||||
// Write Burst Mode
|
||||
if (Addr[9] == 1'b0)
|
||||
$display (" Write Burst Mode = Programmed Burst Length");
|
||||
else if (Addr[9] == 1'b1)
|
||||
$display (" Write Burst Mode = Single Location Access");
|
||||
else
|
||||
$display (" Write Burst Mode = Reserved");
|
||||
end
|
||||
end else begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: all banks must be Precharge before Load Mode Register", $time);
|
||||
end
|
||||
// REF to LMR
|
||||
if ($time - RC_chk < tRC) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRC violation during Load Mode Register", $time);
|
||||
end
|
||||
// LMR to LMR
|
||||
if (MRD_chk < tMRD) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tMRD violation during Load Mode Register", $time);
|
||||
end
|
||||
MRD_chk = 0;
|
||||
end
|
||||
|
||||
// Active Block (Latch Bank Address and Row Address)
|
||||
if (Active_enable == 1'b1) begin
|
||||
if (Ba == 2'b00 && Pc_b0 == 1'b1) begin
|
||||
{Act_b0, Pc_b0} = 2'b10;
|
||||
B0_row_addr = Addr [addr_bits - 1 : 0];
|
||||
RCD_chk0 = $time;
|
||||
RAS_chk0 = $time;
|
||||
if (Debug) $display ("at time %t ACT : Bank = 0 Row = %d", $time, Addr);
|
||||
// Precharge to Activate Bank 0
|
||||
if ($time - RP_chk0 < tRP) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRP violation during Activate bank 0", $time);
|
||||
end
|
||||
end else if (Ba == 2'b01 && Pc_b1 == 1'b1) begin
|
||||
{Act_b1, Pc_b1} = 2'b10;
|
||||
B1_row_addr = Addr [addr_bits - 1 : 0];
|
||||
RCD_chk1 = $time;
|
||||
RAS_chk1 = $time;
|
||||
if (Debug) $display ("at time %t ACT : Bank = 1 Row = %d", $time, Addr);
|
||||
// Precharge to Activate Bank 1
|
||||
if ($time - RP_chk1 < tRP) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRP violation during Activate bank 1", $time);
|
||||
end
|
||||
end else if (Ba == 2'b10 && Pc_b2 == 1'b1) begin
|
||||
{Act_b2, Pc_b2} = 2'b10;
|
||||
B2_row_addr = Addr [addr_bits - 1 : 0];
|
||||
RCD_chk2 = $time;
|
||||
RAS_chk2 = $time;
|
||||
if (Debug) $display ("at time %t ACT : Bank = 2 Row = %d", $time, Addr);
|
||||
// Precharge to Activate Bank 2
|
||||
if ($time - RP_chk2 < tRP) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRP violation during Activate bank 2", $time);
|
||||
end
|
||||
end else if (Ba == 2'b11 && Pc_b3 == 1'b1) begin
|
||||
{Act_b3, Pc_b3} = 2'b10;
|
||||
B3_row_addr = Addr [addr_bits - 1 : 0];
|
||||
RCD_chk3 = $time;
|
||||
RAS_chk3 = $time;
|
||||
if (Debug) $display ("at time %t ACT : Bank = 3 Row = %d", $time, Addr);
|
||||
// Precharge to Activate Bank 3
|
||||
if ($time - RP_chk3 < tRP) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRP violation during Activate bank 3", $time);
|
||||
end
|
||||
end else if (Ba == 2'b00 && Pc_b0 == 1'b0) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: Bank 0 is not Precharged.", $time);
|
||||
end else if (Ba == 2'b01 && Pc_b1 == 1'b0) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: Bank 1 is not Precharged.", $time);
|
||||
end else if (Ba == 2'b10 && Pc_b2 == 1'b0) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: Bank 2 is not Precharged.", $time);
|
||||
end else if (Ba == 2'b11 && Pc_b3 == 1'b0) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: Bank 3 is not Precharged.", $time);
|
||||
end
|
||||
// Active Bank A to Active Bank B
|
||||
if ((Previous_bank != Ba) && ($time - RRD_chk < tRRD)) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRRD violation during Activate bank = %d", $time, Ba);
|
||||
end
|
||||
// Load Mode Register to Active
|
||||
if (MRD_chk < tMRD ) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tMRD violation during Activate bank = %d", $time, Ba);
|
||||
end
|
||||
// Auto Refresh to Activate
|
||||
if ($time - RC_chk < tRC) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRC violation during Activate bank = %d", $time, Ba);
|
||||
end
|
||||
// Record variables for checking violation
|
||||
RRD_chk = $time;
|
||||
Previous_bank = Ba;
|
||||
end
|
||||
|
||||
// Precharge Block
|
||||
if (Prech_enable == 1'b1) begin
|
||||
if (Addr[10] == 1'b1) begin
|
||||
{Pc_b0, Pc_b1, Pc_b2, Pc_b3} = 4'b1111;
|
||||
{Act_b0, Act_b1, Act_b2, Act_b3} = 4'b0000;
|
||||
RP_chk0 = $time;
|
||||
RP_chk1 = $time;
|
||||
RP_chk2 = $time;
|
||||
RP_chk3 = $time;
|
||||
if (Debug) $display ("at time %t PRE : Bank = ALL",$time);
|
||||
// Activate to Precharge all banks
|
||||
if (($time - RAS_chk0 < tRAS) || ($time - RAS_chk1 < tRAS) ||
|
||||
($time - RAS_chk2 < tRAS) || ($time - RAS_chk3 < tRAS)) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRAS violation during Precharge all bank", $time);
|
||||
end
|
||||
// tWR violation check for write
|
||||
if (($time - WR_chk[0] < tWRp) || ($time - WR_chk[1] < tWRp) ||
|
||||
($time - WR_chk[2] < tWRp) || ($time - WR_chk[3] < tWRp)) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tWR violation during Precharge all bank", $time);
|
||||
end
|
||||
end else if (Addr[10] == 1'b0) begin
|
||||
if (Ba == 2'b00) begin
|
||||
{Pc_b0, Act_b0} = 2'b10;
|
||||
RP_chk0 = $time;
|
||||
if (Debug) $display ("at time %t PRE : Bank = 0",$time);
|
||||
// Activate to Precharge Bank 0
|
||||
if ($time - RAS_chk0 < tRAS) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRAS violation during Precharge bank 0", $time);
|
||||
end
|
||||
end else if (Ba == 2'b01) begin
|
||||
{Pc_b1, Act_b1} = 2'b10;
|
||||
RP_chk1 = $time;
|
||||
if (Debug) $display ("at time %t PRE : Bank = 1",$time);
|
||||
// Activate to Precharge Bank 1
|
||||
if ($time - RAS_chk1 < tRAS) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRAS violation during Precharge bank 1", $time);
|
||||
end
|
||||
end else if (Ba == 2'b10) begin
|
||||
{Pc_b2, Act_b2} = 2'b10;
|
||||
RP_chk2 = $time;
|
||||
if (Debug) $display ("at time %t PRE : Bank = 2",$time);
|
||||
// Activate to Precharge Bank 2
|
||||
if ($time - RAS_chk2 < tRAS) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRAS violation during Precharge bank 2", $time);
|
||||
end
|
||||
end else if (Ba == 2'b11) begin
|
||||
{Pc_b3, Act_b3} = 2'b10;
|
||||
RP_chk3 = $time;
|
||||
if (Debug) $display ("at time %t PRE : Bank = 3",$time);
|
||||
// Activate to Precharge Bank 3
|
||||
if ($time - RAS_chk3 < tRAS) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRAS violation during Precharge bank 3", $time);
|
||||
end
|
||||
end
|
||||
// tWR violation check for write
|
||||
if ($time - WR_chk[Ba] < tWRp) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tWR violation during Precharge bank %d", $time, Ba);
|
||||
end
|
||||
end
|
||||
// Terminate a Write Immediately (if same bank or all banks)
|
||||
if (Data_in_enable == 1'b1 && (Bank == Ba || Addr[10] == 1'b1)) begin
|
||||
Data_in_enable = 1'b0;
|
||||
end
|
||||
// Precharge Command Pipeline for Read
|
||||
if (Cas_latency_3 == 1'b1) begin
|
||||
Command[2] = `PRECH;
|
||||
Bank_precharge[2] = Ba;
|
||||
A10_precharge[2] = Addr[10];
|
||||
end else if (Cas_latency_2 == 1'b1) begin
|
||||
Command[1] = `PRECH;
|
||||
Bank_precharge[1] = Ba;
|
||||
A10_precharge[1] = Addr[10];
|
||||
end
|
||||
end
|
||||
|
||||
// Burst terminate
|
||||
if (Burst_term == 1'b1) begin
|
||||
// Terminate a Write Immediately
|
||||
if (Data_in_enable == 1'b1) begin
|
||||
Data_in_enable = 1'b0;
|
||||
end
|
||||
// Terminate a Read Depend on CAS Latency
|
||||
if (Cas_latency_3 == 1'b1) begin
|
||||
Command[2] = `BST;
|
||||
end else if (Cas_latency_2 == 1'b1) begin
|
||||
Command[1] = `BST;
|
||||
end
|
||||
if (Debug) $display ("at time %t BST : Burst Terminate",$time);
|
||||
end
|
||||
|
||||
// Read, Write, Column Latch
|
||||
if (Read_enable == 1'b1 || Write_enable == 1'b1) begin
|
||||
// Check to see if bank is open (ACT)
|
||||
if ((Ba == 2'b00 && Pc_b0 == 1'b1) || (Ba == 2'b01 && Pc_b1 == 1'b1) ||
|
||||
(Ba == 2'b10 && Pc_b2 == 1'b1) || (Ba == 2'b11 && Pc_b3 == 1'b1)) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display("at time %t ERROR: Cannot Read or Write - Bank %d is not Activated", $time, Ba);
|
||||
end
|
||||
// Activate to Read or Write
|
||||
if ((Ba == 2'b00) && ($time - RCD_chk0 < tRCD))
|
||||
begin
|
||||
//->tb.test_control.error_detected;
|
||||
$display("at time %t ERROR: tRCD violation during Read or Write to Bank 0", $time);
|
||||
end
|
||||
|
||||
if ((Ba == 2'b01) && ($time - RCD_chk1 < tRCD))
|
||||
begin
|
||||
//->tb.test_control.error_detected;
|
||||
$display("at time %t ERROR: tRCD violation during Read or Write to Bank 1", $time);
|
||||
end
|
||||
if ((Ba == 2'b10) && ($time - RCD_chk2 < tRCD))
|
||||
begin
|
||||
//->tb.test_control.error_detected;
|
||||
$display("at time %t ERROR: tRCD violation during Read or Write to Bank 2", $time);
|
||||
end
|
||||
if ((Ba == 2'b11) && ($time - RCD_chk3 < tRCD))
|
||||
begin
|
||||
//->tb.test_control.error_detected;
|
||||
$display("at time %t ERROR: tRCD violation during Read or Write to Bank 3", $time);
|
||||
end
|
||||
// Read Command
|
||||
if (Read_enable == 1'b1) begin
|
||||
// CAS Latency pipeline
|
||||
if (Cas_latency_3 == 1'b1) begin
|
||||
if (Addr[10] == 1'b1) begin
|
||||
Command[2] = `READ_A;
|
||||
end else begin
|
||||
Command[2] = `READ;
|
||||
end
|
||||
Col_addr[2] = Addr;
|
||||
Bank_addr[2] = Ba;
|
||||
end else if (Cas_latency_2 == 1'b1) begin
|
||||
if (Addr[10] == 1'b1) begin
|
||||
Command[1] = `READ_A;
|
||||
end else begin
|
||||
Command[1] = `READ;
|
||||
end
|
||||
Col_addr[1] = Addr;
|
||||
Bank_addr[1] = Ba;
|
||||
end
|
||||
|
||||
// Read interrupt Write (terminate Write immediately)
|
||||
if (Data_in_enable == 1'b1) begin
|
||||
Data_in_enable = 1'b0;
|
||||
end
|
||||
|
||||
// Write Command
|
||||
end else if (Write_enable == 1'b1) begin
|
||||
if (Addr[10] == 1'b1) begin
|
||||
Command[0] = `WRITE_A;
|
||||
end else begin
|
||||
Command[0] = `WRITE;
|
||||
end
|
||||
Col_addr[0] = Addr;
|
||||
Bank_addr[0] = Ba;
|
||||
|
||||
// Write interrupt Write (terminate Write immediately)
|
||||
if (Data_in_enable == 1'b1) begin
|
||||
Data_in_enable = 1'b0;
|
||||
end
|
||||
|
||||
// Write interrupt Read (terminate Read immediately)
|
||||
if (Data_out_enable == 1'b1) begin
|
||||
Data_out_enable = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// Interrupting a Write with Autoprecharge
|
||||
if (Auto_precharge[Bank] == 1'b1 && Write_precharge[Bank] == 1'b1) begin
|
||||
RW_interrupt_write[Bank] = 1'b1;
|
||||
if (Debug) $display ("at time %t NOTE : Read/Write Bank %d interrupt Write Bank %d with Autoprecharge", $time, Ba, Bank);
|
||||
end
|
||||
|
||||
// Interrupting a Read with Autoprecharge
|
||||
if (Auto_precharge[Bank] == 1'b1 && Read_precharge[Bank] == 1'b1) begin
|
||||
RW_interrupt_read[Bank] = 1'b1;
|
||||
if (Debug) $display ("at time %t NOTE : Read/Write Bank %d interrupt Read Bank %d with Autoprecharge", $time, Ba, Bank);
|
||||
end
|
||||
|
||||
// Read or Write with Auto Precharge
|
||||
if (Addr[10] == 1'b1) begin
|
||||
Auto_precharge[Ba] = 1'b1;
|
||||
Count_precharge[Ba] = 0;
|
||||
if (Read_enable == 1'b1) begin
|
||||
Read_precharge[Ba] = 1'b1;
|
||||
end else if (Write_enable == 1'b1) begin
|
||||
Write_precharge[Ba] = 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Read with Auto Precharge Calculation
|
||||
// The device start internal precharge:
|
||||
// 1. CAS Latency - 1 cycles before last burst
|
||||
// and 2. Meet minimum tRAS requirement
|
||||
// or 3. Interrupt by a Read or Write (with or without AutoPrecharge)
|
||||
if ((Auto_precharge[0] == 1'b1) && (Read_precharge[0] == 1'b1)) begin
|
||||
if ((($time - RAS_chk0 >= tRAS) && // Case 2
|
||||
((Burst_length_1 == 1'b1 && Count_precharge[0] >= 1) || // Case 1
|
||||
(Burst_length_2 == 1'b1 && Count_precharge[0] >= 2) ||
|
||||
(Burst_length_4 == 1'b1 && Count_precharge[0] >= 4) ||
|
||||
(Burst_length_8 == 1'b1 && Count_precharge[0] >= 8))) ||
|
||||
(RW_interrupt_read[0] == 1'b1)) begin // Case 3
|
||||
Pc_b0 = 1'b1;
|
||||
Act_b0 = 1'b0;
|
||||
RP_chk0 = $time;
|
||||
Auto_precharge[0] = 1'b0;
|
||||
Read_precharge[0] = 1'b0;
|
||||
RW_interrupt_read[0] = 1'b0;
|
||||
if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 0", $time);
|
||||
end
|
||||
end
|
||||
if ((Auto_precharge[1] == 1'b1) && (Read_precharge[1] == 1'b1)) begin
|
||||
if ((($time - RAS_chk1 >= tRAS) &&
|
||||
((Burst_length_1 == 1'b1 && Count_precharge[1] >= 1) ||
|
||||
(Burst_length_2 == 1'b1 && Count_precharge[1] >= 2) ||
|
||||
(Burst_length_4 == 1'b1 && Count_precharge[1] >= 4) ||
|
||||
(Burst_length_8 == 1'b1 && Count_precharge[1] >= 8))) ||
|
||||
(RW_interrupt_read[1] == 1'b1)) begin
|
||||
Pc_b1 = 1'b1;
|
||||
Act_b1 = 1'b0;
|
||||
RP_chk1 = $time;
|
||||
Auto_precharge[1] = 1'b0;
|
||||
Read_precharge[1] = 1'b0;
|
||||
RW_interrupt_read[1] = 1'b0;
|
||||
if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 1", $time);
|
||||
end
|
||||
end
|
||||
if ((Auto_precharge[2] == 1'b1) && (Read_precharge[2] == 1'b1)) begin
|
||||
if ((($time - RAS_chk2 >= tRAS) &&
|
||||
((Burst_length_1 == 1'b1 && Count_precharge[2] >= 1) ||
|
||||
(Burst_length_2 == 1'b1 && Count_precharge[2] >= 2) ||
|
||||
(Burst_length_4 == 1'b1 && Count_precharge[2] >= 4) ||
|
||||
(Burst_length_8 == 1'b1 && Count_precharge[2] >= 8))) ||
|
||||
(RW_interrupt_read[2] == 1'b1)) begin
|
||||
Pc_b2 = 1'b1;
|
||||
Act_b2 = 1'b0;
|
||||
RP_chk2 = $time;
|
||||
Auto_precharge[2] = 1'b0;
|
||||
Read_precharge[2] = 1'b0;
|
||||
RW_interrupt_read[2] = 1'b0;
|
||||
if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 2", $time);
|
||||
end
|
||||
end
|
||||
if ((Auto_precharge[3] == 1'b1) && (Read_precharge[3] == 1'b1)) begin
|
||||
if ((($time - RAS_chk3 >= tRAS) &&
|
||||
((Burst_length_1 == 1'b1 && Count_precharge[3] >= 1) ||
|
||||
(Burst_length_2 == 1'b1 && Count_precharge[3] >= 2) ||
|
||||
(Burst_length_4 == 1'b1 && Count_precharge[3] >= 4) ||
|
||||
(Burst_length_8 == 1'b1 && Count_precharge[3] >= 8))) ||
|
||||
(RW_interrupt_read[3] == 1'b1)) begin
|
||||
Pc_b3 = 1'b1;
|
||||
Act_b3 = 1'b0;
|
||||
RP_chk3 = $time;
|
||||
Auto_precharge[3] = 1'b0;
|
||||
Read_precharge[3] = 1'b0;
|
||||
RW_interrupt_read[3] = 1'b0;
|
||||
if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 3", $time);
|
||||
end
|
||||
end
|
||||
|
||||
// Internal Precharge or Bst
|
||||
if (Command[0] == `PRECH) begin // Precharge terminate a read with same bank or all banks
|
||||
if (Bank_precharge[0] == Bank || A10_precharge[0] == 1'b1) begin
|
||||
if (Data_out_enable == 1'b1) begin
|
||||
Data_out_enable = 1'b0;
|
||||
end
|
||||
end
|
||||
end else if (Command[0] == `BST) begin // BST terminate a read to current bank
|
||||
if (Data_out_enable == 1'b1) begin
|
||||
Data_out_enable = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
if (Data_out_enable == 1'b0) begin
|
||||
Dq_reg <= #tOH {data_bits{1'bz}};
|
||||
end
|
||||
|
||||
// Detect Read or Write command
|
||||
if (Command[0] == `READ || Command[0] == `READ_A) begin
|
||||
Bank = Bank_addr[0];
|
||||
Col = Col_addr[0];
|
||||
Col_brst = Col_addr[0];
|
||||
if (Bank_addr[0] == 2'b00) begin
|
||||
Row = B0_row_addr;
|
||||
end else if (Bank_addr[0] == 2'b01) begin
|
||||
Row = B1_row_addr;
|
||||
end else if (Bank_addr[0] == 2'b10) begin
|
||||
Row = B2_row_addr;
|
||||
end else if (Bank_addr[0] == 2'b11) begin
|
||||
Row = B3_row_addr;
|
||||
end
|
||||
Burst_counter = 0;
|
||||
Data_in_enable = 1'b0;
|
||||
Data_out_enable = 1'b1;
|
||||
end else if (Command[0] == `WRITE || Command[0] == `WRITE_A) begin
|
||||
Bank = Bank_addr[0];
|
||||
Col = Col_addr[0];
|
||||
Col_brst = Col_addr[0];
|
||||
if (Bank_addr[0] == 2'b00) begin
|
||||
Row = B0_row_addr;
|
||||
end else if (Bank_addr[0] == 2'b01) begin
|
||||
Row = B1_row_addr;
|
||||
end else if (Bank_addr[0] == 2'b10) begin
|
||||
Row = B2_row_addr;
|
||||
end else if (Bank_addr[0] == 2'b11) begin
|
||||
Row = B3_row_addr;
|
||||
end
|
||||
Burst_counter = 0;
|
||||
Data_in_enable = 1'b1;
|
||||
Data_out_enable = 1'b0;
|
||||
end
|
||||
|
||||
// DQ buffer (Driver/Receiver)
|
||||
if (Data_in_enable == 1'b1) begin // Writing Data to Memory
|
||||
// Array buffer
|
||||
if (Bank == 2'b00) Dq_dqm [15 : 0] = Bank0 [{Row, Col}];
|
||||
if (Bank == 2'b01) Dq_dqm [15 : 0] = Bank1 [{Row, Col}];
|
||||
if (Bank == 2'b10) Dq_dqm [15 : 0] = Bank2 [{Row, Col}];
|
||||
if (Bank == 2'b11) Dq_dqm [15 : 0] = Bank3 [{Row, Col}];
|
||||
// Dqm operation
|
||||
if (Dqm[0] == 1'b0) Dq_dqm [ 7 : 0] = Dq [ 7 : 0];
|
||||
if (Dqm[1] == 1'b0) Dq_dqm [15 : 8] = Dq [15 : 8];
|
||||
// Write to memory
|
||||
if (Bank == 2'b00) Bank0 [{Row, Col}] = Dq_dqm [15 : 0];
|
||||
if (Bank == 2'b01) Bank1 [{Row, Col}] = Dq_dqm [15 : 0];
|
||||
if (Bank == 2'b10) Bank2 [{Row, Col}] = Dq_dqm [15 : 0];
|
||||
if (Bank == 2'b11) Bank3 [{Row, Col}] = Dq_dqm [15 : 0];
|
||||
// Output result
|
||||
if (Dqm == 2'b11) begin
|
||||
if (Debug) $display("at time %t WRITE: Bank = %d Row = %d, Col = %d, Data = Hi-Z due to DQM", $time, Bank, Row, Col);
|
||||
end else begin
|
||||
if (Debug) $display("at time %t WRITE: Bank = %d Row = %d, Col = %d, Data = %h, Dqm = %b", $time, Bank, Row, Col, Dq_dqm, Dqm);
|
||||
// Record tWR time and reset counter
|
||||
WR_chk [Bank] = $time;
|
||||
WR_counter [Bank] = 0;
|
||||
end
|
||||
// Advance burst counter subroutine
|
||||
#tHZ Burst;
|
||||
end else if (Data_out_enable == 1'b1) begin // Reading Data from Memory
|
||||
// Array buffer
|
||||
if (Bank == 2'b00) Dq_dqm [15 : 0] = Bank0 [{Row, Col}];
|
||||
if (Bank == 2'b01) Dq_dqm [15 : 0] = Bank1 [{Row, Col}];
|
||||
if (Bank == 2'b10) Dq_dqm [15 : 0] = Bank2 [{Row, Col}];
|
||||
if (Bank == 2'b11) Dq_dqm [15 : 0] = Bank3 [{Row, Col}];
|
||||
// Dqm operation
|
||||
if (Dqm_reg0[0] == 1'b1) Dq_dqm [ 7 : 0] = 8'bz;
|
||||
if (Dqm_reg0[1] == 1'b1) Dq_dqm [15 : 8] = 8'bz;
|
||||
// Display result
|
||||
Dq_reg [15 : 0] = #tAC Dq_dqm [15 : 0];
|
||||
if (Dqm_reg0 == 2'b11) begin
|
||||
if (Debug) $display("at time %t READ : Bank = %d Row = %d, Col = %d, Data = Hi-Z due to DQM", $time, Bank, Row, Col);
|
||||
end else begin
|
||||
if (Debug) $display("at time %t READ : Bank = %d Row = %d, Col = %d, Data = %h, Dqm = %b", $time, Bank, Row, Col, Dq_reg, Dqm_reg0);
|
||||
end
|
||||
// Advance burst counter subroutine
|
||||
Burst;
|
||||
end
|
||||
end
|
||||
|
||||
// Write with Auto Precharge Calculation
|
||||
// The device start internal precharge:
|
||||
// 1. tWR Clock after last burst
|
||||
// and 2. Meet minimum tRAS requirement
|
||||
// or 3. Interrupt by a Read or Write (with or without AutoPrecharge)
|
||||
always @ (WR_counter[0]) begin
|
||||
if ((Auto_precharge[0] == 1'b1) && (Write_precharge[0] == 1'b1)) begin
|
||||
if ((($time - RAS_chk0 >= tRAS) && // Case 2
|
||||
(((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [0] >= 1) || // Case 1
|
||||
(Burst_length_2 == 1'b1 && Count_precharge [0] >= 2) ||
|
||||
(Burst_length_4 == 1'b1 && Count_precharge [0] >= 4) ||
|
||||
(Burst_length_8 == 1'b1 && Count_precharge [0] >= 8))) ||
|
||||
(RW_interrupt_write[0] == 1'b1 && WR_counter[0] >= 2)) begin // Case 3 (stop count when interrupt)
|
||||
Auto_precharge[0] = 1'b0;
|
||||
Write_precharge[0] = 1'b0;
|
||||
RW_interrupt_write[0] = 1'b0;
|
||||
#tWRa; // Wait for tWR
|
||||
Pc_b0 = 1'b1;
|
||||
Act_b0 = 1'b0;
|
||||
RP_chk0 = $time;
|
||||
if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 0", $time);
|
||||
end
|
||||
end
|
||||
end
|
||||
always @ (WR_counter[1]) begin
|
||||
if ((Auto_precharge[1] == 1'b1) && (Write_precharge[1] == 1'b1)) begin
|
||||
if ((($time - RAS_chk1 >= tRAS) &&
|
||||
(((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [1] >= 1) ||
|
||||
(Burst_length_2 == 1'b1 && Count_precharge [1] >= 2) ||
|
||||
(Burst_length_4 == 1'b1 && Count_precharge [1] >= 4) ||
|
||||
(Burst_length_8 == 1'b1 && Count_precharge [1] >= 8))) ||
|
||||
(RW_interrupt_write[1] == 1'b1 && WR_counter[1] >= 2)) begin
|
||||
Auto_precharge[1] = 1'b0;
|
||||
Write_precharge[1] = 1'b0;
|
||||
RW_interrupt_write[1] = 1'b0;
|
||||
#tWRa; // Wait for tWR
|
||||
Pc_b1 = 1'b1;
|
||||
Act_b1 = 1'b0;
|
||||
RP_chk1 = $time;
|
||||
if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 1", $time);
|
||||
end
|
||||
end
|
||||
end
|
||||
always @ (WR_counter[2]) begin
|
||||
if ((Auto_precharge[2] == 1'b1) && (Write_precharge[2] == 1'b1)) begin
|
||||
if ((($time - RAS_chk2 >= tRAS) &&
|
||||
(((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [2] >= 1) ||
|
||||
(Burst_length_2 == 1'b1 && Count_precharge [2] >= 2) ||
|
||||
(Burst_length_4 == 1'b1 && Count_precharge [2] >= 4) ||
|
||||
(Burst_length_8 == 1'b1 && Count_precharge [2] >= 8))) ||
|
||||
(RW_interrupt_write[2] == 1'b1 && WR_counter[2] >= 2)) begin
|
||||
Auto_precharge[2] = 1'b0;
|
||||
Write_precharge[2] = 1'b0;
|
||||
RW_interrupt_write[2] = 1'b0;
|
||||
#tWRa; // Wait for tWR
|
||||
Pc_b2 = 1'b1;
|
||||
Act_b2 = 1'b0;
|
||||
RP_chk2 = $time;
|
||||
if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 2", $time);
|
||||
end
|
||||
end
|
||||
end
|
||||
always @ (WR_counter[3]) begin
|
||||
if ((Auto_precharge[3] == 1'b1) && (Write_precharge[3] == 1'b1)) begin
|
||||
if ((($time - RAS_chk3 >= tRAS) &&
|
||||
(((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [3] >= 1) ||
|
||||
(Burst_length_2 == 1'b1 && Count_precharge [3] >= 2) ||
|
||||
(Burst_length_4 == 1'b1 && Count_precharge [3] >= 4) ||
|
||||
(Burst_length_8 == 1'b1 && Count_precharge [3] >= 8))) ||
|
||||
(RW_interrupt_write[3] == 1'b1 && WR_counter[3] >= 2)) begin
|
||||
Auto_precharge[3] = 1'b0;
|
||||
Write_precharge[3] = 1'b0;
|
||||
RW_interrupt_write[3] = 1'b0;
|
||||
#tWRa; // Wait for tWR
|
||||
Pc_b3 = 1'b1;
|
||||
Act_b3 = 1'b0;
|
||||
RP_chk3 = $time;
|
||||
if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 3", $time);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
task Burst;
|
||||
begin
|
||||
// Advance Burst Counter
|
||||
Burst_counter = Burst_counter + 1;
|
||||
|
||||
// Burst Type
|
||||
if (Mode_reg[3] == 1'b0) begin // Sequential Burst
|
||||
Col_temp = Col + 1;
|
||||
end else if (Mode_reg[3] == 1'b1) begin // Interleaved Burst
|
||||
Col_temp[2] = Burst_counter[2] ^ Col_brst[2];
|
||||
Col_temp[1] = Burst_counter[1] ^ Col_brst[1];
|
||||
Col_temp[0] = Burst_counter[0] ^ Col_brst[0];
|
||||
end
|
||||
|
||||
// Burst Length
|
||||
if (Burst_length_2) begin // Burst Length = 2
|
||||
Col [0] = Col_temp [0];
|
||||
end else if (Burst_length_4) begin // Burst Length = 4
|
||||
Col [1 : 0] = Col_temp [1 : 0];
|
||||
end else if (Burst_length_8) begin // Burst Length = 8
|
||||
Col [2 : 0] = Col_temp [2 : 0];
|
||||
end else begin // Burst Length = FULL
|
||||
Col = Col_temp;
|
||||
end
|
||||
|
||||
// Burst Read Single Write
|
||||
if (Write_burst_mode == 1'b1) begin
|
||||
Data_in_enable = 1'b0;
|
||||
end
|
||||
|
||||
// Data Counter
|
||||
if (Burst_length_1 == 1'b1) begin
|
||||
if (Burst_counter >= 1) begin
|
||||
Data_in_enable = 1'b0;
|
||||
Data_out_enable = 1'b0;
|
||||
end
|
||||
end else if (Burst_length_2 == 1'b1) begin
|
||||
if (Burst_counter >= 2) begin
|
||||
Data_in_enable = 1'b0;
|
||||
Data_out_enable = 1'b0;
|
||||
end
|
||||
end else if (Burst_length_4 == 1'b1) begin
|
||||
if (Burst_counter >= 4) begin
|
||||
Data_in_enable = 1'b0;
|
||||
Data_out_enable = 1'b0;
|
||||
end
|
||||
end else if (Burst_length_8 == 1'b1) begin
|
||||
if (Burst_counter >= 8) begin
|
||||
Data_in_enable = 1'b0;
|
||||
Data_out_enable = 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
// Timing Parameters for -75 (PC133) and CAS Latency = 2
|
||||
specify
|
||||
specparam
|
||||
tAH = 0.8, // Addr, Ba Hold Time
|
||||
tAS = 1.5, // Addr, Ba Setup Time
|
||||
tCH = 2.5, // Clock High-Level Width
|
||||
tCL = 2.5, // Clock Low-Level Width
|
||||
tCK = 10, // Clock Cycle Time
|
||||
tDH = 0.8, // Data-in Hold Time
|
||||
tDS = 1.5, // Data-in Setup Time
|
||||
tCKH = 0.8, // CKE Hold Time
|
||||
tCKS = 1.5, // CKE Setup Time
|
||||
tCMH = 0.8, // CS#, RAS#, CAS#, WE#, DQM# Hold Time
|
||||
tCMS = 1.5; // CS#, RAS#, CAS#, WE#, DQM# Setup Time
|
||||
$width (posedge Clk, tCH);
|
||||
$width (negedge Clk, tCL);
|
||||
$period (negedge Clk, tCK);
|
||||
$period (posedge Clk, tCK);
|
||||
$setuphold(posedge Clk, Cke, tCKS, tCKH);
|
||||
$setuphold(posedge Clk, Cs_n, tCMS, tCMH);
|
||||
$setuphold(posedge Clk, Cas_n, tCMS, tCMH);
|
||||
$setuphold(posedge Clk, Ras_n, tCMS, tCMH);
|
||||
$setuphold(posedge Clk, We_n, tCMS, tCMH);
|
||||
$setuphold(posedge Clk, Addr, tAS, tAH);
|
||||
$setuphold(posedge Clk, Ba, tAS, tAH);
|
||||
$setuphold(posedge Clk, Dqm, tCMS, tCMH);
|
||||
$setuphold(posedge Dq_chk, Dq, tDS, tDH);
|
||||
endspecify
|
||||
|
||||
endmodule
|
||||
|
964
lib/common/Driver/SDRAM_driver/model/mt48lc8m8a2.v
Normal file
964
lib/common/Driver/SDRAM_driver/model/mt48lc8m8a2.v
Normal file
@ -0,0 +1,964 @@
|
||||
/****************************************************************************************
|
||||
*
|
||||
* File Name: MT48LC8M8A2.V
|
||||
* Version: 0.0f
|
||||
* Date: July 8th, 1999
|
||||
* Model: BUS Functional
|
||||
* Simulator: Model Technology (PC version 5.2e PE)
|
||||
*
|
||||
* Dependencies: None
|
||||
*
|
||||
* Author: Son P. Huynh
|
||||
* Email: sphuynh@micron.com
|
||||
* Phone: (208) 368-3825
|
||||
* Company: Micron Technology, Inc.
|
||||
* Model: MT48LC8M16A2 (2Meg x 8 x 4 Banks)
|
||||
*
|
||||
* Description: Micron 128Mb SDRAM Verilog model
|
||||
*
|
||||
* Limitation: - Doesn't check for 4096 cycle refresh
|
||||
*
|
||||
* Note: - Set simulator resolution to "ps" accuracy
|
||||
* - Set Debug = 0 to disable $display messages
|
||||
*
|
||||
* Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY
|
||||
* WHATSOEVER AND MICRON SPECIFICALLY DISCLAIMS ANY
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
|
||||
* A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT.
|
||||
*
|
||||
* Copyright © 1998 Micron Semiconductor Products, Inc.
|
||||
* All rights researved
|
||||
*
|
||||
* Rev Author Phone Date Changes
|
||||
* ---- ---------------------------- ---------- ---------------------------------------
|
||||
* 0.0f Son Huynh 208-368-3825 07/08/1999 - Fix tWR = 1 Clk + 7.5 ns (Auto)
|
||||
* Micron Technology Inc. - Fix tWR = 15 ns (Manual)
|
||||
* - Fix tRP (Autoprecharge to AutoRefresh)
|
||||
*
|
||||
* 0.0a Son Huynh 208-368-3825 05/13/1998 - First Release (from 64Mb rev 0.0e)
|
||||
* Micron Technology Inc.
|
||||
****************************************************************************************/
|
||||
|
||||
`timescale 1ns / 100ps
|
||||
|
||||
module mt48lc8m8a2 (Dq, Addr, Ba, Clk, Cke, Cs_n, Ras_n, Cas_n, We_n, Dqm);
|
||||
|
||||
parameter addr_bits = 12;
|
||||
parameter data_bits = 8;
|
||||
parameter col_bits = 9;
|
||||
parameter mem_sizes = 2097151; // 2 Meg
|
||||
|
||||
inout [data_bits - 1 : 0] Dq;
|
||||
input [addr_bits - 1 : 0] Addr;
|
||||
input [1 : 0] Ba;
|
||||
input Clk;
|
||||
input Cke;
|
||||
input Cs_n;
|
||||
input Ras_n;
|
||||
input Cas_n;
|
||||
input We_n;
|
||||
input [0 : 0] Dqm;
|
||||
|
||||
reg [data_bits - 1 : 0] Bank0 [0 : mem_sizes];
|
||||
reg [data_bits - 1 : 0] Bank1 [0 : mem_sizes];
|
||||
reg [data_bits - 1 : 0] Bank2 [0 : mem_sizes];
|
||||
reg [data_bits - 1 : 0] Bank3 [0 : mem_sizes];
|
||||
|
||||
reg [1 : 0] Bank_addr [0 : 3]; // Bank Address Pipeline
|
||||
reg [col_bits - 1 : 0] Col_addr [0 : 3]; // Column Address Pipeline
|
||||
reg [3 : 0] Command [0 : 3]; // Command Operation Pipeline
|
||||
reg [0 : 0] Dqm_reg0, Dqm_reg1; // DQM Operation Pipeline
|
||||
reg [addr_bits - 1 : 0] B0_row_addr, B1_row_addr, B2_row_addr, B3_row_addr;
|
||||
|
||||
reg [addr_bits - 1 : 0] Mode_reg;
|
||||
reg [data_bits - 1 : 0] Dq_reg, Dq_dqm;
|
||||
reg [col_bits - 1 : 0] Col_temp, Burst_counter;
|
||||
|
||||
reg Act_b0, Act_b1, Act_b2, Act_b3; // Bank Activate
|
||||
reg Pc_b0, Pc_b1, Pc_b2, Pc_b3; // Bank Precharge
|
||||
|
||||
reg [1 : 0] Bank_precharge [0 : 3]; // Precharge Command
|
||||
reg A10_precharge [0 : 3]; // Addr[10] = 1 (All banks)
|
||||
reg Auto_precharge [0 : 3]; // RW AutoPrecharge (Bank)
|
||||
reg Read_precharge [0 : 3]; // R AutoPrecharge
|
||||
reg Write_precharge [0 : 3]; // W AutoPrecharge
|
||||
integer Count_precharge [0 : 3]; // RW AutoPrecharge (Counter)
|
||||
reg RW_interrupt_read [0 : 3]; // RW Interrupt Read with Auto Precharge
|
||||
reg RW_interrupt_write [0 : 3]; // RW Interrupt Write with Auto Precharge
|
||||
|
||||
reg Data_in_enable;
|
||||
reg Data_out_enable;
|
||||
|
||||
reg [1 : 0] Bank, Previous_bank;
|
||||
reg [addr_bits - 1 : 0] Row;
|
||||
reg [col_bits - 1 : 0] Col, Col_brst;
|
||||
|
||||
// Internal system clock
|
||||
reg CkeZ, Sys_clk;
|
||||
|
||||
// Commands Decode
|
||||
wire Active_enable = ~Cs_n & ~Ras_n & Cas_n & We_n;
|
||||
wire Aref_enable = ~Cs_n & ~Ras_n & ~Cas_n & We_n;
|
||||
wire Burst_term = ~Cs_n & Ras_n & Cas_n & ~We_n;
|
||||
wire Mode_reg_enable = ~Cs_n & ~Ras_n & ~Cas_n & ~We_n;
|
||||
wire Prech_enable = ~Cs_n & ~Ras_n & Cas_n & ~We_n;
|
||||
wire Read_enable = ~Cs_n & Ras_n & ~Cas_n & We_n;
|
||||
wire Write_enable = ~Cs_n & Ras_n & ~Cas_n & ~We_n;
|
||||
|
||||
// Burst Length Decode
|
||||
wire Burst_length_1 = ~Mode_reg[2] & ~Mode_reg[1] & ~Mode_reg[0];
|
||||
wire Burst_length_2 = ~Mode_reg[2] & ~Mode_reg[1] & Mode_reg[0];
|
||||
wire Burst_length_4 = ~Mode_reg[2] & Mode_reg[1] & ~Mode_reg[0];
|
||||
wire Burst_length_8 = ~Mode_reg[2] & Mode_reg[1] & Mode_reg[0];
|
||||
|
||||
// CAS Latency Decode
|
||||
wire Cas_latency_2 = ~Mode_reg[6] & Mode_reg[5] & ~Mode_reg[4];
|
||||
wire Cas_latency_3 = ~Mode_reg[6] & Mode_reg[5] & Mode_reg[4];
|
||||
|
||||
`ifdef VERBOSE
|
||||
wire Debug = 1'b1; // Debug messages : 1 = On
|
||||
`else
|
||||
wire Debug = 1'b0; // Debug messages : 1 = On
|
||||
`endif
|
||||
// Write Burst Mode
|
||||
wire Write_burst_mode = Mode_reg[9];
|
||||
|
||||
wire Dq_chk = Sys_clk & Data_in_enable; // Check setup/hold time for DQ
|
||||
|
||||
assign Dq = Dq_reg; // DQ buffer
|
||||
|
||||
// Commands Operation
|
||||
`define ACT 0
|
||||
`define NOP 1
|
||||
`define READ 2
|
||||
`define READ_A 3
|
||||
`define SDRAM_WRITE 4
|
||||
`define WRITE_A 5
|
||||
`define SDRAM_PRECH 6
|
||||
`define SDRAM_A_REF 7
|
||||
`define SDRAM_BST 8
|
||||
`define SDRAM_LMR 9
|
||||
|
||||
// Timing Parameters for -75 (PC133) and CAS Latency = 2
|
||||
parameter tAC = 6.0;
|
||||
parameter tHZ = 7.0;
|
||||
parameter tOH = 2.7;
|
||||
parameter tMRD = 2.0; // 2 Clk Cycles
|
||||
parameter tRAS = 44.0;
|
||||
parameter tRC = 66.0;
|
||||
parameter tRCD = 20.0;
|
||||
parameter tRP = 20.0;
|
||||
parameter tRRD = 15.0;
|
||||
parameter tWRa = 7.5; // A2 Version - Auto precharge mode only (1 Clk + 7.5 ns)
|
||||
parameter tWRp = 15.0; // A2 Version - Precharge mode only (15 ns)
|
||||
|
||||
// Timing Check variable
|
||||
integer MRD_chk;
|
||||
integer WR_counter [0 : 3];
|
||||
time WR_chk [0 : 3];
|
||||
time RC_chk, RRD_chk;
|
||||
time RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3;
|
||||
time RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3;
|
||||
time RP_chk0, RP_chk1, RP_chk2, RP_chk3;
|
||||
|
||||
initial begin
|
||||
|
||||
Dq_reg = {data_bits{1'bz}};
|
||||
{Data_in_enable, Data_out_enable} = 0;
|
||||
{Act_b0, Act_b1, Act_b2, Act_b3} = 4'b0000;
|
||||
{Pc_b0, Pc_b1, Pc_b2, Pc_b3} = 4'b0000;
|
||||
{WR_chk[0], WR_chk[1], WR_chk[2], WR_chk[3]} = 0;
|
||||
{WR_counter[0], WR_counter[1], WR_counter[2], WR_counter[3]} = 0;
|
||||
{RW_interrupt_read[0], RW_interrupt_read[1], RW_interrupt_read[2], RW_interrupt_read[3]} = 0;
|
||||
{RW_interrupt_write[0], RW_interrupt_write[1], RW_interrupt_write[2], RW_interrupt_write[3]} = 0;
|
||||
{MRD_chk, RC_chk, RRD_chk} = 0;
|
||||
{RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3} = 0;
|
||||
{RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3} = 0;
|
||||
{RP_chk0, RP_chk1, RP_chk2, RP_chk3} = 0;
|
||||
$timeformat (-9, 0, " ns", 12);
|
||||
//$readmemh("bank0.txt", Bank0);
|
||||
//$readmemh("bank1.txt", Bank1);
|
||||
//$readmemh("bank2.txt", Bank2);
|
||||
//$readmemh("bank3.txt", Bank3);
|
||||
end
|
||||
|
||||
// System clock generator
|
||||
always begin
|
||||
@ (posedge Clk) begin
|
||||
Sys_clk = CkeZ;
|
||||
CkeZ = Cke;
|
||||
end
|
||||
@ (negedge Clk) begin
|
||||
Sys_clk = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always @ (posedge Sys_clk) begin
|
||||
// Internal Commamd Pipelined
|
||||
Command[0] = Command[1];
|
||||
Command[1] = Command[2];
|
||||
Command[2] = Command[3];
|
||||
Command[3] = `NOP;
|
||||
|
||||
Col_addr[0] = Col_addr[1];
|
||||
Col_addr[1] = Col_addr[2];
|
||||
Col_addr[2] = Col_addr[3];
|
||||
Col_addr[3] = {col_bits{1'b0}};
|
||||
|
||||
Bank_addr[0] = Bank_addr[1];
|
||||
Bank_addr[1] = Bank_addr[2];
|
||||
Bank_addr[2] = Bank_addr[3];
|
||||
Bank_addr[3] = 2'b0;
|
||||
|
||||
Bank_precharge[0] = Bank_precharge[1];
|
||||
Bank_precharge[1] = Bank_precharge[2];
|
||||
Bank_precharge[2] = Bank_precharge[3];
|
||||
Bank_precharge[3] = 2'b0;
|
||||
|
||||
A10_precharge[0] = A10_precharge[1];
|
||||
A10_precharge[1] = A10_precharge[2];
|
||||
A10_precharge[2] = A10_precharge[3];
|
||||
A10_precharge[3] = 1'b0;
|
||||
|
||||
// Dqm pipeline for Read
|
||||
Dqm_reg0 = Dqm_reg1;
|
||||
Dqm_reg1 = Dqm;
|
||||
|
||||
// Read or Write with Auto Precharge Counter
|
||||
if (Auto_precharge[0] == 1'b1) begin
|
||||
Count_precharge[0] = Count_precharge[0] + 1;
|
||||
end
|
||||
if (Auto_precharge[1] == 1'b1) begin
|
||||
Count_precharge[1] = Count_precharge[1] + 1;
|
||||
end
|
||||
if (Auto_precharge[2] == 1'b1) begin
|
||||
Count_precharge[2] = Count_precharge[2] + 1;
|
||||
end
|
||||
if (Auto_precharge[3] == 1'b1) begin
|
||||
Count_precharge[3] = Count_precharge[3] + 1;
|
||||
end
|
||||
|
||||
// tMRD Counter
|
||||
MRD_chk = MRD_chk + 1;
|
||||
|
||||
// tWR Counter for Write
|
||||
WR_counter[0] = WR_counter[0] + 1;
|
||||
WR_counter[1] = WR_counter[1] + 1;
|
||||
WR_counter[2] = WR_counter[2] + 1;
|
||||
WR_counter[3] = WR_counter[3] + 1;
|
||||
|
||||
// Auto Refresh
|
||||
if (Aref_enable == 1'b1) begin
|
||||
if (Debug) $display ("at time %t AREF : Auto Refresh", $time);
|
||||
// Auto Refresh to Auto Refresh
|
||||
if ($time - RC_chk < tRC) begin
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRC violation during Auto Refresh", $time);
|
||||
end
|
||||
// Precharge to Auto Refresh
|
||||
if ($time - RP_chk0 < tRP || $time - RP_chk1 < tRP || $time - RP_chk2 < tRP || $time - RP_chk3 < tRP) begin
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRP violation during Auto Refresh", $time);
|
||||
end
|
||||
// Precharge to Refresh
|
||||
if (Pc_b0 == 1'b0 || Pc_b1 == 1'b0 || Pc_b2 == 1'b0 || Pc_b3 == 1'b0) begin
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: All banks must be Precharge before Auto Refresh", $time);
|
||||
end
|
||||
// Record Current tRC time
|
||||
RC_chk = $time;
|
||||
end
|
||||
|
||||
// Load Mode Register
|
||||
if (Mode_reg_enable == 1'b1) begin
|
||||
// Decode CAS Latency, Burst Length, Burst Type, and Write Burst Mode
|
||||
if (Pc_b0 == 1'b1 && Pc_b1 == 1'b1 && Pc_b2 == 1'b1 && Pc_b3 == 1'b1) begin
|
||||
Mode_reg = Addr;
|
||||
if (Debug) begin
|
||||
$display ("at time %t LMR : Load Mode Register", $time);
|
||||
// CAS Latency
|
||||
if (Addr[6 : 4] == 3'b010)
|
||||
$display (" CAS Latency = 2");
|
||||
else if (Addr[6 : 4] == 3'b011)
|
||||
$display (" CAS Latency = 3");
|
||||
else
|
||||
$display (" CAS Latency = Reserved");
|
||||
// Burst Length
|
||||
if (Addr[2 : 0] == 3'b000)
|
||||
$display (" Burst Length = 1");
|
||||
else if (Addr[2 : 0] == 3'b001)
|
||||
$display (" Burst Length = 2");
|
||||
else if (Addr[2 : 0] == 3'b010)
|
||||
$display (" Burst Length = 4");
|
||||
else if (Addr[2 : 0] == 3'b011)
|
||||
$display (" Burst Length = 8");
|
||||
else if (Addr[3 : 0] == 4'b0111)
|
||||
$display (" Burst Length = Full");
|
||||
else
|
||||
$display (" Burst Length = Reserved");
|
||||
// Burst Type
|
||||
if (Addr[3] == 1'b0)
|
||||
$display (" Burst Type = Sequential");
|
||||
else if (Addr[3] == 1'b1)
|
||||
$display (" Burst Type = Interleaved");
|
||||
else
|
||||
$display (" Burst Type = Reserved");
|
||||
// Write Burst Mode
|
||||
if (Addr[9] == 1'b0)
|
||||
$display (" Write Burst Mode = Programmed Burst Length");
|
||||
else if (Addr[9] == 1'b1)
|
||||
$display (" Write Burst Mode = Single Location Access");
|
||||
else
|
||||
$display (" Write Burst Mode = Reserved");
|
||||
end
|
||||
end else begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: all banks must be Precharge before Load Mode Register", $time);
|
||||
end
|
||||
// REF to LMR
|
||||
if ($time - RC_chk < tRC) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRC violation during Load Mode Register", $time);
|
||||
end
|
||||
// LMR to LMR
|
||||
if (MRD_chk < tMRD) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tMRD violation during Load Mode Register", $time);
|
||||
end
|
||||
MRD_chk = 0;
|
||||
end
|
||||
|
||||
// Active Block (Latch Bank Address and Row Address)
|
||||
if (Active_enable == 1'b1) begin
|
||||
if (Ba == 2'b00 && Pc_b0 == 1'b1) begin
|
||||
{Act_b0, Pc_b0} = 2'b10;
|
||||
B0_row_addr = Addr [addr_bits - 1 : 0];
|
||||
RCD_chk0 = $time;
|
||||
RAS_chk0 = $time;
|
||||
if (Debug) $display ("at time %t ACT : Bank = 0 Row = %d", $time, Addr);
|
||||
// Precharge to Activate Bank 0
|
||||
if ($time - RP_chk0 < tRP) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRP violation during Activate bank 0", $time);
|
||||
end
|
||||
end else if (Ba == 2'b01 && Pc_b1 == 1'b1) begin
|
||||
{Act_b1, Pc_b1} = 2'b10;
|
||||
B1_row_addr = Addr [addr_bits - 1 : 0];
|
||||
RCD_chk1 = $time;
|
||||
RAS_chk1 = $time;
|
||||
if (Debug) $display ("at time %t ACT : Bank = 1 Row = %d", $time, Addr);
|
||||
// Precharge to Activate Bank 1
|
||||
if ($time - RP_chk1 < tRP) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRP violation during Activate bank 1", $time);
|
||||
end
|
||||
end else if (Ba == 2'b10 && Pc_b2 == 1'b1) begin
|
||||
{Act_b2, Pc_b2} = 2'b10;
|
||||
B2_row_addr = Addr [addr_bits - 1 : 0];
|
||||
RCD_chk2 = $time;
|
||||
RAS_chk2 = $time;
|
||||
if (Debug) $display ("at time %t ACT : Bank = 2 Row = %d", $time, Addr);
|
||||
// Precharge to Activate Bank 2
|
||||
if ($time - RP_chk2 < tRP) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRP violation during Activate bank 2", $time);
|
||||
end
|
||||
end else if (Ba == 2'b11 && Pc_b3 == 1'b1) begin
|
||||
{Act_b3, Pc_b3} = 2'b10;
|
||||
B3_row_addr = Addr [addr_bits - 1 : 0];
|
||||
RCD_chk3 = $time;
|
||||
RAS_chk3 = $time;
|
||||
if (Debug) $display ("at time %t ACT : Bank = 3 Row = %d", $time, Addr);
|
||||
// Precharge to Activate Bank 3
|
||||
if ($time - RP_chk3 < tRP) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRP violation during Activate bank 3", $time);
|
||||
end
|
||||
end else if (Ba == 2'b00 && Pc_b0 == 1'b0) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: Bank 0 is not Precharged.", $time);
|
||||
end else if (Ba == 2'b01 && Pc_b1 == 1'b0) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: Bank 1 is not Precharged.", $time);
|
||||
end else if (Ba == 2'b10 && Pc_b2 == 1'b0) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: Bank 2 is not Precharged.", $time);
|
||||
end else if (Ba == 2'b11 && Pc_b3 == 1'b0) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: Bank 3 is not Precharged.", $time);
|
||||
end
|
||||
// Active Bank A to Active Bank B
|
||||
if ((Previous_bank != Ba) && ($time - RRD_chk < tRRD)) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRRD violation during Activate bank = %d", $time, Ba);
|
||||
end
|
||||
// Load Mode Register to Active
|
||||
if (MRD_chk < tMRD ) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tMRD violation during Activate bank = %d", $time, Ba);
|
||||
end
|
||||
// Auto Refresh to Activate
|
||||
if ($time - RC_chk < tRC) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRC violation during Activate bank = %d", $time, Ba);
|
||||
end
|
||||
// Record variables for checking violation
|
||||
RRD_chk = $time;
|
||||
Previous_bank = Ba;
|
||||
end
|
||||
|
||||
// Precharge Block
|
||||
if (Prech_enable == 1'b1) begin
|
||||
if (Addr[10] == 1'b1) begin
|
||||
{Pc_b0, Pc_b1, Pc_b2, Pc_b3} = 4'b1111;
|
||||
{Act_b0, Act_b1, Act_b2, Act_b3} = 4'b0000;
|
||||
RP_chk0 = $time;
|
||||
RP_chk1 = $time;
|
||||
RP_chk2 = $time;
|
||||
RP_chk3 = $time;
|
||||
if (Debug) $display ("at time %t PRE : Bank = ALL",$time);
|
||||
// Activate to Precharge all banks
|
||||
if (($time - RAS_chk0 < tRAS) || ($time - RAS_chk1 < tRAS) ||
|
||||
($time - RAS_chk2 < tRAS) || ($time - RAS_chk3 < tRAS)) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRAS violation during Precharge all bank", $time);
|
||||
end
|
||||
// tWR violation check for write
|
||||
if (($time - WR_chk[0] < tWRp) || ($time - WR_chk[1] < tWRp) ||
|
||||
($time - WR_chk[2] < tWRp) || ($time - WR_chk[3] < tWRp)) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tWR violation during Precharge all bank", $time);
|
||||
end
|
||||
end else if (Addr[10] == 1'b0) begin
|
||||
if (Ba == 2'b00) begin
|
||||
{Pc_b0, Act_b0} = 2'b10;
|
||||
RP_chk0 = $time;
|
||||
if (Debug) $display ("at time %t PRE : Bank = 0",$time);
|
||||
// Activate to Precharge Bank 0
|
||||
if ($time - RAS_chk0 < tRAS) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRAS violation during Precharge bank 0", $time);
|
||||
end
|
||||
end else if (Ba == 2'b01) begin
|
||||
{Pc_b1, Act_b1} = 2'b10;
|
||||
RP_chk1 = $time;
|
||||
if (Debug) $display ("at time %t PRE : Bank = 1",$time);
|
||||
// Activate to Precharge Bank 1
|
||||
if ($time - RAS_chk1 < tRAS) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRAS violation during Precharge bank 1", $time);
|
||||
end
|
||||
end else if (Ba == 2'b10) begin
|
||||
{Pc_b2, Act_b2} = 2'b10;
|
||||
RP_chk2 = $time;
|
||||
if (Debug) $display ("at time %t PRE : Bank = 2",$time);
|
||||
// Activate to Precharge Bank 2
|
||||
if ($time - RAS_chk2 < tRAS) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRAS violation during Precharge bank 2", $time);
|
||||
end
|
||||
end else if (Ba == 2'b11) begin
|
||||
{Pc_b3, Act_b3} = 2'b10;
|
||||
RP_chk3 = $time;
|
||||
if (Debug) $display ("at time %t PRE : Bank = 3",$time);
|
||||
// Activate to Precharge Bank 3
|
||||
if ($time - RAS_chk3 < tRAS) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tRAS violation during Precharge bank 3", $time);
|
||||
end
|
||||
end
|
||||
// tWR violation check for write
|
||||
if ($time - WR_chk[Ba] < tWRp) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display ("at time %t ERROR: tWR violation during Precharge bank %d", $time, Ba);
|
||||
end
|
||||
end
|
||||
// Terminate a Write Immediately (if same bank or all banks)
|
||||
if (Data_in_enable == 1'b1 && (Bank == Ba || Addr[10] == 1'b1)) begin
|
||||
Data_in_enable = 1'b0;
|
||||
end
|
||||
// Precharge Command Pipeline for Read
|
||||
if (Cas_latency_3 == 1'b1) begin
|
||||
Command[2] = `SDRAM_PRECH;
|
||||
Bank_precharge[2] = Ba;
|
||||
A10_precharge[2] = Addr[10];
|
||||
end else if (Cas_latency_2 == 1'b1) begin
|
||||
Command[1] = `SDRAM_PRECH;
|
||||
Bank_precharge[1] = Ba;
|
||||
A10_precharge[1] = Addr[10];
|
||||
end
|
||||
end
|
||||
|
||||
// Burst terminate
|
||||
if (Burst_term == 1'b1) begin
|
||||
// Terminate a Write Immediately
|
||||
if (Data_in_enable == 1'b1) begin
|
||||
Data_in_enable = 1'b0;
|
||||
end
|
||||
// Terminate a Read Depend on CAS Latency
|
||||
if (Cas_latency_3 == 1'b1) begin
|
||||
Command[2] = `SDRAM_BST;
|
||||
end else if (Cas_latency_2 == 1'b1) begin
|
||||
Command[1] = `SDRAM_BST;
|
||||
end
|
||||
if (Debug) $display ("at time %t BST : Burst Terminate",$time);
|
||||
end
|
||||
|
||||
// Read, Write, Column Latch
|
||||
if (Read_enable == 1'b1 || Write_enable == 1'b1) begin
|
||||
// Check to see if bank is open (ACT)
|
||||
if ((Ba == 2'b00 && Pc_b0 == 1'b1) || (Ba == 2'b01 && Pc_b1 == 1'b1) ||
|
||||
(Ba == 2'b10 && Pc_b2 == 1'b1) || (Ba == 2'b11 && Pc_b3 == 1'b1)) begin
|
||||
|
||||
//->tb.test_control.error_detected;
|
||||
$display("at time %t ERROR: Cannot Read or Write - Bank %d is not Activated", $time, Ba);
|
||||
end
|
||||
// Activate to Read or Write
|
||||
if ((Ba == 2'b00) && ($time - RCD_chk0 < tRCD))
|
||||
begin
|
||||
//->tb.test_control.error_detected;
|
||||
$display("at time %t ERROR: tRCD violation during Read or Write to Bank 0", $time);
|
||||
end
|
||||
|
||||
if ((Ba == 2'b01) && ($time - RCD_chk1 < tRCD))
|
||||
begin
|
||||
//->tb.test_control.error_detected;
|
||||
$display("at time %t ERROR: tRCD violation during Read or Write to Bank 1", $time);
|
||||
end
|
||||
if ((Ba == 2'b10) && ($time - RCD_chk2 < tRCD))
|
||||
begin
|
||||
//->tb.test_control.error_detected;
|
||||
$display("at time %t ERROR: tRCD violation during Read or Write to Bank 2", $time);
|
||||
end
|
||||
if ((Ba == 2'b11) && ($time - RCD_chk3 < tRCD))
|
||||
begin
|
||||
//->tb.test_control.error_detected;
|
||||
$display("at time %t ERROR: tRCD violation during Read or Write to Bank 3", $time);
|
||||
end
|
||||
// Read Command
|
||||
if (Read_enable == 1'b1) begin
|
||||
// CAS Latency pipeline
|
||||
if (Cas_latency_3 == 1'b1) begin
|
||||
if (Addr[10] == 1'b1) begin
|
||||
Command[2] = `READ_A;
|
||||
end else begin
|
||||
Command[2] = `READ;
|
||||
end
|
||||
Col_addr[2] = Addr;
|
||||
Bank_addr[2] = Ba;
|
||||
end else if (Cas_latency_2 == 1'b1) begin
|
||||
if (Addr[10] == 1'b1) begin
|
||||
Command[1] = `READ_A;
|
||||
end else begin
|
||||
Command[1] = `READ;
|
||||
end
|
||||
Col_addr[1] = Addr;
|
||||
Bank_addr[1] = Ba;
|
||||
end
|
||||
|
||||
// Read interrupt Write (terminate Write immediately)
|
||||
if (Data_in_enable == 1'b1) begin
|
||||
Data_in_enable = 1'b0;
|
||||
end
|
||||
|
||||
// Write Command
|
||||
end else if (Write_enable == 1'b1) begin
|
||||
if (Addr[10] == 1'b1) begin
|
||||
Command[0] = `WRITE_A;
|
||||
end else begin
|
||||
Command[0] = `SDRAM_WRITE;
|
||||
end
|
||||
Col_addr[0] = Addr;
|
||||
Bank_addr[0] = Ba;
|
||||
|
||||
// Write interrupt Write (terminate Write immediately)
|
||||
if (Data_in_enable == 1'b1) begin
|
||||
Data_in_enable = 1'b0;
|
||||
end
|
||||
|
||||
// Write interrupt Read (terminate Read immediately)
|
||||
if (Data_out_enable == 1'b1) begin
|
||||
Data_out_enable = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// Interrupting a Write with Autoprecharge
|
||||
if (Auto_precharge[Bank] == 1'b1 && Write_precharge[Bank] == 1'b1) begin
|
||||
RW_interrupt_write[Bank] = 1'b1;
|
||||
if (Debug) $display ("at time %t NOTE : Read/Write Bank %d interrupt Write Bank %d with Autoprecharge", $time, Ba, Bank);
|
||||
end
|
||||
|
||||
// Interrupting a Read with Autoprecharge
|
||||
if (Auto_precharge[Bank] == 1'b1 && Read_precharge[Bank] == 1'b1) begin
|
||||
RW_interrupt_read[Bank] = 1'b1;
|
||||
if (Debug) $display ("at time %t NOTE : Read/Write Bank %d interrupt Read Bank %d with Autoprecharge", $time, Ba, Bank);
|
||||
end
|
||||
|
||||
// Read or Write with Auto Precharge
|
||||
if (Addr[10] == 1'b1) begin
|
||||
Auto_precharge[Ba] = 1'b1;
|
||||
Count_precharge[Ba] = 0;
|
||||
if (Read_enable == 1'b1) begin
|
||||
Read_precharge[Ba] = 1'b1;
|
||||
end else if (Write_enable == 1'b1) begin
|
||||
Write_precharge[Ba] = 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Read with Auto Precharge Calculation
|
||||
// The device start internal precharge:
|
||||
// 1. CAS Latency - 1 cycles before last burst
|
||||
// and 2. Meet minimum tRAS requirement
|
||||
// or 3. Interrupt by a Read or Write (with or without AutoPrecharge)
|
||||
if ((Auto_precharge[0] == 1'b1) && (Read_precharge[0] == 1'b1)) begin
|
||||
if ((($time - RAS_chk0 >= tRAS) && // Case 2
|
||||
((Burst_length_1 == 1'b1 && Count_precharge[0] >= 1) || // Case 1
|
||||
(Burst_length_2 == 1'b1 && Count_precharge[0] >= 2) ||
|
||||
(Burst_length_4 == 1'b1 && Count_precharge[0] >= 4) ||
|
||||
(Burst_length_8 == 1'b1 && Count_precharge[0] >= 8))) ||
|
||||
(RW_interrupt_read[0] == 1'b1)) begin // Case 3
|
||||
Pc_b0 = 1'b1;
|
||||
Act_b0 = 1'b0;
|
||||
RP_chk0 = $time;
|
||||
Auto_precharge[0] = 1'b0;
|
||||
Read_precharge[0] = 1'b0;
|
||||
RW_interrupt_read[0] = 1'b0;
|
||||
if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 0", $time);
|
||||
end
|
||||
end
|
||||
if ((Auto_precharge[1] == 1'b1) && (Read_precharge[1] == 1'b1)) begin
|
||||
if ((($time - RAS_chk1 >= tRAS) &&
|
||||
((Burst_length_1 == 1'b1 && Count_precharge[1] >= 1) ||
|
||||
(Burst_length_2 == 1'b1 && Count_precharge[1] >= 2) ||
|
||||
(Burst_length_4 == 1'b1 && Count_precharge[1] >= 4) ||
|
||||
(Burst_length_8 == 1'b1 && Count_precharge[1] >= 8))) ||
|
||||
(RW_interrupt_read[1] == 1'b1)) begin
|
||||
Pc_b1 = 1'b1;
|
||||
Act_b1 = 1'b0;
|
||||
RP_chk1 = $time;
|
||||
Auto_precharge[1] = 1'b0;
|
||||
Read_precharge[1] = 1'b0;
|
||||
RW_interrupt_read[1] = 1'b0;
|
||||
if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 1", $time);
|
||||
end
|
||||
end
|
||||
if ((Auto_precharge[2] == 1'b1) && (Read_precharge[2] == 1'b1)) begin
|
||||
if ((($time - RAS_chk2 >= tRAS) &&
|
||||
((Burst_length_1 == 1'b1 && Count_precharge[2] >= 1) ||
|
||||
(Burst_length_2 == 1'b1 && Count_precharge[2] >= 2) ||
|
||||
(Burst_length_4 == 1'b1 && Count_precharge[2] >= 4) ||
|
||||
(Burst_length_8 == 1'b1 && Count_precharge[2] >= 8))) ||
|
||||
(RW_interrupt_read[2] == 1'b1)) begin
|
||||
Pc_b2 = 1'b1;
|
||||
Act_b2 = 1'b0;
|
||||
RP_chk2 = $time;
|
||||
Auto_precharge[2] = 1'b0;
|
||||
Read_precharge[2] = 1'b0;
|
||||
RW_interrupt_read[2] = 1'b0;
|
||||
if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 2", $time);
|
||||
end
|
||||
end
|
||||
if ((Auto_precharge[3] == 1'b1) && (Read_precharge[3] == 1'b1)) begin
|
||||
if ((($time - RAS_chk3 >= tRAS) &&
|
||||
((Burst_length_1 == 1'b1 && Count_precharge[3] >= 1) ||
|
||||
(Burst_length_2 == 1'b1 && Count_precharge[3] >= 2) ||
|
||||
(Burst_length_4 == 1'b1 && Count_precharge[3] >= 4) ||
|
||||
(Burst_length_8 == 1'b1 && Count_precharge[3] >= 8))) ||
|
||||
(RW_interrupt_read[3] == 1'b1)) begin
|
||||
Pc_b3 = 1'b1;
|
||||
Act_b3 = 1'b0;
|
||||
RP_chk3 = $time;
|
||||
Auto_precharge[3] = 1'b0;
|
||||
Read_precharge[3] = 1'b0;
|
||||
RW_interrupt_read[3] = 1'b0;
|
||||
if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 3", $time);
|
||||
end
|
||||
end
|
||||
|
||||
// Internal Precharge or Bst
|
||||
if (Command[0] == `SDRAM_PRECH) begin // Precharge terminate a read with same bank or all banks
|
||||
if (Bank_precharge[0] == Bank || A10_precharge[0] == 1'b1) begin
|
||||
if (Data_out_enable == 1'b1) begin
|
||||
Data_out_enable = 1'b0;
|
||||
end
|
||||
end
|
||||
end else if (Command[0] == `SDRAM_BST) begin // BST terminate a read to current bank
|
||||
if (Data_out_enable == 1'b1) begin
|
||||
Data_out_enable = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
if (Data_out_enable == 1'b0) begin
|
||||
Dq_reg <= #tOH {data_bits{1'bz}};
|
||||
end
|
||||
|
||||
// Detect Read or Write command
|
||||
if (Command[0] == `READ || Command[0] == `READ_A) begin
|
||||
Bank = Bank_addr[0];
|
||||
Col = Col_addr[0];
|
||||
Col_brst = Col_addr[0];
|
||||
if (Bank_addr[0] == 2'b00) begin
|
||||
Row = B0_row_addr;
|
||||
end else if (Bank_addr[0] == 2'b01) begin
|
||||
Row = B1_row_addr;
|
||||
end else if (Bank_addr[0] == 2'b10) begin
|
||||
Row = B2_row_addr;
|
||||
end else if (Bank_addr[0] == 2'b11) begin
|
||||
Row = B3_row_addr;
|
||||
end
|
||||
Burst_counter = 0;
|
||||
Data_in_enable = 1'b0;
|
||||
Data_out_enable = 1'b1;
|
||||
end else if (Command[0] == `SDRAM_WRITE || Command[0] == `WRITE_A) begin
|
||||
Bank = Bank_addr[0];
|
||||
Col = Col_addr[0];
|
||||
Col_brst = Col_addr[0];
|
||||
if (Bank_addr[0] == 2'b00) begin
|
||||
Row = B0_row_addr;
|
||||
end else if (Bank_addr[0] == 2'b01) begin
|
||||
Row = B1_row_addr;
|
||||
end else if (Bank_addr[0] == 2'b10) begin
|
||||
Row = B2_row_addr;
|
||||
end else if (Bank_addr[0] == 2'b11) begin
|
||||
Row = B3_row_addr;
|
||||
end
|
||||
Burst_counter = 0;
|
||||
Data_in_enable = 1'b1;
|
||||
Data_out_enable = 1'b0;
|
||||
end
|
||||
|
||||
// DQ buffer (Driver/Receiver)
|
||||
if (Data_in_enable == 1'b1) begin // Writing Data to Memory
|
||||
// Array buffer
|
||||
if (Bank == 2'b00) Dq_dqm [15 : 0] = Bank0 [{Row, Col}];
|
||||
if (Bank == 2'b01) Dq_dqm [15 : 0] = Bank1 [{Row, Col}];
|
||||
if (Bank == 2'b10) Dq_dqm [15 : 0] = Bank2 [{Row, Col}];
|
||||
if (Bank == 2'b11) Dq_dqm [15 : 0] = Bank3 [{Row, Col}];
|
||||
// Dqm operation
|
||||
if (Dqm[0] == 1'b0) Dq_dqm [ 7 : 0] = Dq [ 7 : 0];
|
||||
// Write to memory
|
||||
if (Bank == 2'b00) Bank0 [{Row, Col}] = Dq_dqm [15 : 0];
|
||||
if (Bank == 2'b01) Bank1 [{Row, Col}] = Dq_dqm [15 : 0];
|
||||
if (Bank == 2'b10) Bank2 [{Row, Col}] = Dq_dqm [15 : 0];
|
||||
if (Bank == 2'b11) Bank3 [{Row, Col}] = Dq_dqm [15 : 0];
|
||||
// Output result
|
||||
if (Dqm == 1'b1) begin
|
||||
if (Debug) $display("at time %t WRITE: Bank = %d Row = %d, Col = %d, Data = Hi-Z due to DQM", $time, Bank, Row, Col);
|
||||
end else begin
|
||||
if (Debug) $display("at time %t WRITE: Bank = %d Row = %d, Col = %d, Data = %h, Dqm = %b", $time, Bank, Row, Col, Dq_dqm, Dqm);
|
||||
// Record tWR time and reset counter
|
||||
WR_chk [Bank] = $time;
|
||||
WR_counter [Bank] = 0;
|
||||
end
|
||||
// Advance burst counter subroutine
|
||||
#tHZ Burst;
|
||||
end else if (Data_out_enable == 1'b1) begin // Reading Data from Memory
|
||||
// Array buffer
|
||||
if (Bank == 2'b00) Dq_dqm [15 : 0] = Bank0 [{Row, Col}];
|
||||
if (Bank == 2'b01) Dq_dqm [15 : 0] = Bank1 [{Row, Col}];
|
||||
if (Bank == 2'b10) Dq_dqm [15 : 0] = Bank2 [{Row, Col}];
|
||||
if (Bank == 2'b11) Dq_dqm [15 : 0] = Bank3 [{Row, Col}];
|
||||
// Dqm operation
|
||||
if (Dqm_reg0[0] == 1'b1) Dq_dqm [ 7 : 0] = 8'bz;
|
||||
// Display result
|
||||
Dq_reg [15 : 0] = #tAC Dq_dqm [15 : 0];
|
||||
if (Dqm_reg0 == 1'b1) begin
|
||||
if (Debug) $display("at time %t READ : Bank = %d Row = %d, Col = %d, Data = Hi-Z due to DQM", $time, Bank, Row, Col);
|
||||
end else begin
|
||||
if (Debug) $display("at time %t READ : Bank = %d Row = %d, Col = %d, Data = %h, Dqm = %b", $time, Bank, Row, Col, Dq_reg, Dqm_reg0);
|
||||
end
|
||||
// Advance burst counter subroutine
|
||||
Burst;
|
||||
end
|
||||
end
|
||||
|
||||
// Write with Auto Precharge Calculation
|
||||
// The device start internal precharge:
|
||||
// 1. tWR Clock after last burst
|
||||
// and 2. Meet minimum tRAS requirement
|
||||
// or 3. Interrupt by a Read or Write (with or without AutoPrecharge)
|
||||
always @ (WR_counter[0]) begin
|
||||
if ((Auto_precharge[0] == 1'b1) && (Write_precharge[0] == 1'b1)) begin
|
||||
if ((($time - RAS_chk0 >= tRAS) && // Case 2
|
||||
(((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [0] >= 1) || // Case 1
|
||||
(Burst_length_2 == 1'b1 && Count_precharge [0] >= 2) ||
|
||||
(Burst_length_4 == 1'b1 && Count_precharge [0] >= 4) ||
|
||||
(Burst_length_8 == 1'b1 && Count_precharge [0] >= 8))) ||
|
||||
(RW_interrupt_write[0] == 1'b1 && WR_counter[0] >= 2)) begin // Case 3 (stop count when interrupt)
|
||||
Auto_precharge[0] = 1'b0;
|
||||
Write_precharge[0] = 1'b0;
|
||||
RW_interrupt_write[0] = 1'b0;
|
||||
#tWRa; // Wait for tWR
|
||||
Pc_b0 = 1'b1;
|
||||
Act_b0 = 1'b0;
|
||||
RP_chk0 = $time;
|
||||
if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 0", $time);
|
||||
end
|
||||
end
|
||||
end
|
||||
always @ (WR_counter[1]) begin
|
||||
if ((Auto_precharge[1] == 1'b1) && (Write_precharge[1] == 1'b1)) begin
|
||||
if ((($time - RAS_chk1 >= tRAS) &&
|
||||
(((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [1] >= 1) ||
|
||||
(Burst_length_2 == 1'b1 && Count_precharge [1] >= 2) ||
|
||||
(Burst_length_4 == 1'b1 && Count_precharge [1] >= 4) ||
|
||||
(Burst_length_8 == 1'b1 && Count_precharge [1] >= 8))) ||
|
||||
(RW_interrupt_write[1] == 1'b1 && WR_counter[1] >= 2)) begin
|
||||
Auto_precharge[1] = 1'b0;
|
||||
Write_precharge[1] = 1'b0;
|
||||
RW_interrupt_write[1] = 1'b0;
|
||||
#tWRa; // Wait for tWR
|
||||
Pc_b1 = 1'b1;
|
||||
Act_b1 = 1'b0;
|
||||
RP_chk1 = $time;
|
||||
if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 1", $time);
|
||||
end
|
||||
end
|
||||
end
|
||||
always @ (WR_counter[2]) begin
|
||||
if ((Auto_precharge[2] == 1'b1) && (Write_precharge[2] == 1'b1)) begin
|
||||
if ((($time - RAS_chk2 >= tRAS) &&
|
||||
(((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [2] >= 1) ||
|
||||
(Burst_length_2 == 1'b1 && Count_precharge [2] >= 2) ||
|
||||
(Burst_length_4 == 1'b1 && Count_precharge [2] >= 4) ||
|
||||
(Burst_length_8 == 1'b1 && Count_precharge [2] >= 8))) ||
|
||||
(RW_interrupt_write[2] == 1'b1 && WR_counter[2] >= 2)) begin
|
||||
Auto_precharge[2] = 1'b0;
|
||||
Write_precharge[2] = 1'b0;
|
||||
RW_interrupt_write[2] = 1'b0;
|
||||
#tWRa; // Wait for tWR
|
||||
Pc_b2 = 1'b1;
|
||||
Act_b2 = 1'b0;
|
||||
RP_chk2 = $time;
|
||||
if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 2", $time);
|
||||
end
|
||||
end
|
||||
end
|
||||
always @ (WR_counter[3]) begin
|
||||
if ((Auto_precharge[3] == 1'b1) && (Write_precharge[3] == 1'b1)) begin
|
||||
if ((($time - RAS_chk3 >= tRAS) &&
|
||||
(((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [3] >= 1) ||
|
||||
(Burst_length_2 == 1'b1 && Count_precharge [3] >= 2) ||
|
||||
(Burst_length_4 == 1'b1 && Count_precharge [3] >= 4) ||
|
||||
(Burst_length_8 == 1'b1 && Count_precharge [3] >= 8))) ||
|
||||
(RW_interrupt_write[3] == 1'b1 && WR_counter[3] >= 2)) begin
|
||||
Auto_precharge[3] = 1'b0;
|
||||
Write_precharge[3] = 1'b0;
|
||||
RW_interrupt_write[3] = 1'b0;
|
||||
#tWRa; // Wait for tWR
|
||||
Pc_b3 = 1'b1;
|
||||
Act_b3 = 1'b0;
|
||||
RP_chk3 = $time;
|
||||
if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 3", $time);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
task Burst;
|
||||
begin
|
||||
// Advance Burst Counter
|
||||
Burst_counter = Burst_counter + 1;
|
||||
|
||||
// Burst Type
|
||||
if (Mode_reg[3] == 1'b0) begin // Sequential Burst
|
||||
Col_temp = Col + 1;
|
||||
end else if (Mode_reg[3] == 1'b1) begin // Interleaved Burst
|
||||
Col_temp[2] = Burst_counter[2] ^ Col_brst[2];
|
||||
Col_temp[1] = Burst_counter[1] ^ Col_brst[1];
|
||||
Col_temp[0] = Burst_counter[0] ^ Col_brst[0];
|
||||
end
|
||||
|
||||
// Burst Length
|
||||
if (Burst_length_2) begin // Burst Length = 2
|
||||
Col [0] = Col_temp [0];
|
||||
end else if (Burst_length_4) begin // Burst Length = 4
|
||||
Col [1 : 0] = Col_temp [1 : 0];
|
||||
end else if (Burst_length_8) begin // Burst Length = 8
|
||||
Col [2 : 0] = Col_temp [2 : 0];
|
||||
end else begin // Burst Length = FULL
|
||||
Col = Col_temp;
|
||||
end
|
||||
|
||||
// Burst Read Single Write
|
||||
if (Write_burst_mode == 1'b1) begin
|
||||
Data_in_enable = 1'b0;
|
||||
end
|
||||
|
||||
// Data Counter
|
||||
if (Burst_length_1 == 1'b1) begin
|
||||
if (Burst_counter >= 1) begin
|
||||
Data_in_enable = 1'b0;
|
||||
Data_out_enable = 1'b0;
|
||||
end
|
||||
end else if (Burst_length_2 == 1'b1) begin
|
||||
if (Burst_counter >= 2) begin
|
||||
Data_in_enable = 1'b0;
|
||||
Data_out_enable = 1'b0;
|
||||
end
|
||||
end else if (Burst_length_4 == 1'b1) begin
|
||||
if (Burst_counter >= 4) begin
|
||||
Data_in_enable = 1'b0;
|
||||
Data_out_enable = 1'b0;
|
||||
end
|
||||
end else if (Burst_length_8 == 1'b1) begin
|
||||
if (Burst_counter >= 8) begin
|
||||
Data_in_enable = 1'b0;
|
||||
Data_out_enable = 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
// Timing Parameters for -75 (PC133) and CAS Latency = 2
|
||||
specify
|
||||
specparam
|
||||
tAH = 0.8, // Addr, Ba Hold Time
|
||||
tAS = 1.5, // Addr, Ba Setup Time
|
||||
tCH = 2.5, // Clock High-Level Width
|
||||
tCL = 2.5, // Clock Low-Level Width
|
||||
tCK = 10, // Clock Cycle Time
|
||||
tDH = 0.8, // Data-in Hold Time
|
||||
tDS = 1.5, // Data-in Setup Time
|
||||
tCKH = 0.8, // CKE Hold Time
|
||||
tCKS = 1.5, // CKE Setup Time
|
||||
tCMH = 0.8, // CS#, RAS#, CAS#, WE#, DQM# Hold Time
|
||||
tCMS = 1.5; // CS#, RAS#, CAS#, WE#, DQM# Setup Time
|
||||
$width (posedge Clk, tCH);
|
||||
$width (negedge Clk, tCL);
|
||||
$period (negedge Clk, tCK);
|
||||
$period (posedge Clk, tCK);
|
||||
$setuphold(posedge Clk, Cke, tCKS, tCKH);
|
||||
$setuphold(posedge Clk, Cs_n, tCMS, tCMH);
|
||||
$setuphold(posedge Clk, Cas_n, tCMS, tCMH);
|
||||
$setuphold(posedge Clk, Ras_n, tCMS, tCMH);
|
||||
$setuphold(posedge Clk, We_n, tCMS, tCMH);
|
||||
$setuphold(posedge Clk, Addr, tAS, tAH);
|
||||
$setuphold(posedge Clk, Ba, tAS, tAH);
|
||||
$setuphold(posedge Clk, Dqm, tCMS, tCMH);
|
||||
$setuphold(posedge Dq_chk, Dq, tDS, tDH);
|
||||
endspecify
|
||||
|
||||
endmodule
|
||||
|
107
lib/common/Driver/SDRAM_driver/synth/constraints/sdrc_synth.sdc
Normal file
107
lib/common/Driver/SDRAM_driver/synth/constraints/sdrc_synth.sdc
Normal file
@ -0,0 +1,107 @@
|
||||
# Syntheis command format
|
||||
#"-from" objects must be of type clock (c:), port (p:), inst (i:), or pin (t:)
|
||||
#
|
||||
#166MHz - Application CLOCK
|
||||
#set APP_CLK_PER 6.0
|
||||
#set APP_CLK_HALF_PER [expr APP_CLK_PER]
|
||||
|
||||
|
||||
#100MHz - SDRAM Clock
|
||||
#set SDR_CLK_PER 10.0
|
||||
#set SDI_CLK_HALF_PER [expr $SDR_CLK_PERR/2]
|
||||
|
||||
|
||||
####################################
|
||||
# Clear Application Clock : 200Mhz
|
||||
####################################
|
||||
|
||||
create_clock -name wb_clk_i -period 6 -waveform {0 3} p:wb_clk_i
|
||||
#set_clock_uncertainty -max 0.2 [get_clocks wb_clk_i]
|
||||
#set_clock_uncertainty -min 0.1 [get_clocks wb_clk_i]
|
||||
#set_clock_latency 2.0 [get_clocks wb_clk_i]
|
||||
|
||||
########################################
|
||||
# Create SDRAM Clock to 100Mhz
|
||||
########################################
|
||||
create_clock -name sdram_clk -period 10 -waveform {0 5} p:sdram_clk
|
||||
#set_clock_uncertainty -max 0.2 [get_clocks sdram_clk]
|
||||
#set_clock_uncertainty -min 0.1 [get_clocks sdram_clk]
|
||||
#set_clock_latency 2.0 [get_clocks sdram_clk]
|
||||
|
||||
|
||||
###########################################
|
||||
# Set false path between application and SDRAM Clock
|
||||
##########################################
|
||||
set_false_path -from c:wb_clk_i -to c:sdram_clk
|
||||
set_false_path -to c:wb_clk_i -from c:sdram_clk
|
||||
|
||||
|
||||
########################################
|
||||
# Set false path through reset
|
||||
########################################
|
||||
set_false_path -from p:wb_rst_i
|
||||
set_false_path -from p:sdram_resetn
|
||||
|
||||
|
||||
########################################
|
||||
# Set False path to all the configuration input
|
||||
########################################
|
||||
|
||||
#set_false_path -from p:{cfg_colbits[*] cfg_req_depth[*] cfg_sdr_cas[*]}
|
||||
#set_false_path -from p:{cfg_sdr_en cfg_sdr_mode_reg[*] cfg_sdr_rfmax[*]]
|
||||
#set_false_path -from p:{cfg_sdr_rfsh[*] cfg_sdr_tras_d[*] cfg_sdr_trcar_d[*]}
|
||||
#set_false_path -from p:{cfg_sdr_trcd_d[*] cfg_sdr_trp_d[*] cfg_sdr_twr_d[*]}
|
||||
#set_false_path -from p:cfg_sdr_width[*]
|
||||
|
||||
|
||||
########################################
|
||||
# Application Port Input Contraints
|
||||
# Since Application Signal will be internally terminated and
|
||||
# there is will not be any additional FPGA pad delay of 3ns.
|
||||
# So input delay constraint changed form 3ns to 0ns
|
||||
#
|
||||
#######################################
|
||||
#set_input_delay 3 -max [ wb_stb_i wb_addr_i wb_we_i wb_dat_i wb_sel_i wb_cyc_i wb_cti_i] -clock wb_clk_i
|
||||
set_input_delay 0 -max { wb_stb_i wb_addr_i[*] wb_we_i wb_dat_i[*] wb_sel_i[*] wb_cyc_i wb_cti_i[*]} -clock wb_clk_i
|
||||
set_input_delay 0.5 -min { wb_stb_i wb_addr_i[*] wb_we_i wb_dat_i[*] wb_sel_i[*] wb_cyc_i wb_cti_i[*]} -clock wb_clk_i
|
||||
|
||||
|
||||
########################################
|
||||
# Application Port Output Contraints
|
||||
# Since Application Signal will be internally terminstated and
|
||||
# there will not be addiitional FPGA pad delay of 3ns.
|
||||
# So output delat contraints are changed from 3ns to 0ns
|
||||
#######################################
|
||||
|
||||
#set_output_delay 3 -max [ wb_ack_o wb_dat_o ] -clock wb_clk_i
|
||||
set_output_delay 0 -max wb_ack_o -clock wb_clk_i
|
||||
set_output_delay 3 -max {wb_dat_o[*]} -clock wb_clk_i
|
||||
set_output_delay 0.5 -min wb_ack_o -clock wb_clk_i
|
||||
set_output_delay 0.5 -min {wb_dat_o[*]} -clock wb_clk_i
|
||||
|
||||
|
||||
|
||||
#######################################
|
||||
# SDRAM Input Contraints
|
||||
# 10 - 2 = 8ns
|
||||
#######################################
|
||||
|
||||
set_input_delay 5 -max {sdr_dq[*]} -clock sdram_clk
|
||||
set_input_delay 0.5 -min {sdr_dq[*]} -clock sdram_clk
|
||||
|
||||
|
||||
#######################################
|
||||
# Set the SDRAM Output delay constraints
|
||||
#######################################
|
||||
|
||||
set_output_delay 5 -max { sdr_cs_n sdr_cke sdr_ras_n sdr_cas_n sdr_we_n sdr_dqm[*] sdr_ba[*] sdr_addr[*] sdr_dq[*] } -clock sdram_clk
|
||||
set_output_delay -2 -min { sdr_cs_n sdr_cke sdr_ras_n sdr_cas_n sdr_we_n sdr_dqm[*] sdr_ba[*] sdr_addr[*] sdr_dq[*] } -clock sdram_clk
|
||||
|
||||
|
||||
|
||||
########################################
|
||||
# Misc
|
||||
#########################################
|
||||
|
||||
set_output_delay 5 -max { sdr_init_done } -clock sdram_clk
|
||||
set_output_delay -2 -min { sdr_init_done } -clock sdram_clk
|
187
lib/common/Driver/SDRAM_driver/synth/constraints/sdrc_top.sdc
Normal file
187
lib/common/Driver/SDRAM_driver/synth/constraints/sdrc_top.sdc
Normal file
@ -0,0 +1,187 @@
|
||||
# Top Level Design Parameters
|
||||
|
||||
# Clocks
|
||||
|
||||
create_clock -period 6.000000 -waveform {0.000000 3.000000} wb_clk_i
|
||||
create_clock -period 10.000000 -waveform {0.000000 5.000000} sdram_clk
|
||||
|
||||
# False Paths Between Clocks
|
||||
|
||||
|
||||
# False Path Constraints
|
||||
|
||||
set_false_path -from {wb_rst_i} -to {*}
|
||||
set_false_path -from {sdram_resetn} -to {*}
|
||||
|
||||
# Maximum Delay Constraints
|
||||
|
||||
|
||||
# Multicycle Constraints
|
||||
|
||||
|
||||
# Virtual Clocks
|
||||
# Output Load Constraints
|
||||
# Driving Cell Constraints
|
||||
# Wire Loads
|
||||
# set_wire_load_mode top
|
||||
|
||||
# Other Constraints
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_stb_i}
|
||||
set_output_delay 0.000 -clock {wb_clk_i} {wb_ack_o}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[0]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[1]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[2]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[3]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[4]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[5]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[6]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[7]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[8]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[9]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[10]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[11]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[12]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[13]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[14]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[15]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[16]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[17]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[18]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[19]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[20]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[21]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[22]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[23]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[24]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[25]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[26]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[27]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[28]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_addr_i[29]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_we_i}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[0]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[1]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[2]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[3]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[4]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[5]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[6]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[7]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[8]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[9]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[10]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[11]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[12]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[13]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[14]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[15]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[16]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[17]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[18]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[19]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[20]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[21]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[22]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[23]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[24]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[25]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[26]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[27]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[28]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[29]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[30]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_dat_i[31]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_sel_i[0]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_sel_i[1]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_sel_i[2]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_sel_i[3]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[0]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[1]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[2]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[3]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[4]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[5]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[6]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[7]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[8]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[9]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[10]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[11]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[12]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[13]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[14]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[15]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[16]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[17]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[18]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[19]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[20]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[21]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[22]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[23]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[24]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[25]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[26]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[27]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[28]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[29]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[30]}
|
||||
set_output_delay 3.000 -clock {wb_clk_i} {wb_dat_o[31]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_cyc_i}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_cti_i[0]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_cti_i[1]}
|
||||
set_input_delay 0.000 -clock {wb_clk_i} {wb_cti_i[2]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_cs_n}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_cke}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_ras_n}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_cas_n}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_we_n}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_dqm[0]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_dqm[1]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_ba[0]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_ba[1]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_addr[0]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_addr[1]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_addr[2]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_addr[3]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_addr[4]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_addr[5]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_addr[6]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_addr[7]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_addr[8]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_addr[9]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_addr[10]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_addr[11]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_dq[0]}
|
||||
set_input_delay 5.000 -clock {sdram_clk} {sdr_dq[0]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_dq[1]}
|
||||
set_input_delay 5.000 -clock {sdram_clk} {sdr_dq[1]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_dq[2]}
|
||||
set_input_delay 5.000 -clock {sdram_clk} {sdr_dq[2]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_dq[3]}
|
||||
set_input_delay 5.000 -clock {sdram_clk} {sdr_dq[3]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_dq[4]}
|
||||
set_input_delay 5.000 -clock {sdram_clk} {sdr_dq[4]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_dq[5]}
|
||||
set_input_delay 5.000 -clock {sdram_clk} {sdr_dq[5]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_dq[6]}
|
||||
set_input_delay 5.000 -clock {sdram_clk} {sdr_dq[6]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_dq[7]}
|
||||
set_input_delay 5.000 -clock {sdram_clk} {sdr_dq[7]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_dq[8]}
|
||||
set_input_delay 5.000 -clock {sdram_clk} {sdr_dq[8]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_dq[9]}
|
||||
set_input_delay 5.000 -clock {sdram_clk} {sdr_dq[9]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_dq[10]}
|
||||
set_input_delay 5.000 -clock {sdram_clk} {sdr_dq[10]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_dq[11]}
|
||||
set_input_delay 5.000 -clock {sdram_clk} {sdr_dq[11]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_dq[12]}
|
||||
set_input_delay 5.000 -clock {sdram_clk} {sdr_dq[12]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_dq[13]}
|
||||
set_input_delay 5.000 -clock {sdram_clk} {sdr_dq[13]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_dq[14]}
|
||||
set_input_delay 5.000 -clock {sdram_clk} {sdr_dq[14]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_dq[15]}
|
||||
set_input_delay 5.000 -clock {sdram_clk} {sdr_dq[15]}
|
||||
set_output_delay 5.000 -clock {sdram_clk} {sdr_init_done}
|
535
lib/common/Driver/SDRAM_driver/tb/tb_core.sv
Normal file
535
lib/common/Driver/SDRAM_driver/tb/tb_core.sv
Normal file
@ -0,0 +1,535 @@
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// ////
|
||||
//// This file is part of the SDRAM Controller project ////
|
||||
//// http://www.opencores.org/cores/sdr_ctrl/ ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// SDRAM CTRL definitions. ////
|
||||
//// ////
|
||||
//// To Do: ////
|
||||
//// nothing ////
|
||||
// Version :0.1 - Test Bench automation is improvised with ////
|
||||
// seperate data,address,burst length fifo. ////
|
||||
// Now user can create different write and ////
|
||||
// read sequence ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Dinesh Annayya, dinesha@opencores.org ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from http://www.opencores.org/lgpl.shtml ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This testbench stand-alone verify the sdram core
|
||||
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module tb_core;
|
||||
|
||||
parameter P_SYS = 10; // 100MHz
|
||||
|
||||
// General
|
||||
reg RESETN;
|
||||
reg sdram_clk;
|
||||
|
||||
initial sdram_clk = 0;
|
||||
|
||||
always #(P_SYS/2) sdram_clk = !sdram_clk;
|
||||
|
||||
parameter dw = 32; // data width
|
||||
parameter tw = 8; // tag id width
|
||||
parameter bl = 5; // burst_lenght_width
|
||||
|
||||
//-------------------------------------------
|
||||
// Application Interface bus
|
||||
//-------------------------------------------
|
||||
reg app_req ; // Application Request
|
||||
reg [8:0] app_req_len ; // Burst Request length
|
||||
wire app_req_ack ; // Application Request Ack
|
||||
reg [25:0] app_req_addr ; // Application Address
|
||||
reg app_req_wr_n ; // 1 -> Read, 0 -> Write
|
||||
reg [dw-1:0] app_wr_data ; // Write Data
|
||||
reg [dw/8-1:0] app_wr_en_n ; // Write Enable, Active Low
|
||||
wire app_rd_valid ; // Read Valid
|
||||
wire app_last_rd ; // Last Read Valid
|
||||
wire app_last_wr ; // Last Write Valid
|
||||
wire [dw-1:0] app_rd_data ; // Read Data
|
||||
|
||||
//--------------------------------------------
|
||||
// SDRAM I/F
|
||||
//--------------------------------------------
|
||||
|
||||
`ifdef SDR_32BIT
|
||||
wire [31:0] Dq ; // SDRAM Read/Write Data Bus
|
||||
wire [31:0] sdr_dout ; // SDRAM Data Out
|
||||
wire [31:0] pad_sdr_din ; // SDRAM Data Input
|
||||
wire [3:0] sdr_den_n ; // SDRAM Data Enable
|
||||
wire [3:0] sdr_dqm ; // SDRAM DATA Mask
|
||||
`elsif SDR_16BIT
|
||||
wire [15:0] Dq ; // SDRAM Read/Write Data Bus
|
||||
wire [15:0] sdr_dout ; // SDRAM Data Out
|
||||
wire [15:0] pad_sdr_din ; // SDRAM Data Input
|
||||
wire [1:0] sdr_den_n ; // SDRAM Data Enable
|
||||
wire [1:0] sdr_dqm ; // SDRAM DATA Mask
|
||||
`else
|
||||
wire [7:0] Dq ; // SDRAM Read/Write Data Bus
|
||||
wire [7:0] sdr_dout ; // SDRAM Data Out
|
||||
wire [7:0] pad_sdr_din ; // SDRAM Data Input
|
||||
wire [0:0] sdr_den_n ; // SDRAM Data Enable
|
||||
wire [0:0] sdr_dqm ; // SDRAM DATA Mask
|
||||
`endif
|
||||
|
||||
wire [1:0] sdr_ba ; // SDRAM Bank Select
|
||||
wire [12:0] sdr_addr ; // SDRAM ADRESS
|
||||
wire sdr_init_done ; // SDRAM Init Done
|
||||
|
||||
// to fix the sdram interface timing issue
|
||||
wire #(2.0) sdram_clk_d = sdram_clk;
|
||||
wire #(1.0) pad_clk = sdram_clk_d;
|
||||
|
||||
`ifdef SDR_32BIT
|
||||
|
||||
sdrc_core #(.SDR_DW(32),.SDR_BW(4)) u_dut(
|
||||
`elsif SDR_16BIT
|
||||
sdrc_core #(.SDR_DW(16),.SDR_BW(2)) u_dut(
|
||||
`else // 8 BIT SDRAM
|
||||
sdrc_core #(.SDR_DW(8),.SDR_BW(1)) u_dut(
|
||||
`endif
|
||||
// System
|
||||
.clk (sdram_clk ),
|
||||
.reset_n (RESETN ),
|
||||
.pad_clk (pad_clk ),
|
||||
`ifdef SDR_32BIT
|
||||
.sdr_width (2'b00 ), // 32 BIT SDRAM
|
||||
`elsif SDR_16BIT
|
||||
.sdr_width (2'b01 ), // 16 BIT SDRAM
|
||||
`else
|
||||
.sdr_width (2'b10 ), // 8 BIT SDRAM
|
||||
`endif
|
||||
.cfg_colbits (2'b00 ), // 8 Bit Column Address
|
||||
|
||||
|
||||
/* Request from app */
|
||||
.app_req (app_req ), // Transfer Request
|
||||
.app_req_addr (app_req_addr ), // SDRAM Address
|
||||
.app_req_len (app_req_len ), // Burst Length (in 16 bit words)
|
||||
.app_req_wrap (1'b0 ), // Wrap mode request (xfr_len = 4)
|
||||
.app_req_wr_n (app_req_wr_n ), // 0 => Write request, 1 => read req
|
||||
.app_req_ack (app_req_ack ), // Request has been accepted
|
||||
|
||||
.app_wr_data (app_wr_data ),
|
||||
.app_wr_en_n (app_wr_en_n ),
|
||||
.app_rd_data (app_rd_data ),
|
||||
.app_last_rd (app_last_rd ),
|
||||
.app_last_wr (app_last_wr ),
|
||||
.app_rd_valid (app_rd_valid ),
|
||||
.app_wr_next_req (app_wr_next_req ),
|
||||
.app_req_dma_last (app_req ),
|
||||
|
||||
/* Interface to SDRAMs */
|
||||
.sdr_cs_n (sdr_cs_n ),
|
||||
.sdr_cke (sdr_cke ),
|
||||
.sdr_ras_n (sdr_ras_n ),
|
||||
.sdr_cas_n (sdr_cas_n ),
|
||||
.sdr_we_n (sdr_we_n ),
|
||||
.sdr_dqm (sdr_dqm ),
|
||||
.sdr_ba (sdr_ba ),
|
||||
.sdr_addr (sdr_addr ),
|
||||
.pad_sdr_din (Dq ),
|
||||
.sdr_dout (sdr_dout ),
|
||||
.sdr_den_n (sdr_den_n ),
|
||||
|
||||
/* Parameters */
|
||||
.sdr_init_done (sdr_init_done ),
|
||||
.cfg_req_depth (2'h3 ), //how many req. buffer should hold
|
||||
.cfg_sdr_en (1'b1 ),
|
||||
.cfg_sdr_mode_reg (13'h033 ),
|
||||
.cfg_sdr_tras_d (4'h4 ),
|
||||
.cfg_sdr_trp_d (4'h2 ),
|
||||
.cfg_sdr_trcd_d (4'h2 ),
|
||||
.cfg_sdr_cas (3'h3 ),
|
||||
.cfg_sdr_trcar_d (4'h7 ),
|
||||
.cfg_sdr_twr_d (4'h1 ),
|
||||
.cfg_sdr_rfsh (12'h100 ), // reduced from 12'hC35
|
||||
.cfg_sdr_rfmax (3'h6 )
|
||||
|
||||
);
|
||||
|
||||
|
||||
`ifdef SDR_32BIT
|
||||
assign Dq[7:0] = (sdr_den_n[0] == 1'b0) ? sdr_dout[7:0] : 8'hZZ;
|
||||
assign Dq[15:8] = (sdr_den_n[1] == 1'b0) ? sdr_dout[15:8] : 8'hZZ;
|
||||
assign Dq[23:16] = (sdr_den_n[2] == 1'b0) ? sdr_dout[23:16] : 8'hZZ;
|
||||
assign Dq[31:24] = (sdr_den_n[3] == 1'b0) ? sdr_dout[31:24] : 8'hZZ;
|
||||
mt48lc2m32b2 #(.data_bits(32)) u_sdram32 (
|
||||
.Dq (Dq ) ,
|
||||
.Addr (sdr_addr[10:0] ),
|
||||
.Ba (sdr_ba ),
|
||||
.Clk (sdram_clk_d ),
|
||||
.Cke (sdr_cke ),
|
||||
.Cs_n (sdr_cs_n ),
|
||||
.Ras_n (sdr_ras_n ),
|
||||
.Cas_n (sdr_cas_n ),
|
||||
.We_n (sdr_we_n ),
|
||||
.Dqm (sdr_dqm )
|
||||
);
|
||||
|
||||
`elsif SDR_16BIT
|
||||
|
||||
assign Dq[7:0] = (sdr_den_n[0] == 1'b0) ? sdr_dout[7:0] : 8'hZZ;
|
||||
assign Dq[15:8] = (sdr_den_n[1] == 1'b0) ? sdr_dout[15:8] : 8'hZZ;
|
||||
|
||||
IS42VM16400K u_sdram16 (
|
||||
.dq (Dq ),
|
||||
.addr (sdr_addr[11:0] ),
|
||||
.ba (sdr_ba ),
|
||||
.clk (sdram_clk_d ),
|
||||
.cke (sdr_cke ),
|
||||
.csb (sdr_cs_n ),
|
||||
.rasb (sdr_ras_n ),
|
||||
.casb (sdr_cas_n ),
|
||||
.web (sdr_we_n ),
|
||||
.dqm (sdr_dqm )
|
||||
);
|
||||
`else
|
||||
|
||||
assign Dq[7:0] = (sdr_den_n[0] == 1'b0) ? sdr_dout[7:0] : 8'hZZ;
|
||||
|
||||
mt48lc8m8a2 #(.data_bits(8)) u_sdram8 (
|
||||
.Dq (Dq ) ,
|
||||
.Addr (sdr_addr[11:0] ),
|
||||
.Ba (sdr_ba ),
|
||||
.Clk (sdram_clk_d ),
|
||||
.Cke (sdr_cke ),
|
||||
.Cs_n (sdr_cs_n ),
|
||||
.Ras_n (sdr_ras_n ),
|
||||
.Cas_n (sdr_cas_n ),
|
||||
.We_n (sdr_we_n ),
|
||||
.Dqm (sdr_dqm )
|
||||
);
|
||||
`endif
|
||||
|
||||
//--------------------
|
||||
// data/address/burst length FIFO
|
||||
//--------------------
|
||||
int dfifo[$]; // data fifo
|
||||
int afifo[$]; // address fifo
|
||||
int bfifo[$]; // Burst Length fifo
|
||||
|
||||
reg [31:0] read_data;
|
||||
reg [31:0] ErrCnt;
|
||||
int k;
|
||||
reg [31:0] StartAddr;
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Test Case
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
initial begin //{
|
||||
ErrCnt = 0;
|
||||
app_req_addr = 0;
|
||||
app_wr_data = 0;
|
||||
app_wr_en_n = 4'hF;
|
||||
app_req_wr_n = 0;
|
||||
app_req = 0;
|
||||
app_req_len = 0;
|
||||
|
||||
RESETN = 1'h1;
|
||||
|
||||
#100
|
||||
// Applying reset
|
||||
RESETN = 1'h0;
|
||||
#10000;
|
||||
// Releasing reset
|
||||
RESETN = 1'h1;
|
||||
#1000;
|
||||
wait(u_dut.sdr_init_done == 1);
|
||||
|
||||
#1000;
|
||||
$display("-------------------------------------- ");
|
||||
$display(" Case-1: Single Write/Read Case ");
|
||||
$display("-------------------------------------- ");
|
||||
|
||||
burst_write(32'h4_0000,8'h4);
|
||||
#1000;
|
||||
burst_read();
|
||||
|
||||
// Repeat one more time to analysis the
|
||||
// SDRAM state change for same col/row address
|
||||
$display("-------------------------------------- ");
|
||||
$display(" Case-2: Repeat same transfer once again ");
|
||||
$display("----------------------------------------");
|
||||
burst_write(32'h4_0000,8'h4);
|
||||
burst_read();
|
||||
burst_write(32'h0040_0000,8'h5);
|
||||
burst_read();
|
||||
$display("----------------------------------------");
|
||||
$display(" Case-3 Create a Page Cross Over ");
|
||||
$display("----------------------------------------");
|
||||
burst_write(32'h0000_0FF0,8'h8);
|
||||
burst_write(32'h0001_0FF4,8'hF);
|
||||
burst_write(32'h0002_0FF8,8'hF);
|
||||
burst_write(32'h0003_0FFC,8'hF);
|
||||
burst_write(32'h0004_0FE0,8'hF);
|
||||
burst_write(32'h0005_0FE4,8'hF);
|
||||
burst_write(32'h0006_0FE8,8'hF);
|
||||
burst_write(32'h0007_0FEC,8'hF);
|
||||
burst_write(32'h0008_0FD0,8'hF);
|
||||
burst_write(32'h0009_0FD4,8'hF);
|
||||
burst_write(32'h000A_0FD8,8'hF);
|
||||
burst_write(32'h000B_0FDC,8'hF);
|
||||
burst_write(32'h000C_0FC0,8'hF);
|
||||
burst_write(32'h000D_0FC4,8'hF);
|
||||
burst_write(32'h000E_0FC8,8'hF);
|
||||
burst_write(32'h000F_0FCC,8'hF);
|
||||
burst_write(32'h0010_0FB0,8'hF);
|
||||
burst_write(32'h0011_0FB4,8'hF);
|
||||
burst_write(32'h0012_0FB8,8'hF);
|
||||
burst_write(32'h0013_0FBC,8'hF);
|
||||
burst_write(32'h0014_0FA0,8'hF);
|
||||
burst_write(32'h0015_0FA4,8'hF);
|
||||
burst_write(32'h0016_0FA8,8'hF);
|
||||
burst_write(32'h0017_0FAC,8'hF);
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
|
||||
$display("----------------------------------------");
|
||||
$display(" Case:4 4 Write & 4 Read ");
|
||||
$display("----------------------------------------");
|
||||
burst_write(32'h4_0000,8'h4);
|
||||
burst_write(32'h5_0000,8'h5);
|
||||
burst_write(32'h6_0000,8'h6);
|
||||
burst_write(32'h7_0000,8'h7);
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
|
||||
$display("---------------------------------------");
|
||||
$display(" Case:5 24 Write & 24 Read With Different Bank and Row ");
|
||||
$display("---------------------------------------");
|
||||
//----------------------------------------
|
||||
// Address Decodeing:
|
||||
// with cfg_col bit configured as: 00
|
||||
// <12 Bit Row> <2 Bit Bank> <8 Bit Column> <2'b00>
|
||||
//
|
||||
burst_write({12'h000,2'b00,8'h00,2'b00},8'h4); // Row: 0 Bank : 0
|
||||
burst_write({12'h000,2'b01,8'h00,2'b00},8'h5); // Row: 0 Bank : 1
|
||||
burst_write({12'h000,2'b10,8'h00,2'b00},8'h6); // Row: 0 Bank : 2
|
||||
burst_write({12'h000,2'b11,8'h00,2'b00},8'h7); // Row: 0 Bank : 3
|
||||
burst_write({12'h001,2'b00,8'h00,2'b00},8'h4); // Row: 1 Bank : 0
|
||||
burst_write({12'h001,2'b01,8'h00,2'b00},8'h5); // Row: 1 Bank : 1
|
||||
burst_write({12'h001,2'b10,8'h00,2'b00},8'h6); // Row: 1 Bank : 2
|
||||
burst_write({12'h001,2'b11,8'h00,2'b00},8'h7); // Row: 1 Bank : 3
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
|
||||
burst_write({12'h002,2'b00,8'h00,2'b00},8'h4); // Row: 2 Bank : 0
|
||||
burst_write({12'h002,2'b01,8'h00,2'b00},8'h5); // Row: 2 Bank : 1
|
||||
burst_write({12'h002,2'b10,8'h00,2'b00},8'h6); // Row: 2 Bank : 2
|
||||
burst_write({12'h002,2'b11,8'h00,2'b00},8'h7); // Row: 2 Bank : 3
|
||||
burst_write({12'h003,2'b00,8'h00,2'b00},8'h4); // Row: 3 Bank : 0
|
||||
burst_write({12'h003,2'b01,8'h00,2'b00},8'h5); // Row: 3 Bank : 1
|
||||
burst_write({12'h003,2'b10,8'h00,2'b00},8'h6); // Row: 3 Bank : 2
|
||||
burst_write({12'h003,2'b11,8'h00,2'b00},8'h7); // Row: 3 Bank : 3
|
||||
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
|
||||
|
||||
burst_write({12'h002,2'b00,8'h00,2'b00},8'h4); // Row: 2 Bank : 0
|
||||
burst_write({12'h002,2'b01,8'h01,2'b00},8'h5); // Row: 2 Bank : 1
|
||||
burst_write({12'h002,2'b10,8'h02,2'b00},8'h6); // Row: 2 Bank : 2
|
||||
burst_write({12'h002,2'b11,8'h03,2'b00},8'h7); // Row: 2 Bank : 3
|
||||
burst_write({12'h003,2'b00,8'h04,2'b00},8'h4); // Row: 3 Bank : 0
|
||||
burst_write({12'h003,2'b01,8'h05,2'b00},8'h5); // Row: 3 Bank : 1
|
||||
burst_write({12'h003,2'b10,8'h06,2'b00},8'h6); // Row: 3 Bank : 2
|
||||
burst_write({12'h003,2'b11,8'h07,2'b00},8'h7); // Row: 3 Bank : 3
|
||||
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
|
||||
$display("---------------------------------------------------");
|
||||
$display(" Case: 6 Random 2 write and 2 read random");
|
||||
$display("---------------------------------------------------");
|
||||
for(k=0; k < 20; k++) begin
|
||||
StartAddr = $random & 32'h003FFFFF;
|
||||
burst_write(StartAddr,($random & 8'h0f)+1);
|
||||
#100;
|
||||
|
||||
StartAddr = $random & 32'h003FFFFF;
|
||||
burst_write(StartAddr,($random & 8'h0f)+1);
|
||||
#100;
|
||||
burst_read();
|
||||
#100;
|
||||
burst_read();
|
||||
#100;
|
||||
end
|
||||
|
||||
|
||||
#10000;
|
||||
|
||||
$display("###############################");
|
||||
if(ErrCnt == 0)
|
||||
$display("STATUS: SDRAM Write/Read TEST PASSED");
|
||||
else
|
||||
$display("ERROR: SDRAM Write/Read TEST FAILED");
|
||||
$display("###############################");
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
|
||||
task burst_write;
|
||||
input [31:0] Address;
|
||||
input [7:0] bl;
|
||||
int i;
|
||||
begin
|
||||
afifo.push_back(Address);
|
||||
bfifo.push_back(bl);
|
||||
|
||||
@ (negedge sdram_clk);
|
||||
app_req = 1;
|
||||
app_wr_en_n = 0;
|
||||
app_req_wr_n = 1'b0;
|
||||
app_req_addr = Address[31:2];
|
||||
app_req_len = bl;
|
||||
$display("Write Address: %x, Burst Size: %d",Address,bl);
|
||||
|
||||
// wait for app_req_ack == 1
|
||||
do begin
|
||||
@ (posedge sdram_clk);
|
||||
end while(app_req_ack == 1'b0);
|
||||
@ (negedge sdram_clk);
|
||||
app_req = 0;
|
||||
|
||||
for(i=0; i < bl; i++) begin
|
||||
app_wr_data = $random & 32'hFFFFFFFF;
|
||||
dfifo.push_back(app_wr_data);
|
||||
|
||||
do begin
|
||||
@ (posedge sdram_clk);
|
||||
end while(app_wr_next_req == 1'b0);
|
||||
@ (negedge sdram_clk);
|
||||
|
||||
$display("Status: Burst-No: %d Write Address: %x WriteData: %x ",i,Address,app_wr_data);
|
||||
end
|
||||
app_req = 0;
|
||||
app_wr_en_n = 'hx;
|
||||
app_req_wr_n = 'hx;
|
||||
app_req_addr = 'hx;
|
||||
app_req_len = 'hx;
|
||||
|
||||
|
||||
end
|
||||
endtask
|
||||
|
||||
task burst_read;
|
||||
reg [31:0] Address;
|
||||
reg [7:0] bl;
|
||||
|
||||
int i,j;
|
||||
reg [31:0] exp_data;
|
||||
begin
|
||||
|
||||
Address = afifo.pop_front();
|
||||
bl = bfifo.pop_front();
|
||||
|
||||
@ (negedge sdram_clk);
|
||||
app_req = 1;
|
||||
app_wr_en_n = 0;
|
||||
app_req_wr_n = 1;
|
||||
app_req_addr = Address[29:2];
|
||||
app_req_len = bl;
|
||||
|
||||
// wait for app_req_ack == 1
|
||||
do begin
|
||||
@ (posedge sdram_clk);
|
||||
end while(app_req_ack == 1'b0);
|
||||
@ (negedge sdram_clk);
|
||||
app_req = 0;
|
||||
app_wr_en_n = 'hx;
|
||||
app_req_wr_n = 'hx;
|
||||
app_req_addr = 'hx;
|
||||
app_req_len = 'hx;
|
||||
|
||||
for(j=0; j < bl; j++) begin
|
||||
wait(app_rd_valid == 1);
|
||||
exp_data = dfifo.pop_front(); // Exptected Read Data
|
||||
if(app_rd_data !== exp_data) begin
|
||||
$display("READ ERROR: Burst-No: %d Addr: %x Rxp: %x Exd: %x",j,Address+(j*2),app_rd_data,exp_data);
|
||||
ErrCnt = ErrCnt+1;
|
||||
end else begin
|
||||
$display("READ STATUS: Burst-No: %d Addr: %x Rxd: %x",j,Address+(j*2),app_rd_data);
|
||||
end
|
||||
@ (posedge sdram_clk);
|
||||
@ (negedge sdram_clk);
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
|
||||
endmodule
|
500
lib/common/Driver/SDRAM_driver/tb/tb_top.sv
Normal file
500
lib/common/Driver/SDRAM_driver/tb/tb_top.sv
Normal file
@ -0,0 +1,500 @@
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// ////
|
||||
//// This file is part of the SDRAM Controller project ////
|
||||
//// http://www.opencores.org/cores/sdr_ctrl/ ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// SDRAM CTRL definitions. ////
|
||||
//// ////
|
||||
//// To Do: ////
|
||||
//// nothing ////
|
||||
//// ////
|
||||
// Version :0.1 - Test Bench automation is improvised with ////
|
||||
// seperate data,address,burst length fifo. ////
|
||||
// Now user can create different write and ////
|
||||
// read sequence ////
|
||||
// ////
|
||||
//// Author(s): ////
|
||||
//// - Dinesh Annayya, dinesha@opencores.org ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from http://www.opencores.org/lgpl.shtml ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
`timescale 1ns/1ps
|
||||
|
||||
// This testbench verify with SDRAM TOP
|
||||
|
||||
module tb_top;
|
||||
|
||||
parameter P_SYS = 10; // 200MHz
|
||||
parameter P_SDR = 20; // 100MHz
|
||||
|
||||
// General
|
||||
reg RESETN;
|
||||
reg sdram_clk;
|
||||
reg sys_clk;
|
||||
|
||||
initial sys_clk = 0;
|
||||
initial sdram_clk = 0;
|
||||
|
||||
always #(P_SYS/2) sys_clk = !sys_clk;
|
||||
always #(P_SDR/2) sdram_clk = !sdram_clk;
|
||||
|
||||
parameter dw = 32; // data width
|
||||
parameter tw = 8; // tag id width
|
||||
parameter bl = 5; // burst_lenght_width
|
||||
|
||||
//-------------------------------------------
|
||||
// WISH BONE Interface
|
||||
//-------------------------------------------
|
||||
//--------------------------------------
|
||||
// Wish Bone Interface
|
||||
// -------------------------------------
|
||||
reg wb_stb_i ;
|
||||
wire wb_ack_o ;
|
||||
reg [25:0] wb_addr_i ;
|
||||
reg wb_we_i ; // 1 - Write, 0 - Read
|
||||
reg [dw-1:0] wb_dat_i ;
|
||||
reg [dw/8-1:0] wb_sel_i ; // Byte enable
|
||||
wire [dw-1:0] wb_dat_o ;
|
||||
reg wb_cyc_i ;
|
||||
reg [2:0] wb_cti_i ;
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------
|
||||
// SDRAM I/F
|
||||
//--------------------------------------------
|
||||
|
||||
`ifdef SDR_32BIT
|
||||
wire [31:0] Dq ; // SDRAM Read/Write Data Bus
|
||||
wire [3:0] sdr_dqm ; // SDRAM DATA Mask
|
||||
`elsif SDR_16BIT
|
||||
wire [15:0] Dq ; // SDRAM Read/Write Data Bus
|
||||
wire [1:0] sdr_dqm ; // SDRAM DATA Mask
|
||||
`else
|
||||
wire [7:0] Dq ; // SDRAM Read/Write Data Bus
|
||||
wire [0:0] sdr_dqm ; // SDRAM DATA Mask
|
||||
`endif
|
||||
|
||||
wire [1:0] sdr_ba ; // SDRAM Bank Select
|
||||
wire [12:0] sdr_addr ; // SDRAM ADRESS
|
||||
wire sdr_init_done ; // SDRAM Init Done
|
||||
|
||||
// to fix the sdram interface timing issue
|
||||
wire #(2.0) sdram_clk_d = sdram_clk;
|
||||
|
||||
`ifdef SDR_32BIT
|
||||
|
||||
sdrc_top #(.SDR_DW(32),.SDR_BW(4)) u_dut(
|
||||
`elsif SDR_16BIT
|
||||
sdrc_top #(.SDR_DW(16),.SDR_BW(2)) u_dut(
|
||||
`else // 8 BIT SDRAM
|
||||
sdrc_top #(.SDR_DW(8),.SDR_BW(1)) u_dut(
|
||||
`endif
|
||||
// System
|
||||
`ifdef SDR_32BIT
|
||||
.cfg_sdr_width (2'b00 ), // 32 BIT SDRAM
|
||||
`elsif SDR_16BIT
|
||||
.cfg_sdr_width (2'b01 ), // 16 BIT SDRAM
|
||||
`else
|
||||
.cfg_sdr_width (2'b10 ), // 8 BIT SDRAM
|
||||
`endif
|
||||
.cfg_colbits (2'b00 ), // 8 Bit Column Address
|
||||
|
||||
/* WISH BONE */
|
||||
.wb_rst_i (!RESETN ),
|
||||
.wb_clk_i (sys_clk ),
|
||||
|
||||
.wb_stb_i (wb_stb_i ),
|
||||
.wb_ack_o (wb_ack_o ),
|
||||
.wb_addr_i (wb_addr_i ),
|
||||
.wb_we_i (wb_we_i ),
|
||||
.wb_dat_i (wb_dat_i ),
|
||||
.wb_sel_i (wb_sel_i ),
|
||||
.wb_dat_o (wb_dat_o ),
|
||||
.wb_cyc_i (wb_cyc_i ),
|
||||
.wb_cti_i (wb_cti_i ),
|
||||
|
||||
/* Interface to SDRAMs */
|
||||
.sdram_clk (sdram_clk ),
|
||||
.sdram_resetn (RESETN ),
|
||||
.sdr_cs_n (sdr_cs_n ),
|
||||
.sdr_cke (sdr_cke ),
|
||||
.sdr_ras_n (sdr_ras_n ),
|
||||
.sdr_cas_n (sdr_cas_n ),
|
||||
.sdr_we_n (sdr_we_n ),
|
||||
.sdr_dqm (sdr_dqm ),
|
||||
.sdr_ba (sdr_ba ),
|
||||
.sdr_addr (sdr_addr ),
|
||||
.sdr_dq (Dq ),
|
||||
|
||||
/* Parameters */
|
||||
.sdr_init_done (sdr_init_done ),
|
||||
.cfg_req_depth (2'h3 ), //how many req. buffer should hold
|
||||
.cfg_sdr_en (1'b1 ),
|
||||
.cfg_sdr_mode_reg (13'h033 ),
|
||||
.cfg_sdr_tras_d (4'h4 ),
|
||||
.cfg_sdr_trp_d (4'h2 ),
|
||||
.cfg_sdr_trcd_d (4'h2 ),
|
||||
.cfg_sdr_cas (3'h3 ),
|
||||
.cfg_sdr_trcar_d (4'h7 ),
|
||||
.cfg_sdr_twr_d (4'h1 ),
|
||||
.cfg_sdr_rfsh (12'h100 ), // reduced from 12'hC35
|
||||
.cfg_sdr_rfmax (3'h6 )
|
||||
|
||||
);
|
||||
|
||||
|
||||
`ifdef SDR_32BIT
|
||||
mt48lc2m32b2 #(.data_bits(32)) u_sdram32 (
|
||||
.Dq (Dq ) ,
|
||||
.Addr (sdr_addr[10:0] ),
|
||||
.Ba (sdr_ba ),
|
||||
.Clk (sdram_clk_d ),
|
||||
.Cke (sdr_cke ),
|
||||
.Cs_n (sdr_cs_n ),
|
||||
.Ras_n (sdr_ras_n ),
|
||||
.Cas_n (sdr_cas_n ),
|
||||
.We_n (sdr_we_n ),
|
||||
.Dqm (sdr_dqm )
|
||||
);
|
||||
|
||||
`elsif SDR_16BIT
|
||||
|
||||
IS42VM16400K u_sdram16 (
|
||||
.dq (Dq ),
|
||||
.addr (sdr_addr[11:0] ),
|
||||
.ba (sdr_ba ),
|
||||
.clk (sdram_clk_d ),
|
||||
.cke (sdr_cke ),
|
||||
.csb (sdr_cs_n ),
|
||||
.rasb (sdr_ras_n ),
|
||||
.casb (sdr_cas_n ),
|
||||
.web (sdr_we_n ),
|
||||
.dqm (sdr_dqm )
|
||||
);
|
||||
`else
|
||||
|
||||
|
||||
mt48lc8m8a2 #(.data_bits(8)) u_sdram8 (
|
||||
.Dq (Dq ) ,
|
||||
.Addr (sdr_addr[11:0] ),
|
||||
.Ba (sdr_ba ),
|
||||
.Clk (sdram_clk_d ),
|
||||
.Cke (sdr_cke ),
|
||||
.Cs_n (sdr_cs_n ),
|
||||
.Ras_n (sdr_ras_n ),
|
||||
.Cas_n (sdr_cas_n ),
|
||||
.We_n (sdr_we_n ),
|
||||
.Dqm (sdr_dqm )
|
||||
);
|
||||
`endif
|
||||
|
||||
//--------------------
|
||||
// data/address/burst length FIFO
|
||||
//--------------------
|
||||
int dfifo[$]; // data fifo
|
||||
int afifo[$]; // address fifo
|
||||
int bfifo[$]; // Burst Length fifo
|
||||
|
||||
reg [31:0] read_data;
|
||||
reg [31:0] ErrCnt;
|
||||
int k;
|
||||
reg [31:0] StartAddr;
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Test Case
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
initial begin //{
|
||||
ErrCnt = 0;
|
||||
wb_addr_i = 0;
|
||||
wb_dat_i = 0;
|
||||
wb_sel_i = 4'h0;
|
||||
wb_we_i = 0;
|
||||
wb_stb_i = 0;
|
||||
wb_cyc_i = 0;
|
||||
|
||||
RESETN = 1'h1;
|
||||
|
||||
#100
|
||||
// Applying reset
|
||||
RESETN = 1'h0;
|
||||
#10000;
|
||||
// Releasing reset
|
||||
RESETN = 1'h1;
|
||||
#1000;
|
||||
wait(u_dut.sdr_init_done == 1);
|
||||
|
||||
#1000;
|
||||
$display("-------------------------------------- ");
|
||||
$display(" Case-1: Single Write/Read Case ");
|
||||
$display("-------------------------------------- ");
|
||||
|
||||
burst_write(32'h4_0000,8'h4);
|
||||
#1000;
|
||||
burst_read();
|
||||
|
||||
// Repeat one more time to analysis the
|
||||
// SDRAM state change for same col/row address
|
||||
$display("-------------------------------------- ");
|
||||
$display(" Case-2: Repeat same transfer once again ");
|
||||
$display("----------------------------------------");
|
||||
burst_write(32'h4_0000,8'h4);
|
||||
burst_read();
|
||||
burst_write(32'h0040_0000,8'h5);
|
||||
burst_read();
|
||||
$display("----------------------------------------");
|
||||
$display(" Case-3 Create a Page Cross Over ");
|
||||
$display("----------------------------------------");
|
||||
burst_write(32'h0000_0FF0,8'h8);
|
||||
burst_write(32'h0001_0FF4,8'hF);
|
||||
burst_write(32'h0002_0FF8,8'hF);
|
||||
burst_write(32'h0003_0FFC,8'hF);
|
||||
burst_write(32'h0004_0FE0,8'hF);
|
||||
burst_write(32'h0005_0FE4,8'hF);
|
||||
burst_write(32'h0006_0FE8,8'hF);
|
||||
burst_write(32'h0007_0FEC,8'hF);
|
||||
burst_write(32'h0008_0FD0,8'hF);
|
||||
burst_write(32'h0009_0FD4,8'hF);
|
||||
burst_write(32'h000A_0FD8,8'hF);
|
||||
burst_write(32'h000B_0FDC,8'hF);
|
||||
burst_write(32'h000C_0FC0,8'hF);
|
||||
burst_write(32'h000D_0FC4,8'hF);
|
||||
burst_write(32'h000E_0FC8,8'hF);
|
||||
burst_write(32'h000F_0FCC,8'hF);
|
||||
burst_write(32'h0010_0FB0,8'hF);
|
||||
burst_write(32'h0011_0FB4,8'hF);
|
||||
burst_write(32'h0012_0FB8,8'hF);
|
||||
burst_write(32'h0013_0FBC,8'hF);
|
||||
burst_write(32'h0014_0FA0,8'hF);
|
||||
burst_write(32'h0015_0FA4,8'hF);
|
||||
burst_write(32'h0016_0FA8,8'hF);
|
||||
burst_write(32'h0017_0FAC,8'hF);
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
|
||||
$display("----------------------------------------");
|
||||
$display(" Case:4 4 Write & 4 Read ");
|
||||
$display("----------------------------------------");
|
||||
burst_write(32'h4_0000,8'h4);
|
||||
burst_write(32'h5_0000,8'h5);
|
||||
burst_write(32'h6_0000,8'h6);
|
||||
burst_write(32'h7_0000,8'h7);
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
|
||||
$display("---------------------------------------");
|
||||
$display(" Case:5 24 Write & 24 Read With Different Bank and Row ");
|
||||
$display("---------------------------------------");
|
||||
//----------------------------------------
|
||||
// Address Decodeing:
|
||||
// with cfg_col bit configured as: 00
|
||||
// <12 Bit Row> <2 Bit Bank> <8 Bit Column> <2'b00>
|
||||
//
|
||||
burst_write({12'h000,2'b00,8'h00,2'b00},8'h4); // Row: 0 Bank : 0
|
||||
burst_write({12'h000,2'b01,8'h00,2'b00},8'h5); // Row: 0 Bank : 1
|
||||
burst_write({12'h000,2'b10,8'h00,2'b00},8'h6); // Row: 0 Bank : 2
|
||||
burst_write({12'h000,2'b11,8'h00,2'b00},8'h7); // Row: 0 Bank : 3
|
||||
burst_write({12'h001,2'b00,8'h00,2'b00},8'h4); // Row: 1 Bank : 0
|
||||
burst_write({12'h001,2'b01,8'h00,2'b00},8'h5); // Row: 1 Bank : 1
|
||||
burst_write({12'h001,2'b10,8'h00,2'b00},8'h6); // Row: 1 Bank : 2
|
||||
burst_write({12'h001,2'b11,8'h00,2'b00},8'h7); // Row: 1 Bank : 3
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
|
||||
burst_write({12'h002,2'b00,8'h00,2'b00},8'h4); // Row: 2 Bank : 0
|
||||
burst_write({12'h002,2'b01,8'h00,2'b00},8'h5); // Row: 2 Bank : 1
|
||||
burst_write({12'h002,2'b10,8'h00,2'b00},8'h6); // Row: 2 Bank : 2
|
||||
burst_write({12'h002,2'b11,8'h00,2'b00},8'h7); // Row: 2 Bank : 3
|
||||
burst_write({12'h003,2'b00,8'h00,2'b00},8'h4); // Row: 3 Bank : 0
|
||||
burst_write({12'h003,2'b01,8'h00,2'b00},8'h5); // Row: 3 Bank : 1
|
||||
burst_write({12'h003,2'b10,8'h00,2'b00},8'h6); // Row: 3 Bank : 2
|
||||
burst_write({12'h003,2'b11,8'h00,2'b00},8'h7); // Row: 3 Bank : 3
|
||||
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
|
||||
burst_write({12'h002,2'b00,8'h00,2'b00},8'h4); // Row: 2 Bank : 0
|
||||
burst_write({12'h002,2'b01,8'h01,2'b00},8'h5); // Row: 2 Bank : 1
|
||||
burst_write({12'h002,2'b10,8'h02,2'b00},8'h6); // Row: 2 Bank : 2
|
||||
burst_write({12'h002,2'b11,8'h03,2'b00},8'h7); // Row: 2 Bank : 3
|
||||
burst_write({12'h003,2'b00,8'h04,2'b00},8'h4); // Row: 3 Bank : 0
|
||||
burst_write({12'h003,2'b01,8'h05,2'b00},8'h5); // Row: 3 Bank : 1
|
||||
burst_write({12'h003,2'b10,8'h06,2'b00},8'h6); // Row: 3 Bank : 2
|
||||
burst_write({12'h003,2'b11,8'h07,2'b00},8'h7); // Row: 3 Bank : 3
|
||||
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
burst_read();
|
||||
$display("---------------------------------------------------");
|
||||
$display(" Case: 6 Random 2 write and 2 read random");
|
||||
$display("---------------------------------------------------");
|
||||
for(k=0; k < 20; k++) begin
|
||||
StartAddr = $random & 32'h003FFFFF;
|
||||
burst_write(StartAddr,($random & 8'h0f)+1);
|
||||
#100;
|
||||
|
||||
StartAddr = $random & 32'h003FFFFF;
|
||||
burst_write(StartAddr,($random & 8'h0f)+1);
|
||||
#100;
|
||||
burst_read();
|
||||
#100;
|
||||
burst_read();
|
||||
#100;
|
||||
end
|
||||
|
||||
#10000;
|
||||
|
||||
$display("###############################");
|
||||
if(ErrCnt == 0)
|
||||
$display("STATUS: SDRAM Write/Read TEST PASSED");
|
||||
else
|
||||
$display("ERROR: SDRAM Write/Read TEST FAILED");
|
||||
$display("###############################");
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
task burst_write;
|
||||
input [31:0] Address;
|
||||
input [7:0] bl;
|
||||
int i;
|
||||
begin
|
||||
afifo.push_back(Address);
|
||||
bfifo.push_back(bl);
|
||||
|
||||
@ (negedge sys_clk);
|
||||
$display("Write Address: %x, Burst Size: %d",Address,bl);
|
||||
|
||||
for(i=0; i < bl; i++) begin
|
||||
wb_stb_i = 1;
|
||||
wb_cyc_i = 1;
|
||||
wb_we_i = 1;
|
||||
wb_sel_i = 4'b1111;
|
||||
wb_addr_i = Address[31:2]+i;
|
||||
wb_dat_i = $random & 32'hFFFFFFFF;
|
||||
dfifo.push_back(wb_dat_i);
|
||||
|
||||
do begin
|
||||
@ (posedge sys_clk);
|
||||
end while(wb_ack_o == 1'b0);
|
||||
@ (negedge sys_clk);
|
||||
|
||||
$display("Status: Burst-No: %d Write Address: %x WriteData: %x ",i,wb_addr_i,wb_dat_i);
|
||||
end
|
||||
wb_stb_i = 0;
|
||||
wb_cyc_i = 0;
|
||||
wb_we_i = 'hx;
|
||||
wb_sel_i = 'hx;
|
||||
wb_addr_i = 'hx;
|
||||
wb_dat_i = 'hx;
|
||||
end
|
||||
endtask
|
||||
|
||||
task burst_read;
|
||||
reg [31:0] Address;
|
||||
reg [7:0] bl;
|
||||
|
||||
int i,j;
|
||||
reg [31:0] exp_data;
|
||||
begin
|
||||
|
||||
Address = afifo.pop_front();
|
||||
bl = bfifo.pop_front();
|
||||
@ (negedge sys_clk);
|
||||
|
||||
for(j=0; j < bl; j++) begin
|
||||
wb_stb_i = 1;
|
||||
wb_cyc_i = 1;
|
||||
wb_we_i = 0;
|
||||
wb_addr_i = Address[31:2]+j;
|
||||
|
||||
exp_data = dfifo.pop_front(); // Exptected Read Data
|
||||
do begin
|
||||
@ (posedge sys_clk);
|
||||
end while(wb_ack_o == 1'b0);
|
||||
if(wb_dat_o !== exp_data) begin
|
||||
$display("READ ERROR: Burst-No: %d Addr: %x Rxp: %x Exd: %x",j,wb_addr_i,wb_dat_o,exp_data);
|
||||
ErrCnt = ErrCnt+1;
|
||||
end else begin
|
||||
$display("READ STATUS: Burst-No: %d Addr: %x Rxd: %x",j,wb_addr_i,wb_dat_o);
|
||||
end
|
||||
@ (negedge sdram_clk);
|
||||
end
|
||||
wb_stb_i = 0;
|
||||
wb_cyc_i = 0;
|
||||
wb_we_i = 'hx;
|
||||
wb_addr_i = 'hx;
|
||||
end
|
||||
endtask
|
||||
|
||||
|
||||
endmodule
|
297
lib/common/Driver/SDRAM_driver/top/sdrc_top.v
Normal file
297
lib/common/Driver/SDRAM_driver/top/sdrc_top.v
Normal file
@ -0,0 +1,297 @@
|
||||
/*********************************************************************
|
||||
|
||||
SDRAM Controller top File
|
||||
|
||||
This file is part of the sdram controller project
|
||||
http://www.opencores.org/cores/sdr_ctrl/
|
||||
|
||||
Description: SDRAM Controller Top Module.
|
||||
Support 81/6/32 Bit SDRAM.
|
||||
Column Address is Programmable
|
||||
Bank Bit are 2 Bit
|
||||
Row Bits are 12 Bits
|
||||
|
||||
This block integrate following sub modules
|
||||
|
||||
sdrc_core
|
||||
SDRAM Controller file
|
||||
wb2sdrc
|
||||
This module transalate the bus protocl from wishbone to custome
|
||||
sdram controller
|
||||
|
||||
To Do:
|
||||
nothing
|
||||
|
||||
Author(s): Dinesh Annayya, dinesha@opencores.org
|
||||
Version : 0.0 - 8th Jan 2012
|
||||
Initial version with 16/32 Bit SDRAM Support
|
||||
: 0.1 - 24th Jan 2012
|
||||
8 Bit SDRAM Support is added
|
||||
0.2 - 31st Jan 2012
|
||||
sdram_dq and sdram_pad_clk are internally generated
|
||||
0.3 - 26th April 2013
|
||||
Sdram Address witdh is increased from 12 to 13bits
|
||||
|
||||
|
||||
Copyright (C) 2000 Authors and OPENCORES.ORG
|
||||
|
||||
This source file may be used and distributed without
|
||||
restriction provided that this copyright statement is not
|
||||
removed from the file and that any derivative work contains
|
||||
the original copyright notice and the associated disclaimer.
|
||||
|
||||
This source file is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU Lesser General
|
||||
Public License as published by the Free Software Foundation;
|
||||
either version 2.1 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
This source is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the GNU Lesser General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this source; if not, download it
|
||||
from http://www.opencores.org/lgpl.shtml
|
||||
|
||||
*******************************************************************/
|
||||
|
||||
|
||||
`include "sdrc_define.v"
|
||||
module sdrc_top
|
||||
(
|
||||
cfg_sdr_width ,
|
||||
cfg_colbits ,
|
||||
|
||||
// WB bus
|
||||
wb_rst_i ,
|
||||
wb_clk_i ,
|
||||
|
||||
wb_stb_i ,
|
||||
wb_ack_o ,
|
||||
wb_addr_i ,
|
||||
wb_we_i ,
|
||||
wb_dat_i ,
|
||||
wb_sel_i ,
|
||||
wb_dat_o ,
|
||||
wb_cyc_i ,
|
||||
wb_cti_i ,
|
||||
|
||||
|
||||
/* Interface to SDRAMs */
|
||||
sdram_clk ,
|
||||
sdram_resetn ,
|
||||
sdr_cs_n ,
|
||||
sdr_cke ,
|
||||
sdr_ras_n ,
|
||||
sdr_cas_n ,
|
||||
sdr_we_n ,
|
||||
sdr_dqm ,
|
||||
sdr_ba ,
|
||||
sdr_addr ,
|
||||
sdr_dq ,
|
||||
|
||||
/* Parameters */
|
||||
sdr_init_done ,
|
||||
cfg_req_depth , //how many req. buffer should hold
|
||||
cfg_sdr_en ,
|
||||
cfg_sdr_mode_reg ,
|
||||
cfg_sdr_tras_d ,
|
||||
cfg_sdr_trp_d ,
|
||||
cfg_sdr_trcd_d ,
|
||||
cfg_sdr_cas ,
|
||||
cfg_sdr_trcar_d ,
|
||||
cfg_sdr_twr_d ,
|
||||
cfg_sdr_rfsh ,
|
||||
cfg_sdr_rfmax
|
||||
);
|
||||
|
||||
parameter APP_AW = 26; // Application Address Width
|
||||
parameter APP_DW = 32; // Application Data Width
|
||||
parameter APP_BW = 4; // Application Byte Width
|
||||
parameter APP_RW = 9; // Application Request Width
|
||||
|
||||
parameter SDR_DW = 16; // SDR Data Width
|
||||
parameter SDR_BW = 2; // SDR Byte Width
|
||||
|
||||
parameter dw = 32; // data width
|
||||
parameter tw = 8; // tag id width
|
||||
parameter bl = 9; // burst_lenght_width
|
||||
|
||||
//-----------------------------------------------
|
||||
// Global Variable
|
||||
// ----------------------------------------------
|
||||
input sdram_clk ; // SDRAM Clock
|
||||
input sdram_resetn ; // Reset Signal
|
||||
input [1:0] cfg_sdr_width ; // 2'b00 - 32 Bit SDR, 2'b01 - 16 Bit SDR, 2'b1x - 8 Bit
|
||||
input [1:0] cfg_colbits ; // 2'b00 - 8 Bit column address,
|
||||
// 2'b01 - 9 Bit, 10 - 10 bit, 11 - 11Bits
|
||||
|
||||
//--------------------------------------
|
||||
// Wish Bone Interface
|
||||
// -------------------------------------
|
||||
input wb_rst_i ;
|
||||
input wb_clk_i ;
|
||||
|
||||
input wb_stb_i ;
|
||||
output wb_ack_o ;
|
||||
input [APP_AW-1:0] wb_addr_i ;
|
||||
input wb_we_i ; // 1 - Write, 0 - Read
|
||||
input [dw-1:0] wb_dat_i ;
|
||||
input [dw/8-1:0] wb_sel_i ; // Byte enable
|
||||
output [dw-1:0] wb_dat_o ;
|
||||
input wb_cyc_i ;
|
||||
input [2:0] wb_cti_i ;
|
||||
|
||||
//------------------------------------------------
|
||||
// Interface to SDRAMs
|
||||
//------------------------------------------------
|
||||
output sdr_cke ; // SDRAM CKE
|
||||
output sdr_cs_n ; // SDRAM Chip Select
|
||||
output sdr_ras_n ; // SDRAM ras
|
||||
output sdr_cas_n ; // SDRAM cas
|
||||
output sdr_we_n ; // SDRAM write enable
|
||||
output [SDR_BW-1:0] sdr_dqm ; // SDRAM Data Mask
|
||||
output [1:0] sdr_ba ; // SDRAM Bank Enable
|
||||
output [12:0] sdr_addr ; // SDRAM Address
|
||||
inout [SDR_DW-1:0] sdr_dq ; // SDRA Data Input/output
|
||||
|
||||
//------------------------------------------------
|
||||
// Configuration Parameter
|
||||
//------------------------------------------------
|
||||
output sdr_init_done ; // Indicate SDRAM Initialisation Done
|
||||
input [3:0] cfg_sdr_tras_d ; // Active to precharge delay
|
||||
input [3:0] cfg_sdr_trp_d ; // Precharge to active delay
|
||||
input [3:0] cfg_sdr_trcd_d ; // Active to R/W delay
|
||||
input cfg_sdr_en ; // Enable SDRAM controller
|
||||
input [1:0] cfg_req_depth ; // Maximum Request accepted by SDRAM controller
|
||||
input [12:0] cfg_sdr_mode_reg ;
|
||||
input [2:0] cfg_sdr_cas ; // SDRAM CAS Latency
|
||||
input [3:0] cfg_sdr_trcar_d ; // Auto-refresh period
|
||||
input [3:0] cfg_sdr_twr_d ; // Write recovery delay
|
||||
input [`SDR_RFSH_TIMER_W-1 : 0] cfg_sdr_rfsh;
|
||||
input [`SDR_RFSH_ROW_CNT_W -1 : 0] cfg_sdr_rfmax;
|
||||
|
||||
//--------------------------------------------
|
||||
// SDRAM controller Interface
|
||||
//--------------------------------------------
|
||||
wire app_req ; // SDRAM request
|
||||
wire [APP_AW-1:0] app_req_addr ; // SDRAM Request Address
|
||||
wire [bl-1:0] app_req_len ;
|
||||
wire app_req_wr_n ; // 0 - Write, 1 -> Read
|
||||
wire app_req_ack ; // SDRAM request Accepted
|
||||
wire app_busy_n ; // 0 -> sdr busy
|
||||
wire [dw/8-1:0] app_wr_en_n ; // Active low sdr byte-wise write data valid
|
||||
wire app_wr_next_req ; // Ready to accept the next write
|
||||
wire app_rd_valid ; // sdr read valid
|
||||
wire app_last_rd ; // Indicate last Read of Burst Transfer
|
||||
wire app_last_wr ; // Indicate last Write of Burst Transfer
|
||||
wire [dw-1:0] app_wr_data ; // sdr write data
|
||||
wire [dw-1:0] app_rd_data ; // sdr read data
|
||||
|
||||
/****************************************
|
||||
* These logic has to be implemented using Pads
|
||||
* **************************************/
|
||||
wire [SDR_DW-1:0] pad_sdr_din ; // SDRA Data Input
|
||||
wire [SDR_DW-1:0] sdr_dout ; // SDRAM Data Output
|
||||
wire [SDR_BW-1:0] sdr_den_n ; // SDRAM Data Output enable
|
||||
|
||||
|
||||
assign sdr_dq = (&sdr_den_n == 1'b0) ? sdr_dout : {SDR_DW{1'bz}};
|
||||
assign pad_sdr_din = sdr_dq;
|
||||
|
||||
// sdram pad clock is routed back through pad
|
||||
// SDRAM Clock from Pad, used for registering Read Data
|
||||
wire #(1.0) sdram_pad_clk = sdram_clk;
|
||||
|
||||
/************** Ends Here **************************/
|
||||
wb2sdrc #(.dw(dw),.tw(tw),.bl(bl)) u_wb2sdrc (
|
||||
// WB bus
|
||||
.wb_rst_i (wb_rst_i ) ,
|
||||
.wb_clk_i (wb_clk_i ) ,
|
||||
|
||||
.wb_stb_i (wb_stb_i ) ,
|
||||
.wb_ack_o (wb_ack_o ) ,
|
||||
.wb_addr_i (wb_addr_i ) ,
|
||||
.wb_we_i (wb_we_i ) ,
|
||||
.wb_dat_i (wb_dat_i ) ,
|
||||
.wb_sel_i (wb_sel_i ) ,
|
||||
.wb_dat_o (wb_dat_o ) ,
|
||||
.wb_cyc_i (wb_cyc_i ) ,
|
||||
.wb_cti_i (wb_cti_i ) ,
|
||||
|
||||
|
||||
//SDRAM Controller Hand-Shake Signal
|
||||
.sdram_clk (sdram_clk ) ,
|
||||
.sdram_resetn (sdram_resetn ) ,
|
||||
.sdr_req (app_req ) ,
|
||||
.sdr_req_addr (app_req_addr ) ,
|
||||
.sdr_req_len (app_req_len ) ,
|
||||
.sdr_req_wr_n (app_req_wr_n ) ,
|
||||
.sdr_req_ack (app_req_ack ) ,
|
||||
.sdr_busy_n (app_busy_n ) ,
|
||||
.sdr_wr_en_n (app_wr_en_n ) ,
|
||||
.sdr_wr_next (app_wr_next_req ) ,
|
||||
.sdr_rd_valid (app_rd_valid ) ,
|
||||
.sdr_last_rd (app_last_rd ) ,
|
||||
.sdr_wr_data (app_wr_data ) ,
|
||||
.sdr_rd_data (app_rd_data )
|
||||
|
||||
);
|
||||
|
||||
|
||||
sdrc_core #(.SDR_DW(SDR_DW) , .SDR_BW(SDR_BW)) u_sdrc_core (
|
||||
.clk (sdram_clk ) ,
|
||||
.pad_clk (sdram_pad_clk ) ,
|
||||
.reset_n (sdram_resetn ) ,
|
||||
.sdr_width (cfg_sdr_width ) ,
|
||||
.cfg_colbits (cfg_colbits ) ,
|
||||
|
||||
/* Request from app */
|
||||
.app_req (app_req ) ,// Transfer Request
|
||||
.app_req_addr (app_req_addr ) ,// SDRAM Address
|
||||
.app_req_len (app_req_len ) ,// Burst Length (in 16 bit words)
|
||||
.app_req_wrap (1'b0 ) ,// Wrap mode request
|
||||
.app_req_wr_n (app_req_wr_n ) ,// 0 => Write request, 1 => read req
|
||||
.app_req_ack (app_req_ack ) ,// Request has been accepted
|
||||
.cfg_req_depth (cfg_req_depth ) ,//how many req. buffer should hold
|
||||
|
||||
.app_wr_data (app_wr_data ) ,
|
||||
.app_wr_en_n (app_wr_en_n ) ,
|
||||
.app_rd_data (app_rd_data ) ,
|
||||
.app_rd_valid (app_rd_valid ) ,
|
||||
.app_last_rd (app_last_rd ) ,
|
||||
.app_last_wr (app_last_wr ) ,
|
||||
.app_wr_next_req (app_wr_next_req ) ,
|
||||
.sdr_init_done (sdr_init_done ) ,
|
||||
.app_req_dma_last (app_req ) ,
|
||||
|
||||
/* Interface to SDRAMs */
|
||||
.sdr_cs_n (sdr_cs_n ) ,
|
||||
.sdr_cke (sdr_cke ) ,
|
||||
.sdr_ras_n (sdr_ras_n ) ,
|
||||
.sdr_cas_n (sdr_cas_n ) ,
|
||||
.sdr_we_n (sdr_we_n ) ,
|
||||
.sdr_dqm (sdr_dqm ) ,
|
||||
.sdr_ba (sdr_ba ) ,
|
||||
.sdr_addr (sdr_addr ) ,
|
||||
.pad_sdr_din (pad_sdr_din ) ,
|
||||
.sdr_dout (sdr_dout ) ,
|
||||
.sdr_den_n (sdr_den_n ) ,
|
||||
|
||||
/* Parameters */
|
||||
.cfg_sdr_en (cfg_sdr_en ) ,
|
||||
.cfg_sdr_mode_reg (cfg_sdr_mode_reg ) ,
|
||||
.cfg_sdr_tras_d (cfg_sdr_tras_d ) ,
|
||||
.cfg_sdr_trp_d (cfg_sdr_trp_d ) ,
|
||||
.cfg_sdr_trcd_d (cfg_sdr_trcd_d ) ,
|
||||
.cfg_sdr_cas (cfg_sdr_cas ) ,
|
||||
.cfg_sdr_trcar_d (cfg_sdr_trcar_d ) ,
|
||||
.cfg_sdr_twr_d (cfg_sdr_twr_d ) ,
|
||||
.cfg_sdr_rfsh (cfg_sdr_rfsh ) ,
|
||||
.cfg_sdr_rfmax (cfg_sdr_rfmax )
|
||||
);
|
||||
|
||||
endmodule // sdrc_core
|
371
lib/common/Driver/SDRAM_driver/wb2sdrc/wb2sdrc.v
Normal file
371
lib/common/Driver/SDRAM_driver/wb2sdrc/wb2sdrc.v
Normal file
@ -0,0 +1,371 @@
|
||||
/*********************************************************************
|
||||
|
||||
This file is part of the sdram controller project
|
||||
http://www.opencores.org/cores/sdr_ctrl/
|
||||
|
||||
Description: WISHBONE to SDRAM Controller Bus Transalator
|
||||
1. This module translate the WISHBONE protocol to custom sdram controller i/f
|
||||
2. Also Handle the clock domain change from Application layer to Sdram layer
|
||||
|
||||
To Do:
|
||||
nothing
|
||||
|
||||
Author(s): Dinesh Annayya, dinesha@opencores.org
|
||||
Version : 0.0 - Initial Release
|
||||
0.1 - 2nd Feb 2012
|
||||
Async Fifo towards the application layer is selected
|
||||
with Registered Full Generation
|
||||
0.2 - 2nd Feb 2012
|
||||
Pending Read generation bug fix done to handle backto back write
|
||||
followed by read request
|
||||
|
||||
Copyright (C) 2000 Authors and OPENCORES.ORG
|
||||
|
||||
|
||||
This source file may be used and distributed without
|
||||
restriction provided that this copyright statement is not
|
||||
removed from the file and that any derivative work contains
|
||||
the original copyright notice and the associated disclaimer.
|
||||
|
||||
This source file is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU Lesser General
|
||||
Public License as published by the Free Software Foundation;
|
||||
either version 2.1 of the License, or (at your option) any
|
||||
later version.
|
||||
|
||||
This source is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the GNU Lesser General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this source; if not, download it
|
||||
from http://www.opencores.org/lgpl.shtml
|
||||
|
||||
*******************************************************************/
|
||||
|
||||
|
||||
module wb2sdrc (
|
||||
// WB bus
|
||||
wb_rst_i ,
|
||||
wb_clk_i ,
|
||||
|
||||
wb_stb_i ,
|
||||
wb_ack_o ,
|
||||
wb_addr_i ,
|
||||
wb_we_i ,
|
||||
wb_dat_i ,
|
||||
wb_sel_i ,
|
||||
wb_dat_o ,
|
||||
wb_cyc_i ,
|
||||
wb_cti_i ,
|
||||
|
||||
|
||||
//SDRAM Controller Hand-Shake Signal
|
||||
sdram_clk ,
|
||||
sdram_resetn ,
|
||||
sdr_req ,
|
||||
sdr_req_addr ,
|
||||
sdr_req_len ,
|
||||
sdr_req_wr_n ,
|
||||
sdr_req_ack ,
|
||||
sdr_busy_n ,
|
||||
sdr_wr_en_n ,
|
||||
sdr_wr_next ,
|
||||
sdr_rd_valid ,
|
||||
sdr_last_rd ,
|
||||
sdr_wr_data ,
|
||||
sdr_rd_data
|
||||
|
||||
);
|
||||
|
||||
parameter dw = 32; // data width
|
||||
parameter tw = 8; // tag id width
|
||||
parameter bl = 9; // burst_lenght_width
|
||||
parameter APP_AW = 26; // Application Address Width
|
||||
//--------------------------------------
|
||||
// Wish Bone Interface
|
||||
// -------------------------------------
|
||||
input wb_rst_i ;
|
||||
input wb_clk_i ;
|
||||
|
||||
input wb_stb_i ;
|
||||
output wb_ack_o ;
|
||||
input [APP_AW-1:0] wb_addr_i ;
|
||||
input wb_we_i ; // 1 - Write , 0 - Read
|
||||
input [dw-1:0] wb_dat_i ;
|
||||
input [dw/8-1:0] wb_sel_i ; // Byte enable
|
||||
output [dw-1:0] wb_dat_o ;
|
||||
input wb_cyc_i ;
|
||||
input [2:0] wb_cti_i ;
|
||||
/***************************************************
|
||||
The Cycle Type Idenfier [CTI_IO()] Address Tag provides
|
||||
additional information about the current cycle.
|
||||
The MASTER sends this information to the SLAVE. The SLAVE can use this
|
||||
information to prepare the response for the next cycle.
|
||||
Table 4-2 Cycle Type Identifiers
|
||||
CTI_O(2:0) Description
|
||||
‘000’ Classic cycle.
|
||||
‘001’ Constant address burst cycle
|
||||
‘010’ Incrementing burst cycle
|
||||
‘011’ Reserved
|
||||
‘100’ Reserved
|
||||
‘101 Reserved
|
||||
‘110’ Reserved
|
||||
‘111’ End-of-Burst
|
||||
****************************************************/
|
||||
//--------------------------------------------
|
||||
// SDRAM controller Interface
|
||||
//--------------------------------------------
|
||||
input sdram_clk ; // sdram clock
|
||||
input sdram_resetn ; // sdram reset
|
||||
output sdr_req ; // SDRAM request
|
||||
output [APP_AW-1:0] sdr_req_addr ; // SDRAM Request Address
|
||||
output [bl-1:0] sdr_req_len ;
|
||||
output sdr_req_wr_n ; // 0 - Write, 1 -> Read
|
||||
input sdr_req_ack ; // SDRAM request Accepted
|
||||
input sdr_busy_n ; // 0 -> sdr busy
|
||||
output [dw/8-1:0] sdr_wr_en_n ; // Active low sdr byte-wise write data valid
|
||||
input sdr_wr_next ; // Ready to accept the next write
|
||||
input sdr_rd_valid ; // sdr read valid
|
||||
input sdr_last_rd ; // Indicate last Read of Burst Transfer
|
||||
output [dw-1:0] sdr_wr_data ; // sdr write data
|
||||
input [dw-1:0] sdr_rd_data ; // sdr read data
|
||||
|
||||
//----------------------------------------------------
|
||||
// Wire Decleration
|
||||
// ---------------------------------------------------
|
||||
wire cmdfifo_full ;
|
||||
wire cmdfifo_empty ;
|
||||
wire wrdatafifo_full ;
|
||||
wire wrdatafifo_empty ;
|
||||
wire tagfifo_full ;
|
||||
wire tagfifo_empty ;
|
||||
wire rddatafifo_empty ;
|
||||
wire rddatafifo_full ;
|
||||
|
||||
reg pending_read ;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Ack Generaltion Logic
|
||||
// If Write Request - Acknowledge if the command and write FIFO are not full
|
||||
// If Read Request - Generate the Acknowledgment once read fifo has data
|
||||
// available
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
assign wb_ack_o = (wb_stb_i && wb_cyc_i && wb_we_i) ? // Write Phase
|
||||
((!cmdfifo_full) && (!wrdatafifo_full)) :
|
||||
(wb_stb_i && wb_cyc_i && !wb_we_i) ? // Read Phase
|
||||
!rddatafifo_empty : 1'b0;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Command FIFO Write Generation
|
||||
// If Write Request - Generate write, when Write fifo and command fifo is
|
||||
// not full
|
||||
// If Read Request - Generate write, when command fifo not full and there
|
||||
// is no pending read request.
|
||||
//---------------------------------------------------------------------------
|
||||
wire cmdfifo_wr = (wb_stb_i && wb_cyc_i && wb_we_i && (!cmdfifo_full) ) ? wb_ack_o :
|
||||
(wb_stb_i && wb_cyc_i && !wb_we_i && (!cmdfifo_full)) ? !pending_read: 1'b0 ;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// command fifo read generation
|
||||
// Command FIFo read will be generated, whenever SDRAM Controller
|
||||
// Acknowldge the Request
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
wire cmdfifo_rd = sdr_req_ack;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Application layer request is generated towards the controller, whenever
|
||||
// Command FIFO is not full
|
||||
// --------------------------------------------------------------------------
|
||||
assign sdr_req = !cmdfifo_empty;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Since Burst length is not known at the start of the Burst, It's assumed as
|
||||
// Single Cycle Burst. We need to improvise this ...
|
||||
// --------------------------------------------------------------------------
|
||||
wire [bl-1:0] burst_length = 1; // 0 Mean 1 Transfer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// In Wish Bone Spec, For Read Request has to be acked along with data.
|
||||
// We need to identify the pending read request.
|
||||
// Once we accept the read request, we should not accept one more read
|
||||
// request, untill we have transmitted the read data.
|
||||
// Pending Read will
|
||||
// set - with Read Request
|
||||
// reset - with Read Request + Ack
|
||||
// ----------------------------------------------------------------------------
|
||||
always @(posedge wb_rst_i or posedge wb_clk_i) begin
|
||||
if(wb_rst_i) begin
|
||||
pending_read <= 1'b0;
|
||||
end else begin
|
||||
//pending_read <= wb_stb_i & wb_cyc_i & !wb_we_i & !wb_ack_o;
|
||||
pending_read <= (cmdfifo_wr && !wb_we_i) ? 1'b1:
|
||||
(wb_stb_i & wb_cyc_i & !wb_we_i & wb_ack_o) ? 1'b0: pending_read;
|
||||
end
|
||||
end
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Async Command FIFO. This block handle the clock domain change from
|
||||
// Application layer to SDRAM Controller
|
||||
// ------------------------------------------------------------------
|
||||
// Address + Burst Length + W/R Request
|
||||
async_fifo #(.W(APP_AW+bl+1),.DP(4),.WR_FAST(1'b0), .RD_FAST(1'b0)) u_cmdfifo (
|
||||
// Write Path Sys CLock Domain
|
||||
.wr_clk (wb_clk_i ),
|
||||
.wr_reset_n (!wb_rst_i ),
|
||||
.wr_en (cmdfifo_wr ),
|
||||
.wr_data ({burst_length,
|
||||
!wb_we_i,
|
||||
wb_addr_i} ),
|
||||
.afull ( ),
|
||||
.full (cmdfifo_full ),
|
||||
|
||||
// Read Path, SDRAM clock domain
|
||||
.rd_clk (sdram_clk ),
|
||||
.rd_reset_n (sdram_resetn ),
|
||||
.aempty ( ),
|
||||
.empty (cmdfifo_empty ),
|
||||
.rd_en (cmdfifo_rd ),
|
||||
.rd_data ({sdr_req_len,
|
||||
sdr_req_wr_n,
|
||||
sdr_req_addr} )
|
||||
);
|
||||
|
||||
// synopsys translate_off
|
||||
always @(posedge wb_clk_i) begin
|
||||
if (cmdfifo_full == 1'b1 && cmdfifo_wr == 1'b1) begin
|
||||
$display("ERROR:%m COMMAND FIFO WRITE OVERFLOW");
|
||||
end
|
||||
end
|
||||
// synopsys translate_on
|
||||
// synopsys translate_off
|
||||
always @(posedge sdram_clk) begin
|
||||
if (cmdfifo_empty == 1'b1 && cmdfifo_rd == 1'b1) begin
|
||||
$display("ERROR:%m COMMAND FIFO READ OVERFLOW");
|
||||
end
|
||||
end
|
||||
// synopsys translate_on
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Write Data FIFO Write Generation, when ever Acked + Write Request
|
||||
// Note: Ack signal generation already taking account of FIFO full condition
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
wire wrdatafifo_wr = wb_ack_o & wb_we_i ;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Write Data FIFO Read Generation, When ever Next Write request generated
|
||||
// from SDRAM Controller
|
||||
// ------------------------------------------------------------------------
|
||||
wire wrdatafifo_rd = sdr_wr_next;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Async Write Data FIFO
|
||||
// This block handle the clock domain change over + Write Data + Byte mask
|
||||
// From Application layer to SDRAM controller layer
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
// Write DATA + Data Mask FIFO
|
||||
async_fifo #(.W(dw+(dw/8)), .DP(8), .WR_FAST(1'b0), .RD_FAST(1'b1)) u_wrdatafifo (
|
||||
// Write Path , System clock domain
|
||||
.wr_clk (wb_clk_i ),
|
||||
.wr_reset_n (!wb_rst_i ),
|
||||
.wr_en (wrdatafifo_wr ),
|
||||
.wr_data ({~wb_sel_i,
|
||||
wb_dat_i} ),
|
||||
.afull ( ),
|
||||
.full (wrdatafifo_full ),
|
||||
|
||||
|
||||
// Read Path , SDRAM clock domain
|
||||
.rd_clk (sdram_clk ),
|
||||
.rd_reset_n (sdram_resetn ),
|
||||
.aempty ( ),
|
||||
.empty (wrdatafifo_empty ),
|
||||
.rd_en (wrdatafifo_rd ),
|
||||
.rd_data ({sdr_wr_en_n,
|
||||
sdr_wr_data} )
|
||||
);
|
||||
// synopsys translate_off
|
||||
always @(posedge wb_clk_i) begin
|
||||
if (wrdatafifo_full == 1'b1 && wrdatafifo_wr == 1'b1) begin
|
||||
$display("ERROR:%m WRITE DATA FIFO WRITE OVERFLOW");
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge sdram_clk) begin
|
||||
if (wrdatafifo_empty == 1'b1 && wrdatafifo_rd == 1'b1) begin
|
||||
$display("ERROR:%m WRITE DATA FIFO READ OVERFLOW");
|
||||
end
|
||||
end
|
||||
// synopsys translate_on
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// READ DATA FIFO
|
||||
// ------------------------------------------------------------------
|
||||
wire rd_eop; // last read indication
|
||||
|
||||
// Read FIFO write generation, when ever SDRAM controller issues the read
|
||||
// valid signal
|
||||
wire rddatafifo_wr = sdr_rd_valid;
|
||||
|
||||
// Read FIFO read generation, when ever ack is generated along with read
|
||||
// request.
|
||||
// Note: Ack generation is already accounted the write FIFO Not Empty
|
||||
// condition
|
||||
wire rddatafifo_rd = wb_ack_o & !wb_we_i;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Async Read FIFO
|
||||
// This block handles the clock domain change over + Read data from SDRAM
|
||||
// controller to Application layer.
|
||||
// Note:
|
||||
// 1. READ DATA FIFO depth is kept small, assuming that Sys-CLock > SDRAM Clock
|
||||
// READ DATA + EOP
|
||||
// 2. EOP indicate, last transfer of Burst Read Access. use-full for future
|
||||
// Tag handling per burst
|
||||
//
|
||||
// ------------------------------------------------------------------------
|
||||
async_fifo #(.W(dw+1), .DP(4), .WR_FAST(1'b0), .RD_FAST(1'b1) ) u_rddatafifo (
|
||||
// Write Path , SDRAM clock domain
|
||||
.wr_clk (sdram_clk ),
|
||||
.wr_reset_n (sdram_resetn ),
|
||||
.wr_en (rddatafifo_wr ),
|
||||
.wr_data ({sdr_last_rd,
|
||||
sdr_rd_data} ),
|
||||
.afull ( ),
|
||||
.full (rddatafifo_full ),
|
||||
|
||||
|
||||
// Read Path , SYS clock domain
|
||||
.rd_clk (wb_clk_i ),
|
||||
.rd_reset_n (!wb_rst_i ),
|
||||
.empty (rddatafifo_empty ),
|
||||
.aempty ( ),
|
||||
.rd_en (rddatafifo_rd ),
|
||||
.rd_data ({rd_eop,
|
||||
wb_dat_o} )
|
||||
);
|
||||
|
||||
// synopsys translate_off
|
||||
always @(posedge sdram_clk) begin
|
||||
if (rddatafifo_full == 1'b1 && rddatafifo_wr == 1'b1) begin
|
||||
$display("ERROR:%m READ DATA FIFO WRITE OVERFLOW");
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge wb_clk_i) begin
|
||||
if (rddatafifo_empty == 1'b1 && rddatafifo_rd == 1'b1) begin
|
||||
$display("ERROR:%m READ DATA FIFO READ OVERFLOW");
|
||||
end
|
||||
end
|
||||
// synopsys translate_on
|
||||
|
||||
|
||||
endmodule
|
78
lib/common/Driver/UART_driver/UART_rx.v
Normal file
78
lib/common/Driver/UART_driver/UART_rx.v
Normal file
@ -0,0 +1,78 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module uart_rx(
|
||||
input clk_50m,
|
||||
input uart_rx,
|
||||
output [7:0] uart_rx_data,
|
||||
output uart_rx_done
|
||||
);
|
||||
|
||||
parameter [12:0] BAUD_DIV = 13'd87;//bps115200 每位数据传输时间为t=1/115200 s,周期T=1/100000000,计数值为t/T=868
|
||||
parameter [12:0] BAUD_DIV_CAP = 13'd43;
|
||||
|
||||
reg [12:0] baud_div=0;
|
||||
reg baud_bps=0;
|
||||
reg bps_start=0;
|
||||
always@(posedge clk_50m)
|
||||
begin
|
||||
if(baud_div==BAUD_DIV_CAP)
|
||||
begin
|
||||
baud_bps<=1'b1;
|
||||
baud_div<=baud_div+1'b1;
|
||||
end
|
||||
else if(baud_div<BAUD_DIV && bps_start)
|
||||
begin
|
||||
baud_div<=baud_div+1'b1;
|
||||
baud_bps<=0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
baud_bps<=0;
|
||||
baud_div<=0;
|
||||
end
|
||||
end
|
||||
|
||||
reg [4:0] uart_rx_r=5'b11111;
|
||||
always@(posedge clk_50m)
|
||||
begin
|
||||
uart_rx_r<={uart_rx_r[3:0],uart_rx};
|
||||
end
|
||||
wire uart_rxnt=uart_rx_r[4]|uart_rx_r[3]|uart_rx_r[2]|uart_rx_r[1]|uart_rx_r[0];
|
||||
|
||||
reg [3:0] bit_num=0;
|
||||
reg state=1'b0;
|
||||
|
||||
reg [7:0] uart_rx_data_r0=0;
|
||||
reg [7:0] uart_rx_data_r1=0;
|
||||
reg uart_rx_dong_r=0;
|
||||
always@(posedge clk_50m)
|
||||
begin
|
||||
uart_rx_dong_r <= 0;
|
||||
case(state)
|
||||
1'b0 :
|
||||
if(!uart_rxnt)
|
||||
begin
|
||||
bps_start<=1'b1;
|
||||
state<=1'b1;
|
||||
end
|
||||
1'b1 :
|
||||
if(baud_bps)
|
||||
begin
|
||||
bit_num<=bit_num+1'b1;
|
||||
if(bit_num<4'd9)
|
||||
uart_rx_data_r0[bit_num-1]<=uart_rx;
|
||||
end
|
||||
else if(bit_num==4'd10)
|
||||
begin
|
||||
bit_num<=0;
|
||||
uart_rx_dong_r <= 1;
|
||||
uart_rx_data_r1<=uart_rx_data_r0;
|
||||
state<=1'b0;
|
||||
bps_start<=0;
|
||||
end
|
||||
default:;
|
||||
endcase
|
||||
end
|
||||
assign uart_rx_data=uart_rx_data_r1;
|
||||
assign uart_rx_done= uart_rx_dong_r;
|
||||
endmodule
|
74
lib/common/Driver/UART_driver/UART_tx.v
Normal file
74
lib/common/Driver/UART_driver/UART_tx.v
Normal file
@ -0,0 +1,74 @@
|
||||
module uart_tx(
|
||||
input clk_50m,
|
||||
input [7:0] uart_tx_data,
|
||||
input uart_tx_en,
|
||||
output uart_tx,
|
||||
output uart_tx_done
|
||||
);
|
||||
|
||||
parameter BAUD_DIV = 13'd87;
|
||||
parameter BAUD_DIV_CAP = 13'd43;
|
||||
reg [12:0] baud_div=0;
|
||||
reg baud_bps=0;
|
||||
reg [9:0] send_data=10'b1111111111;
|
||||
reg [3:0] bit_num=0;
|
||||
reg uart_send_flag=0;
|
||||
reg uart_tx_r=1;
|
||||
always@(posedge clk_50m)
|
||||
begin
|
||||
if(baud_div==BAUD_DIV_CAP)
|
||||
begin
|
||||
baud_bps<=1'b1;
|
||||
baud_div<=baud_div+1'b1;
|
||||
end
|
||||
else if(baud_div<BAUD_DIV && uart_send_flag)
|
||||
begin
|
||||
baud_div<=baud_div+1'b1;
|
||||
baud_bps<=0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
baud_bps<=0;
|
||||
baud_div<=0;
|
||||
end
|
||||
end
|
||||
|
||||
always@(posedge clk_50m)
|
||||
begin
|
||||
if(uart_tx_en)
|
||||
begin
|
||||
uart_send_flag<=1'b1;
|
||||
send_data<={1'b1,uart_tx_data,1'b0};
|
||||
end
|
||||
else if(bit_num==4'd10)
|
||||
begin
|
||||
uart_send_flag<=1'b0;
|
||||
send_data<=10'b1111_1111_11;
|
||||
end
|
||||
end
|
||||
|
||||
always@(posedge clk_50m)
|
||||
begin
|
||||
if(uart_send_flag)
|
||||
begin
|
||||
if(baud_bps)
|
||||
begin
|
||||
if(bit_num<=4'd9)
|
||||
begin
|
||||
uart_tx_r<=send_data[bit_num];
|
||||
bit_num<=bit_num+1'b1;
|
||||
end
|
||||
end
|
||||
else if(bit_num==4'd10)
|
||||
bit_num<=4'd0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
uart_tx_r<=1'b1;
|
||||
bit_num<=0;
|
||||
end
|
||||
end
|
||||
|
||||
assign uart_tx=uart_tx_r;
|
||||
assign uart_tx_done = (bit_num == 10) ? 1:0;
|
||||
endmodule
|
61
lib/common/Driver/UART_driver/uart_rx_control.v
Normal file
61
lib/common/Driver/UART_driver/uart_rx_control.v
Normal file
@ -0,0 +1,61 @@
|
||||
module uart_rx_control
|
||||
(
|
||||
input clk_50m,
|
||||
input rst_n,
|
||||
input uart_rx_done,
|
||||
input [7:0] uart_rx_data,
|
||||
output [31:0] data_out_0,
|
||||
output [15:0] data_out_1,
|
||||
output [15:0] data_out_2,
|
||||
output uart_done
|
||||
);
|
||||
reg [31:0] uart_data_buf_0;
|
||||
reg [31:0] data_out_r_0;
|
||||
|
||||
reg [15:0] uart_data_buf_1;
|
||||
reg [15:0] data_out_r_1;
|
||||
|
||||
reg [15:0] uart_data_buf_2;
|
||||
reg [15:0] data_out_r_2;
|
||||
|
||||
reg [4:0] state;
|
||||
reg uart_done_buf;
|
||||
|
||||
always@(posedge clk_50m or negedge rst_n)
|
||||
begin
|
||||
if(!rst_n)
|
||||
begin
|
||||
state <= 4'd0;
|
||||
uart_data_buf_0 <= 32'd0;
|
||||
uart_data_buf_1 <= 15'd0;
|
||||
uart_data_buf_2 <= 15'd0;
|
||||
uart_done_buf <= 1'd0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
case(state)
|
||||
5'd0:begin uart_done_buf<=1'd0; state<=state+1; end
|
||||
5'd1:if((uart_rx_data == 8'h99)&&uart_rx_done)begin state<=state+1; end
|
||||
5'd2:if((uart_rx_data == 8'h50)&&uart_rx_done)begin state<=state+1; end
|
||||
5'd3:if(uart_rx_done)begin uart_data_buf_0[7:0]<=uart_rx_data; state<=state+1; end
|
||||
5'd4:if(uart_rx_done)begin uart_data_buf_0[15:8]<=uart_rx_data; state<=state+1; end
|
||||
5'd5:if(uart_rx_done)begin uart_data_buf_0[23:16]<=uart_rx_data; state<=state+1; end
|
||||
5'd6:if(uart_rx_done)begin uart_data_buf_0[31:24]<=uart_rx_data; state<=state+1; end
|
||||
5'd7:if(uart_rx_done)begin uart_data_buf_1[7:0]<=uart_rx_data; state<=state+1; end
|
||||
5'd8:if(uart_rx_done)begin uart_data_buf_1[15:8]<=uart_rx_data; state<=state+1; end
|
||||
5'd9:if(uart_rx_done)begin uart_data_buf_2[7:0]<=uart_rx_data; state<=state+1; end
|
||||
5'd10:if(uart_rx_done)begin uart_data_buf_2[15:8]<=uart_rx_data; state<=state+1; end
|
||||
5'd11:begin data_out_r_0<=uart_data_buf_0;
|
||||
data_out_r_1<=uart_data_buf_1;
|
||||
data_out_r_2<=uart_data_buf_2;
|
||||
uart_done_buf<=1'd1; state<=4'd0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
assign data_out_0 = data_out_r_0;
|
||||
assign data_out_1 = data_out_r_1;
|
||||
assign data_out_2 = data_out_r_2;
|
||||
|
||||
assign uart_done = uart_done_buf;
|
||||
endmodule
|
110
lib/common/Driver/UART_driver/uart_tx_control.v
Normal file
110
lib/common/Driver/UART_driver/uart_tx_control.v
Normal file
@ -0,0 +1,110 @@
|
||||
module uart_tx_control
|
||||
(
|
||||
input clk_50m,
|
||||
input rst_n,
|
||||
input uart_tx_done,
|
||||
input start_sig,
|
||||
input [31:0] uart_data_a,
|
||||
input [31:0] uart_data_b,
|
||||
input [1:0] mod,
|
||||
output [7:0] uart_tx_data,
|
||||
output tx_sig_q,
|
||||
output uart_tx_en
|
||||
);
|
||||
parameter clk_pw_div_1 = 16'd44999;
|
||||
parameter clk_pw_div_2 = 16'd249999;
|
||||
reg [4:0] state;
|
||||
reg [7:0] uart_tx_data_r;
|
||||
reg tx_en_r;
|
||||
reg tx_sig;
|
||||
reg [31:0] uart_data_a_buf;
|
||||
reg [31:0] uart_data_b_buf;
|
||||
reg start_sig_buf;
|
||||
reg [2:0] state_sweep;
|
||||
reg [2:0] state_piont;
|
||||
reg [22:0] clk_cnt;
|
||||
always@(posedge clk_50m or negedge rst_n)
|
||||
begin
|
||||
if(!rst_n)
|
||||
begin
|
||||
start_sig_buf <= 1'd0;
|
||||
state_sweep <= 3'd0;
|
||||
state_piont <= 3'd0;
|
||||
clk_cnt <= 23'd0;
|
||||
end
|
||||
else if(mod == 2'b01)//扫频
|
||||
begin
|
||||
state_piont <= 3'd0;
|
||||
case(state_sweep)
|
||||
3'd0:begin start_sig_buf<=1'd0; clk_cnt<=15'd0; state_sweep<=3'd1;end
|
||||
3'd1:begin if(start_sig) state_sweep<=2'd2;end
|
||||
3'd2:begin if(clk_cnt==clk_pw_div_1) state_sweep<=3'd3; else clk_cnt<=clk_cnt+23'd1;end
|
||||
3'd3:begin start_sig_buf<=1'd1; state_sweep<=3'd0; end
|
||||
endcase
|
||||
end
|
||||
else if(mod == 2'b10)//点频
|
||||
begin
|
||||
state_sweep <= 3'd0;
|
||||
case(state_piont)
|
||||
3'd0:begin start_sig_buf<=1'd0; clk_cnt<=15'd0; state_piont<=3'd1;end
|
||||
3'd1:begin if(start_sig) state_piont<=2'd2;end
|
||||
3'd2:begin start_sig_buf<=1'd0; if(clk_cnt==clk_pw_div_2) state_piont<=3'd3; else clk_cnt<=clk_cnt+23'd1;end
|
||||
3'd3:begin start_sig_buf<=1'd1; clk_cnt<=15'd0; state_piont<=3'd2; end
|
||||
endcase
|
||||
end
|
||||
else
|
||||
begin
|
||||
start_sig_buf <= 1'd0;
|
||||
state_sweep <= 3'd0;
|
||||
state_piont <= 3'd0;
|
||||
clk_cnt <= 15'd0;
|
||||
end
|
||||
end
|
||||
|
||||
always@(posedge clk_50m or negedge rst_n)
|
||||
begin
|
||||
if(!rst_n)
|
||||
begin
|
||||
uart_data_a_buf <= 28'd0;
|
||||
uart_data_b_buf <= 28'd0;
|
||||
end
|
||||
else if(start_sig_buf)
|
||||
begin
|
||||
uart_data_a_buf <= uart_data_a;
|
||||
uart_data_b_buf <= uart_data_b;
|
||||
end
|
||||
end
|
||||
always@(posedge clk_50m or negedge rst_n)
|
||||
begin
|
||||
if(!rst_n)
|
||||
begin
|
||||
state <= 5'd0;
|
||||
tx_sig <= 1'd0;
|
||||
uart_tx_data_r <= 8'd0;
|
||||
tx_en_r <= 1'd0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
case(state)
|
||||
5'd0:begin if(start_sig_buf)begin state<=state+1; tx_sig<=0; tx_en_r<=1; end end
|
||||
5'd1:begin uart_tx_data_r<=8'h99; tx_en_r<=1; state<=state+1; end
|
||||
5'd2:begin if(uart_tx_done) begin uart_tx_data_r<=8'h24; tx_en_r<=1; state<=state+1; end end
|
||||
5'd3:begin if(uart_tx_done) begin uart_tx_data_r<=uart_data_a_buf[7:0]; tx_en_r<=1; state<=state+1; end end
|
||||
5'd4:begin if(uart_tx_done) begin uart_tx_data_r<=uart_data_a_buf[15:8]; tx_en_r<=1; state<=state+1; end end
|
||||
5'd5:begin if(uart_tx_done) begin uart_tx_data_r<=uart_data_a_buf[23:16]; tx_en_r<=1; state<=state+1; end end
|
||||
5'd6:begin if(uart_tx_done) begin uart_tx_data_r<=uart_data_a_buf[31:24]; tx_en_r<=1; state<=state+1; end end
|
||||
5'd7:begin if(uart_tx_done) begin uart_tx_data_r<=uart_data_b_buf[7:0]; tx_en_r<=1; state<=state+1; end end
|
||||
5'd8:begin if(uart_tx_done) begin uart_tx_data_r<=uart_data_b_buf[15:8]; tx_en_r<=1; state<=state+1; end end
|
||||
5'd9:begin if(uart_tx_done) begin uart_tx_data_r<=uart_data_b_buf[23:16]; tx_en_r<=1; state<=state+1; end end
|
||||
5'd10:begin if(uart_tx_done) begin uart_tx_data_r<=uart_data_b_buf[31:24]; tx_en_r<=1; state<=state+1; end end
|
||||
5'd11:begin tx_en_r<=0; state<=state+1; end
|
||||
5'd12:begin if(uart_tx_done) begin tx_sig<=1; state<=5'd0;end end
|
||||
default:begin state <= 0; end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
assign uart_tx_data = uart_tx_data_r;
|
||||
assign uart_tx_en = tx_en_r;
|
||||
assign tx_sig_q = tx_sig;
|
||||
endmodule
|
||||
|
277
lib/common/Malloc/FIFO/async_fifo.v
Normal file
277
lib/common/Malloc/FIFO/async_fifo.v
Normal file
@ -0,0 +1,277 @@
|
||||
//-------------------------------------------
|
||||
// async FIFO
|
||||
//-----------------------------------------------
|
||||
`timescale 1ns/1ps
|
||||
module async_fifo #(
|
||||
parameter W = 4'd8
|
||||
) (
|
||||
//timing for wr
|
||||
input wr_clk,
|
||||
input wr_reset_n,
|
||||
input wr_en,
|
||||
output full,
|
||||
output afull,
|
||||
input [W-1 : 0] wr_data,
|
||||
//timing for rd
|
||||
input rd_clk,
|
||||
input rd_reset_n,
|
||||
input rd_en,
|
||||
output empty,
|
||||
output aempty,
|
||||
output [W-1 : 0] rd_data
|
||||
);
|
||||
|
||||
parameter DP = 3'd4;
|
||||
parameter WR_FAST = 1'b1;
|
||||
parameter RD_FAST = 1'b1;
|
||||
parameter EMPTY_DP = 1'b0;
|
||||
parameter FULL_DP = DP;
|
||||
|
||||
parameter AW = (DP == 2) ? 1 :
|
||||
(DP == 4) ? 2 :
|
||||
(DP == 8) ? 3 :
|
||||
(DP == 16) ? 4 :
|
||||
(DP == 32) ? 5 :
|
||||
(DP == 64) ? 6 :
|
||||
(DP == 128) ? 7 :
|
||||
(DP == 256) ? 8 : 0;
|
||||
// synopsys translate_off
|
||||
|
||||
initial begin
|
||||
if (AW == 0) begin
|
||||
$display ("%m : ERROR!!! Fifo depth %d not in range 2 to 256", DP);
|
||||
end // if (AW == 0)
|
||||
end // initial begin
|
||||
|
||||
// synopsys translate_on
|
||||
|
||||
reg [W-1 : 0] mem[DP-1 : 0];
|
||||
|
||||
/*********************** write side ************************/
|
||||
reg [AW:0] sync_rd_ptr_0, sync_rd_ptr_1;
|
||||
wire [AW:0] sync_rd_ptr;
|
||||
reg [AW:0] wr_ptr, grey_wr_ptr;
|
||||
reg [AW:0] grey_rd_ptr;
|
||||
reg full_q;
|
||||
wire full_c;
|
||||
wire afull_c;
|
||||
wire [AW:0] wr_ptr_inc = wr_ptr + 1'b1;
|
||||
wire [AW:0] wr_cnt = get_cnt(wr_ptr, sync_rd_ptr);
|
||||
|
||||
assign full_c = (wr_cnt == FULL_DP) ? 1'b1 : 1'b0;
|
||||
assign afull_c = (wr_cnt == FULL_DP-1) ? 1'b1 : 1'b0;
|
||||
|
||||
always @(posedge wr_clk or negedge wr_reset_n) begin
|
||||
if (!wr_reset_n) begin
|
||||
wr_ptr <= 0;
|
||||
grey_wr_ptr <= 0;
|
||||
full_q <= 0;
|
||||
end
|
||||
else if (wr_en) begin
|
||||
wr_ptr <= wr_ptr_inc;
|
||||
grey_wr_ptr <= bin2grey(wr_ptr_inc);
|
||||
if (wr_cnt == (FULL_DP-1)) begin
|
||||
full_q <= 1'b1;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
if (full_q && (wr_cnt<FULL_DP)) begin
|
||||
full_q <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign full = (WR_FAST == 1) ? full_c : full_q;
|
||||
assign afull = afull_c;
|
||||
|
||||
always @(posedge wr_clk) begin
|
||||
if (wr_en) begin
|
||||
mem[wr_ptr[AW-1:0]] <= wr_data;
|
||||
end
|
||||
end
|
||||
|
||||
wire [AW:0] grey_rd_ptr_dly ;
|
||||
assign #1 grey_rd_ptr_dly = grey_rd_ptr;
|
||||
|
||||
// read pointer synchronizer
|
||||
always @(posedge wr_clk or negedge wr_reset_n) begin
|
||||
if (!wr_reset_n) begin
|
||||
sync_rd_ptr_0 <= 0;
|
||||
sync_rd_ptr_1 <= 0;
|
||||
end
|
||||
else begin
|
||||
sync_rd_ptr_0 <= grey_rd_ptr_dly;
|
||||
sync_rd_ptr_1 <= sync_rd_ptr_0;
|
||||
end
|
||||
end
|
||||
|
||||
assign sync_rd_ptr = grey2bin(sync_rd_ptr_1);
|
||||
|
||||
/************************ read side *****************************/
|
||||
reg [AW:0] sync_wr_ptr_0, sync_wr_ptr_1;
|
||||
wire [AW:0] sync_wr_ptr;
|
||||
reg [AW:0] rd_ptr;
|
||||
reg empty_q;
|
||||
wire empty_c;
|
||||
wire aempty_c;
|
||||
wire [AW:0] rd_ptr_inc = rd_ptr + 1'b1;
|
||||
wire [AW:0] sync_wr_ptr_dec = sync_wr_ptr - 1'b1;
|
||||
wire [AW:0] rd_cnt = get_cnt(sync_wr_ptr, rd_ptr);
|
||||
|
||||
assign empty_c = (rd_cnt == 0) ? 1'b1 : 1'b0;
|
||||
assign aempty_c = (rd_cnt == 1) ? 1'b1 : 1'b0;
|
||||
|
||||
always @(posedge rd_clk or negedge rd_reset_n) begin
|
||||
if (!rd_reset_n) begin
|
||||
rd_ptr <= 0;
|
||||
grey_rd_ptr <= 0;
|
||||
empty_q <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
if (rd_en) begin
|
||||
rd_ptr <= rd_ptr_inc;
|
||||
grey_rd_ptr <= bin2grey(rd_ptr_inc);
|
||||
if (rd_cnt==(EMPTY_DP+1)) begin
|
||||
empty_q <= 1'b1;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
if (empty_q && (rd_cnt!=EMPTY_DP)) begin
|
||||
empty_q <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign empty = (RD_FAST == 1) ? empty_c : empty_q;
|
||||
assign aempty = aempty_c;
|
||||
|
||||
reg [W-1 : 0] rd_data_q;
|
||||
|
||||
wire [W-1 : 0] rd_data_c = mem[rd_ptr[AW-1:0]];
|
||||
always @(posedge rd_clk) begin
|
||||
rd_data_q <= rd_data_c;
|
||||
end
|
||||
assign rd_data = (RD_FAST == 1) ? rd_data_c : rd_data_q;
|
||||
|
||||
wire [AW:0] grey_wr_ptr_dly ;
|
||||
assign #1 grey_wr_ptr_dly = grey_wr_ptr;
|
||||
|
||||
// write pointer synchronizer
|
||||
always @(posedge rd_clk or negedge rd_reset_n) begin
|
||||
if (!rd_reset_n) begin
|
||||
sync_wr_ptr_0 <= 0;
|
||||
sync_wr_ptr_1 <= 0;
|
||||
end
|
||||
else begin
|
||||
sync_wr_ptr_0 <= grey_wr_ptr_dly;
|
||||
sync_wr_ptr_1 <= sync_wr_ptr_0;
|
||||
end
|
||||
end
|
||||
assign sync_wr_ptr = grey2bin(sync_wr_ptr_1);
|
||||
|
||||
/************************ functions ******************************/
|
||||
function [AW:0] bin2grey;
|
||||
input [AW:0] bin;
|
||||
reg [8:0] bin_8;
|
||||
reg [8:0] grey_8;
|
||||
begin
|
||||
bin_8 = bin;
|
||||
grey_8[1:0] = do_grey(bin_8[2:0]);
|
||||
grey_8[3:2] = do_grey(bin_8[4:2]);
|
||||
grey_8[5:4] = do_grey(bin_8[6:4]);
|
||||
grey_8[7:6] = do_grey(bin_8[8:6]);
|
||||
grey_8[8] = bin_8[8];
|
||||
bin2grey = grey_8;
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [AW:0] grey2bin;
|
||||
input [AW:0] grey;
|
||||
reg [8:0] grey_8;
|
||||
reg [8:0] bin_8;
|
||||
begin
|
||||
grey_8 = grey;
|
||||
bin_8[8] = grey_8[8];
|
||||
bin_8[7:6] = do_bin({bin_8[8], grey_8[7:6]});
|
||||
bin_8[5:4] = do_bin({bin_8[6], grey_8[5:4]});
|
||||
bin_8[3:2] = do_bin({bin_8[4], grey_8[3:2]});
|
||||
bin_8[1:0] = do_bin({bin_8[2], grey_8[1:0]});
|
||||
grey2bin = bin_8;
|
||||
end
|
||||
endfunction
|
||||
|
||||
|
||||
function [1:0] do_grey;
|
||||
input [2:0] bin;
|
||||
begin
|
||||
if (bin[2]) begin // do reverse grey
|
||||
case (bin[1:0])
|
||||
2'b00: do_grey = 2'b10;
|
||||
2'b01: do_grey = 2'b11;
|
||||
2'b10: do_grey = 2'b01;
|
||||
2'b11: do_grey = 2'b00;
|
||||
endcase
|
||||
end
|
||||
else begin
|
||||
case (bin[1:0])
|
||||
2'b00: do_grey = 2'b00;
|
||||
2'b01: do_grey = 2'b01;
|
||||
2'b10: do_grey = 2'b11;
|
||||
2'b11: do_grey = 2'b10;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [1:0] do_bin;
|
||||
input [2:0] grey;
|
||||
begin
|
||||
if (grey[2]) begin // actually bin[2]
|
||||
case (grey[1:0])
|
||||
2'b10: do_bin = 2'b00;
|
||||
2'b11: do_bin = 2'b01;
|
||||
2'b01: do_bin = 2'b10;
|
||||
2'b00: do_bin = 2'b11;
|
||||
endcase
|
||||
end
|
||||
else begin
|
||||
case (grey[1:0])
|
||||
2'b00: do_bin = 2'b00;
|
||||
2'b01: do_bin = 2'b01;
|
||||
2'b11: do_bin = 2'b10;
|
||||
2'b10: do_bin = 2'b11;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [AW:0] get_cnt;
|
||||
input [AW:0] wr_ptr, rd_ptr;
|
||||
begin
|
||||
if (wr_ptr >= rd_ptr) begin
|
||||
get_cnt = (wr_ptr - rd_ptr);
|
||||
end
|
||||
else begin
|
||||
get_cnt = DP*2 - (rd_ptr - wr_ptr);
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
// synopsys translate_off
|
||||
always @(posedge wr_clk) begin
|
||||
if (wr_en && full) begin
|
||||
$display($time, "%m Error! afifo overflow!");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge rd_clk) begin
|
||||
if (rd_en && empty) begin
|
||||
$display($time, "%m error! afifo underflow!");
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
// synopsys translate_on
|
||||
|
||||
endmodule
|
101
lib/common/Malloc/FIFO/sync_fifo.v
Normal file
101
lib/common/Malloc/FIFO/sync_fifo.v
Normal file
@ -0,0 +1,101 @@
|
||||
`timescale 1ns/1ps
|
||||
module sync_fifo #(
|
||||
parameter W = 8
|
||||
)
|
||||
(
|
||||
input clk,
|
||||
input reset_n,
|
||||
input rd_en,
|
||||
output [W-1 : 0] rd_data,
|
||||
input wr_en,
|
||||
input [W-1 : 0] wr_data,
|
||||
output reg full,
|
||||
output reg empty
|
||||
);
|
||||
|
||||
parameter D = 4;
|
||||
|
||||
parameter AW = (D == 4) ? 2 :
|
||||
(D == 8) ? 3 :
|
||||
(D == 16) ? 4 :
|
||||
(D == 32) ? 5 :
|
||||
(D == 64) ? 6 :
|
||||
(D == 128) ? 7 :
|
||||
(D == 256) ? 8 : 0;
|
||||
|
||||
// synopsys translate_off
|
||||
initial begin
|
||||
if (AW == 0) begin
|
||||
$display ("%m : ERROR!!! Fifo depth %d not in range 4 to 256", D);
|
||||
end // if (AW == 0)
|
||||
end // initial begin
|
||||
|
||||
// synopsys translate_on
|
||||
|
||||
reg [W-1 : 0] mem[D-1 : 0];
|
||||
reg [AW-1 : 0] rd_ptr, wr_ptr;
|
||||
|
||||
always @ (posedge clk or negedge reset_n)
|
||||
if (reset_n == 1'b0) begin
|
||||
wr_ptr <= {AW{1'b0}} ;
|
||||
end
|
||||
else begin
|
||||
if (wr_en & !full) begin
|
||||
wr_ptr <= wr_ptr + 1'b1 ;
|
||||
end
|
||||
end
|
||||
|
||||
always @ (posedge clk or negedge reset_n)
|
||||
if (reset_n == 1'b0) begin
|
||||
rd_ptr <= {AW{1'b0}} ;
|
||||
end
|
||||
else begin
|
||||
if (rd_en & !empty) begin
|
||||
rd_ptr <= rd_ptr + 1'b1 ;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
always @ (posedge clk or negedge reset_n)
|
||||
if (reset_n == 1'b0) begin
|
||||
empty <= 1'b1 ;
|
||||
end
|
||||
else begin
|
||||
empty <= (((wr_ptr - rd_ptr) == {{(AW-1){1'b0}}, 1'b1}) & rd_en & ~wr_en) ? 1'b1 :
|
||||
((wr_ptr == rd_ptr) & ~rd_en & wr_en) ? 1'b0 : empty ;
|
||||
end
|
||||
|
||||
always @ (posedge clk or negedge reset_n)
|
||||
if (reset_n == 1'b0) begin
|
||||
full <= 1'b0 ;
|
||||
end
|
||||
else begin
|
||||
full <= (((wr_ptr - rd_ptr) == {{(AW-1){1'b1}}, 1'b0}) & ~rd_en & wr_en) ? 1'b1 :
|
||||
(((wr_ptr - rd_ptr) == {AW{1'b1}}) & rd_en & ~wr_en) ? 1'b0 : full ;
|
||||
end
|
||||
|
||||
always @ (posedge clk)
|
||||
if (wr_en)
|
||||
mem[wr_ptr] <= wr_data;
|
||||
|
||||
assign rd_data = mem[rd_ptr];
|
||||
|
||||
|
||||
// synopsys translate_off
|
||||
always @(posedge clk) begin
|
||||
if (wr_en && full) begin
|
||||
$display("%m : Error! sfifo overflow!");
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rd_en && empty) begin
|
||||
$display("%m : error! sfifo underflow!");
|
||||
end
|
||||
end
|
||||
// synopsys translate_on
|
||||
//---------------------------------------
|
||||
|
||||
endmodule
|
||||
|
||||
|
33
lib/common/Malloc/RAM/Shift_RAM/Line_Shift_RAM.v
Normal file
33
lib/common/Malloc/RAM/Shift_RAM/Line_Shift_RAM.v
Normal file
@ -0,0 +1,33 @@
|
||||
module Line_Shift_RAM #(
|
||||
parameter RAM_Length = 640, //640*480
|
||||
parameter DATA_WIDTH = 8
|
||||
) (
|
||||
input clken,
|
||||
input clock,
|
||||
input [DATA_WIDTH-1:0] shiftin,
|
||||
output [DATA_WIDTH-1:0] taps0x,
|
||||
output [DATA_WIDTH-1:0] taps1x
|
||||
);
|
||||
|
||||
RAMshift_taps #(
|
||||
.TOTAL_RAM_Length (RAM_Length),
|
||||
.DATA_WIDTH (DATA_WIDTH)
|
||||
) RAMshfit_taps_u1 (
|
||||
.clken(clken),
|
||||
.clock(clock),
|
||||
.Delay_Length(RAM_Length),
|
||||
.shiftin(shiftin),
|
||||
.shiftout(taps0x)
|
||||
);
|
||||
|
||||
RAMshift_taps #(
|
||||
.TOTAL_RAM_Length (RAM_Length),
|
||||
.DATA_WIDTH (DATA_WIDTH)
|
||||
) RAMshfit_taps_u2 (
|
||||
.clken(clken),
|
||||
.clock(clock),
|
||||
.Delay_Length(RAM_Length),
|
||||
.shiftin(taps0x),
|
||||
.shiftout(taps1x)
|
||||
);
|
||||
endmodule
|
46
lib/common/Malloc/RAM/Shift_RAM/RAMshift_taps.v
Normal file
46
lib/common/Malloc/RAM/Shift_RAM/RAMshift_taps.v
Normal file
@ -0,0 +1,46 @@
|
||||
`timescale 1 ns / 1 ns
|
||||
|
||||
module RAMshift_taps #(
|
||||
parameter TOTAL_RAM_Length = 640,
|
||||
parameter DATA_WIDTH = 8
|
||||
) (
|
||||
input clken,
|
||||
input clock,
|
||||
input [31:0] Delay_Length,
|
||||
input [DATA_WIDTH - 1 : 0] shiftin,
|
||||
output [DATA_WIDTH - 1 : 0] shiftout
|
||||
);
|
||||
|
||||
reg [31:0] RAM_CNT = 0;
|
||||
reg [DATA_WIDTH - 1 : 0] ram_buf = 0;
|
||||
reg [DATA_WIDTH - 1 : 0] shift_ram [TOTAL_RAM_Length - 1 : 0];
|
||||
|
||||
integer m;
|
||||
initial begin
|
||||
for (m = 0; m<=TOTAL_RAM_Length; m=m+1) begin
|
||||
shift_ram[m] = 0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (RAM_CNT == (Delay_Length - 1))
|
||||
RAM_CNT <= 0;
|
||||
else if (clken)
|
||||
RAM_CNT <= RAM_CNT + 1;
|
||||
else
|
||||
RAM_CNT <= RAM_CNT;
|
||||
end
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (clken) begin
|
||||
shift_ram[RAM_CNT] <= shiftin;
|
||||
end
|
||||
else begin
|
||||
shift_ram[RAM_CNT] <= shift_ram[RAM_CNT];
|
||||
end
|
||||
end
|
||||
|
||||
assign shiftout = shift_ram[RAM_CNT];
|
||||
|
||||
endmodule
|
||||
|
258
lib/common/Math/Cordic.v
Normal file
258
lib/common/Math/Cordic.v
Normal file
@ -0,0 +1,258 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module Cordic #(
|
||||
parameter XY_BITS = 12,
|
||||
parameter PH_BITS = 32,
|
||||
parameter ITERATIONS = 32,
|
||||
parameter CORDIC_STYLE = "ROTATE",
|
||||
parameter PHASE_ACC = "ON"
|
||||
)(
|
||||
input clk,
|
||||
input RST,
|
||||
input signed [XY_BITS-1:0] x_i,
|
||||
input signed [XY_BITS-1:0] y_i,
|
||||
input signed [PH_BITS-1:0] phase_in,
|
||||
|
||||
output signed [XY_BITS-1:0] x_o,
|
||||
output signed [XY_BITS-1:0] y_o,
|
||||
output signed [PH_BITS-1:0] phase_out,
|
||||
|
||||
input valid_in,
|
||||
output valid_out
|
||||
);
|
||||
|
||||
localparam [XY_BITS-1:0] K_COS = (0.607252935 * 2**(XY_BITS-1))-2;
|
||||
|
||||
/*
|
||||
//360°--2^16,phase_in = 16bits (input [15:0] phase_in)
|
||||
//1°--2^16/360
|
||||
*/
|
||||
function [PH_BITS-1:0] tanangle;
|
||||
input [4:0] i;
|
||||
begin
|
||||
case (i)
|
||||
5'b00000: tanangle = (32'h20000000 >> (32 - PH_BITS)); //tan = 1/2^1 = 1/2
|
||||
5'b00001: tanangle = (32'h12e4051e >> (32 - PH_BITS)); //tan = 1/2^2 = 1/4
|
||||
5'b00010: tanangle = (32'h09fb385b >> (32 - PH_BITS)); //tan = 1/2^3 = 1/8
|
||||
5'b00011: tanangle = (32'h051111d4 >> (32 - PH_BITS)); //tan = 1/2^4 = 1/16
|
||||
5'b00100: tanangle = (32'h028b0d43 >> (32 - PH_BITS)); //tan = 1/2^5 = 1/32
|
||||
5'b00101: tanangle = (32'h0145d7e1 >> (32 - PH_BITS)); //tan = 1/2^6 = 1/64
|
||||
5'b00110: tanangle = (32'h00a2f61e >> (32 - PH_BITS)); //tan = 1/2^7 = 1/128
|
||||
5'b00111: tanangle = (32'h00517c55 >> (32 - PH_BITS)); //tan = 1/2^8 = 1/256
|
||||
5'b01000: tanangle = (32'h0028be53 >> (32 - PH_BITS)); //tan = 1/2^9 = 1/512
|
||||
5'b01001: tanangle = (32'h00145f2f >> (32 - PH_BITS)); //tan = 1/2^10 = 1/1024
|
||||
5'b01010: tanangle = (32'h000a2f98 >> (32 - PH_BITS)); //tan = 1/2^11 = 1/2048
|
||||
5'b01011: tanangle = (32'h000517cc >> (32 - PH_BITS)); //tan = 1/2^12 = 1/4096
|
||||
5'b01100: tanangle = (32'h00028be6 >> (32 - PH_BITS)); //tan = 1/2^13 = 1/8192
|
||||
5'b01101: tanangle = (32'h000145f3 >> (32 - PH_BITS)); //tan = 1/2^14 = 1/16384
|
||||
5'b01110: tanangle = (32'h0000a2fa >> (32 - PH_BITS)); //tan = 1/2^15 = 1/32768
|
||||
5'b01111: tanangle = (32'h0000517d >> (32 - PH_BITS)); //tan = 1/2^16 = 1/65536
|
||||
5'b10000: tanangle = (32'h000028be >> (32 - PH_BITS)); //tan = 1/2^17 = 1/131072
|
||||
5'b10001: tanangle = (32'h0000145f >> (32 - PH_BITS)); //tan = 1/2^18 = 1/262144
|
||||
5'b10010: tanangle = (32'h00000a30 >> (32 - PH_BITS)); //tan = 1/2^19 = 1/524288
|
||||
5'b10011: tanangle = (32'h00000518 >> (32 - PH_BITS)); //tan = 1/2^20 = 1/1048576
|
||||
5'b10100: tanangle = (32'h0000028c >> (32 - PH_BITS)); //tan = 1/2^21 = 1/2097152
|
||||
5'b10101: tanangle = (32'h00000146 >> (32 - PH_BITS)); //tan = 1/2^22 = 1/4194304
|
||||
5'b10110: tanangle = (32'h000000a3 >> (32 - PH_BITS)); //tan = 1/2^23 = 1/8388608
|
||||
5'b10111: tanangle = (32'h00000051 >> (32 - PH_BITS)); //tan = 1/2^24 = 1/16777216
|
||||
5'b11000: tanangle = (32'h00000029 >> (32 - PH_BITS)); //tan = 1/2^25 = 1/33554432
|
||||
5'b11001: tanangle = (32'h00000014 >> (32 - PH_BITS)); //tan = 1/2^26 = 1/67108864
|
||||
5'b11010: tanangle = (32'h0000000a >> (32 - PH_BITS)); //tan = 1/2^27 = 1/134217728
|
||||
5'b11011: tanangle = (32'h00000005 >> (32 - PH_BITS)); //tan = 1/2^28 = 1/268435456
|
||||
5'b11100: tanangle = (32'h00000003 >> (32 - PH_BITS)); //tan = 1/2^29 = 1/536870912
|
||||
5'b11101: tanangle = (32'h00000001 >> (32 - PH_BITS)); //tan = 1/2^30 = 1/1073741824
|
||||
5'b11110: tanangle = (32'h00000001 >> (32 - PH_BITS)); //tan = 1/2^31 = 1/2147483648
|
||||
5'b11111: tanangle = (32'h00000000 >> (32 - PH_BITS)); //tan = 1/2^32 = 1/4294967296
|
||||
endcase
|
||||
end
|
||||
endfunction
|
||||
|
||||
reg [1:0] data_in_buff [ITERATIONS:0];
|
||||
reg signed [XY_BITS-1:0] x [ITERATIONS:0];
|
||||
reg signed [XY_BITS-1:0] y [ITERATIONS:0];
|
||||
reg signed [PH_BITS-1:0] z [ITERATIONS:0];
|
||||
|
||||
integer m;
|
||||
initial begin
|
||||
for (m = 0; m<=ITERATIONS; m=m+1) begin
|
||||
x[m] = 0;
|
||||
end
|
||||
end
|
||||
|
||||
integer n;
|
||||
initial begin
|
||||
for (n = 0; n<=ITERATIONS; n=n+1) begin
|
||||
y[n] = 0;
|
||||
end
|
||||
end
|
||||
|
||||
integer s;
|
||||
initial begin
|
||||
for (s = 0; s<=ITERATIONS; s=s+1) begin
|
||||
z[s] = 0;
|
||||
end
|
||||
end
|
||||
|
||||
integer k;
|
||||
initial begin
|
||||
for (k = 0; k<=ITERATIONS; k=k+1) begin
|
||||
data_in_buff[k] = 0;
|
||||
end
|
||||
end
|
||||
|
||||
genvar i;
|
||||
generate for(i=0;i<ITERATIONS;i=i+1) begin : CORDIC
|
||||
always @ (posedge clk) begin
|
||||
if (RST) begin
|
||||
x[i+1] <= 0;
|
||||
y[i+1] <= 0;
|
||||
z[i+1] <= 0;
|
||||
end
|
||||
else begin
|
||||
if (CORDIC_STYLE == "ROTATE") begin
|
||||
if (z[i] < 0) begin
|
||||
x[i+1] <= x[i] + (y[i]>>>i);
|
||||
y[i+1] <= y[i] - (x[i]>>>i);
|
||||
z[i+1] <= z[i] + tanangle(i);
|
||||
end
|
||||
else begin
|
||||
x[i+1] <= x[i] - (y[i]>>>i);
|
||||
y[i+1] <= y[i] + (x[i]>>>i);
|
||||
z[i+1] <= z[i] - tanangle(i);
|
||||
end
|
||||
end
|
||||
else if(CORDIC_STYLE == "VECTOR") begin
|
||||
if (y[i] > 0) begin
|
||||
x[i+1] <= x[i] + (y[i]>>>i);
|
||||
y[i+1] <= y[i] - (x[i]>>>i);
|
||||
z[i+1] <= z[i] + tanangle(i);
|
||||
end else begin
|
||||
x[i+1] <= x[i] - (y[i]>>>i);
|
||||
y[i+1] <= y[i] + (x[i]>>>i);
|
||||
z[i+1] <= z[i] - tanangle(i);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
always @ (posedge clk) begin
|
||||
data_in_buff[i+1] <= data_in_buff[i];
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate if (CORDIC_STYLE == "ROTATE") begin : IQ_Gen
|
||||
reg [PH_BITS - 1 : 0] Phase_input = 0;
|
||||
if (PHASE_ACC == "ON") begin
|
||||
reg [PH_BITS - 1 : 0] addr_r0 = 0;
|
||||
always @(posedge clk) begin
|
||||
addr_r0 <= addr_r0 + phase_in;
|
||||
end
|
||||
always @(posedge clk) begin
|
||||
Phase_input <= addr_r0;
|
||||
end
|
||||
end
|
||||
else if (PHASE_ACC == "OFF") begin
|
||||
always @(posedge clk) begin
|
||||
Phase_input <= phase_in;
|
||||
end
|
||||
end
|
||||
always @(posedge clk) begin
|
||||
if(valid_in & (~RST)) begin
|
||||
x[0] <= K_COS;
|
||||
y[0] <= 0;
|
||||
z[0] <= Phase_input[PH_BITS - 3 : 0];
|
||||
data_in_buff[0] <= Phase_input[PH_BITS - 1 : PH_BITS - 2];
|
||||
end
|
||||
else begin
|
||||
x[0] <= 0;
|
||||
y[0] <= 0;
|
||||
z[0] <= 0;
|
||||
data_in_buff[0] <= 0;
|
||||
end
|
||||
end
|
||||
reg signed [XY_BITS-1:0] cos = 0;
|
||||
reg signed [XY_BITS-1:0] sin = 0;
|
||||
always @ (posedge clk) begin
|
||||
case(data_in_buff[ITERATIONS])
|
||||
2'b00:begin //if the phase is in first quadrant,the sin(X)=sin(A),cos(X)=cos(A)
|
||||
cos <= x[ITERATIONS];
|
||||
sin <= y[ITERATIONS];
|
||||
end
|
||||
2'b01:begin //if the phase is in second quadrant,the sin(X)=sin(A+90)=cosA,cos(X)=cos(A+90)=-sinA
|
||||
cos <= ~(y[ITERATIONS]) + 1'b1;//-sin
|
||||
sin <= x[ITERATIONS];//cos
|
||||
end
|
||||
2'b10:begin //if the phase is in third quadrant,the sin(X)=sin(A+180)=-sinA,cos(X)=cos(A+180)=-cosA
|
||||
cos <= ~(x[ITERATIONS]) + 1'b1;//-cos
|
||||
sin <= ~(y[ITERATIONS]) + 1'b1;//-sin
|
||||
end
|
||||
2'b11:begin //if the phase is in forth quadrant,the sin(X)=sin(A+270)=-cosA,cos(X)=cos(A+270)=sinA
|
||||
cos <= y[ITERATIONS];//sin
|
||||
sin <= ~(x[ITERATIONS]) + 1'b1;//-cos
|
||||
end
|
||||
endcase
|
||||
end
|
||||
assign x_o = cos;
|
||||
assign y_o = sin;
|
||||
assign phase_out = z[ITERATIONS];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate if (CORDIC_STYLE == "VECTOR") begin : Demodule_Gen
|
||||
localparam signed [PH_BITS-1:0] PHASE_COE = (2**(PH_BITS-2)) - 1;
|
||||
//localparam MODUIUS_COE = ;
|
||||
always @(posedge clk) begin
|
||||
if(valid_in & (~RST)) begin
|
||||
case ({x_i[XY_BITS-1],y_i[XY_BITS-1]})
|
||||
2'b00 : begin x[0] <= {x_i[XY_BITS-1],x_i[XY_BITS-1:1]};
|
||||
y[0] <= {y_i[XY_BITS-1],y_i[XY_BITS-1:1]}; end
|
||||
2'b01 : begin x[0] <= {x_i[XY_BITS-1],x_i[XY_BITS-1:1]};
|
||||
y[0] <= {y_i[XY_BITS-1],y_i[XY_BITS-1:1]}; end
|
||||
2'b10 : begin x[0] <= {y_i[XY_BITS-1],y_i[XY_BITS-1:1]};
|
||||
y[0] <= -{x_i[XY_BITS-1],x_i[XY_BITS-1:1]}; end
|
||||
2'b11 : begin x[0] <= -{y_i[XY_BITS-1],y_i[XY_BITS-1:1]};
|
||||
y[0] <= {x_i[XY_BITS-1],x_i[XY_BITS-1:1]}; end
|
||||
default : begin x[0] <= {x_i[XY_BITS-1],x_i[XY_BITS-1:1]};
|
||||
y[0] <= {y_i[XY_BITS-1],y_i[XY_BITS-1:1]}; end
|
||||
endcase
|
||||
z[0] <= phase_in;
|
||||
data_in_buff[0] <= {x_i[XY_BITS-1],y_i[XY_BITS-1]};
|
||||
end
|
||||
else begin
|
||||
x[0] <= 0;
|
||||
y[0] <= 0;
|
||||
z[0] <= 0;
|
||||
data_in_buff[0] <= 0;
|
||||
end
|
||||
end
|
||||
reg [XY_BITS*2-1:0] Modulus = 0;
|
||||
wire [XY_BITS*2-1:0] Modulus_buf;
|
||||
reg signed [PH_BITS - 1:0] phase_r = 0;
|
||||
always @ (posedge clk) begin
|
||||
case(data_in_buff[ITERATIONS])
|
||||
2'b00:begin phase_r <= $signed(z[ITERATIONS]); end
|
||||
2'b01:begin phase_r <= $signed(z[ITERATIONS]); end
|
||||
2'b10:begin phase_r <= $signed(z[ITERATIONS]) + $signed(PHASE_COE); end
|
||||
2'b11:begin phase_r <= $signed(z[ITERATIONS]) - $signed(PHASE_COE); end
|
||||
endcase
|
||||
Modulus[XY_BITS:0] <= x[ITERATIONS];
|
||||
end
|
||||
assign Modulus_buf = (Modulus * 32'd39797)>>15;
|
||||
assign x_o = Modulus_buf[XY_BITS-1:0];
|
||||
assign y_o = y[ITERATIONS];
|
||||
assign phase_out = phase_r;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
reg [ITERATIONS+1:0] v = 0;
|
||||
always @ (posedge clk) begin
|
||||
if (RST)
|
||||
v <= 0;
|
||||
else begin
|
||||
v <= v << 1;
|
||||
v[0] <= valid_in;
|
||||
end
|
||||
end
|
||||
assign valid_out = v[ITERATIONS+1];
|
||||
|
||||
endmodule
|
45
lib/common/Math/Sort3.v
Normal file
45
lib/common/Math/Sort3.v
Normal file
@ -0,0 +1,45 @@
|
||||
`timescale 1ns/1ns
|
||||
module Sort3 (
|
||||
input clk,
|
||||
input rst_n,
|
||||
|
||||
input [7:0] data1, data2, data3,
|
||||
output reg [7:0] max_data, mid_data, min_data
|
||||
);
|
||||
|
||||
//-----------------------------------
|
||||
//Sort of 3 datas
|
||||
always@(posedge clk or negedge rst_n) begin
|
||||
if(!rst_n) begin
|
||||
max_data <= 0;
|
||||
mid_data <= 0;
|
||||
min_data <= 0;
|
||||
end
|
||||
else begin
|
||||
//get the max value
|
||||
if(data1 >= data2 && data1 >= data3)
|
||||
max_data <= data1;
|
||||
else if(data2 >= data1 && data2 >= data3)
|
||||
max_data <= data2;
|
||||
else//(data3 >= data1 && data3 >= data2)
|
||||
max_data <= data3;
|
||||
|
||||
//get the mid value
|
||||
if((data1 >= data2 && data1 <= data3) || (data1 >= data3 && data1 <= data2))
|
||||
mid_data <= data1;
|
||||
else if((data2 >= data1 && data2 <= data3) || (data2 >= data3 && data2 <= data1))
|
||||
mid_data <= data2;
|
||||
else//((data3 >= data1 && data3 <= data2) || (data3 >= data2 && data3 <= data1))
|
||||
mid_data <= data3;
|
||||
|
||||
//ge the min value
|
||||
if(data1 <= data2 && data1 <= data3)
|
||||
min_data <= data1;
|
||||
else if(data2 <= data1 && data2 <= data3)
|
||||
min_data <= data2;
|
||||
else//(data3 <= data1 && data3 <= data2)
|
||||
min_data <= data3;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
63
lib/common/Math/phase_acc.v
Normal file
63
lib/common/Math/phase_acc.v
Normal file
@ -0,0 +1,63 @@
|
||||
module phase_acc(clr,en,rst,valid_out1,clk,add_sub,sel,D,Q);
|
||||
parameter DATASIZE=16;
|
||||
input clr,en,rst,clk,add_sub,sel,valid_out1;
|
||||
input [DATASIZE-1:0] D;
|
||||
output [DATASIZE:0] Q;
|
||||
|
||||
reg count0,count1,count2,count3;
|
||||
reg [DATASIZE:0] b_tmp,b_tmp0,b_tmp1,b_tmp2;
|
||||
reg [3:0] sum0;
|
||||
reg [7:0] sum1;
|
||||
reg [11:0] sum2;
|
||||
reg [16:0] sum3;
|
||||
reg add_sub0,add_sub1,add_sub2;
|
||||
reg clr0,clr1,clr2;
|
||||
|
||||
always @(posedge clk) begin
|
||||
case({clr,add_sub})
|
||||
2'b00:{count0,sum0}<={1'b0,sum0}+{1'b0,D[3:0]};
|
||||
2'b01:{count0,sum0}<={1'b0,sum0}-{1'b0,D[3:0]};
|
||||
2'b10:{count0,sum0}<=5'b0+{1'b0,D[3:0]};
|
||||
default:{count0,sum0}<=5'b0-{1'b0,D[3:0]};
|
||||
endcase
|
||||
b_tmp0<=D;
|
||||
clr0<=clr;
|
||||
add_sub0<=add_sub;
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
case({clr0,add_sub0})
|
||||
2'b00:{count1,sum1}<={{1'b0,sum1[7:4]}+{1'b0,b_tmp0[7:4]}+count0,sum0};
|
||||
2'b01:{count1,sum1}<={{1'b0,sum1[7:4]}-{1'b0,b_tmp0[7:4]}-count0,sum0};
|
||||
2'b10:{count1,sum1}<=5'b0+{1'b0,b_tmp0[7:4]};
|
||||
default:{count1,sum1}<=5'b0-{1'b0,b_tmp0[7:4]};
|
||||
endcase
|
||||
b_tmp1<=b_tmp0;
|
||||
clr1<=clr0;
|
||||
add_sub1<=add_sub0;
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
case({clr1,add_sub1})
|
||||
2'b00:{count2,sum2}<={{1'b0,sum2[11:8]}+{1'b0,b_tmp1[11:8]}+count1,sum1};
|
||||
2'b01:{count2,sum2}<={{1'b0,sum2[11:8]}-{1'b0,b_tmp1[11:8]}-count1,sum1};
|
||||
2'b10:{count2,sum2}<=5'b0+{1'b0,b_tmp1[11:8]};
|
||||
default:{count2,sum2}<=5'b0-{1'b0,b_tmp1[11:8]};
|
||||
endcase
|
||||
b_tmp2<=b_tmp1;
|
||||
clr2<=clr1;
|
||||
add_sub2<=add_sub1;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
case({clr2,add_sub2})
|
||||
2'b00:sum3<={sum3[16:12]+{1'b0,b_tmp2[15:12]}+count2,sum2};
|
||||
2'b01:sum3<={sum3[16:12]-{1'b0,b_tmp2[15:12]}-count2,sum2};
|
||||
2'b10:sum3<=5'b0+{1'b0,b_tmp2[15:12]};
|
||||
default:sum3<=5'b0-{1'b0,b_tmp2[15:12]};
|
||||
endcase
|
||||
end
|
||||
assign Q=sum3;
|
||||
endmodule
|
299
lib/common/Soc/AXI4/AXI_lite.v
Normal file
299
lib/common/Soc/AXI4/AXI_lite.v
Normal file
@ -0,0 +1,299 @@
|
||||
`timescale 1 ns / 1 ps
|
||||
|
||||
module AXI #(
|
||||
parameter integer OUTPUT_WIDTH = 12,
|
||||
parameter integer PHASE_WIDTH = 32,
|
||||
parameter integer C_S_AXI_DATA_WIDTH = 32,
|
||||
parameter integer C_S_AXI_ADDR_WIDTH = 4
|
||||
) (
|
||||
// Users to add ports here
|
||||
|
||||
// User ports ends
|
||||
// Do not modify the ports beyond this line
|
||||
|
||||
input wire S_AXI_ACLK,
|
||||
input wire S_AXI_ARESETN,
|
||||
|
||||
input wire S_AXI_WVALID,
|
||||
output wire S_AXI_RVALID,
|
||||
output wire S_AXI_WREADY,
|
||||
input wire S_AXI_RREADY,
|
||||
|
||||
input wire S_AXI_AWVALID,
|
||||
input wire S_AXI_ARVALID,
|
||||
output wire S_AXI_AWREADY,
|
||||
output wire S_AXI_ARREADY,
|
||||
|
||||
input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_AWADDR,
|
||||
input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_ARADDR,
|
||||
input wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_WDATA,
|
||||
output wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_RDATA,
|
||||
|
||||
input wire [2 : 0] S_AXI_AWPROT,
|
||||
input wire [2 : 0] S_AXI_ARPROT,
|
||||
|
||||
output wire [1 : 0] S_AXI_BRESP,
|
||||
output wire [1 : 0] S_AXI_RRESP,
|
||||
|
||||
output wire S_AXI_BVALID,
|
||||
input wire S_AXI_BREADY,
|
||||
|
||||
input wire [(C_S_AXI_DATA_WIDTH/8)-1 : 0] S_AXI_WSTRB
|
||||
);
|
||||
|
||||
// AXI4LITE signals
|
||||
reg axi_awready;
|
||||
reg axi_arready;
|
||||
reg axi_bvalid;
|
||||
reg axi_rvalid;
|
||||
reg axi_wready;
|
||||
|
||||
reg [1 : 0] axi_bresp;
|
||||
reg [1 : 0] axi_rresp;
|
||||
|
||||
reg [C_S_AXI_ADDR_WIDTH-1 : 0] axi_awaddr;
|
||||
reg [C_S_AXI_ADDR_WIDTH-1 : 0] axi_araddr;
|
||||
reg [C_S_AXI_DATA_WIDTH-1 : 0] axi_rdata;
|
||||
// Example-specific design signals
|
||||
// local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH
|
||||
// ADDR_LSB is used for addressing 32/64 bit registers/memories
|
||||
// ADDR_LSB = 2 for 32 bits (n downto 2)
|
||||
// ADDR_LSB = 3 for 64 bits (n downto 3)
|
||||
localparam integer ADDR_LSB = (C_S_AXI_DATA_WIDTH/32) + 1;
|
||||
localparam integer OPT_MEM_ADDR_BITS = 1;
|
||||
//----------------------------------------------
|
||||
//-- Signals for user logic register space example
|
||||
//------------------------------------------------
|
||||
//-- Number of Slave Registers 4
|
||||
reg aw_en;
|
||||
wire slv_reg_rden;
|
||||
wire slv_reg_wren;
|
||||
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg0;
|
||||
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg1;
|
||||
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg2;
|
||||
reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg3;
|
||||
reg [C_S_AXI_DATA_WIDTH-1:0] reg_data_out;
|
||||
|
||||
integer byte_index;
|
||||
// I/O Connections assignments
|
||||
|
||||
assign S_AXI_AWREADY = axi_awready;
|
||||
assign S_AXI_WREADY = axi_wready;
|
||||
assign S_AXI_BRESP = axi_bresp;
|
||||
assign S_AXI_BVALID = axi_bvalid;
|
||||
assign S_AXI_ARREADY = axi_arready;
|
||||
assign S_AXI_RDATA = axi_rdata;
|
||||
assign S_AXI_RRESP = axi_rresp;
|
||||
assign S_AXI_RVALID = axi_rvalid;
|
||||
// Implement axi_awready generation
|
||||
// axi_awready is asserted for one S_AXI_ACLK clock cycle when both
|
||||
// S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is
|
||||
// de-asserted when reset is low.
|
||||
|
||||
always @( posedge S_AXI_ACLK ) begin
|
||||
if ( S_AXI_ARESETN == 1'b0 ) begin
|
||||
axi_awready <= 1'b0;
|
||||
aw_en <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en) begin
|
||||
axi_awready <= 1'b1;
|
||||
aw_en <= 1'b0;
|
||||
end
|
||||
else if (S_AXI_BREADY && axi_bvalid) begin
|
||||
aw_en <= 1'b1;
|
||||
axi_awready <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
axi_awready <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Implement axi_awaddr latching
|
||||
// This process is used to latch the address when both
|
||||
// S_AXI_AWVALID and S_AXI_WVALID are valid.
|
||||
always @( posedge S_AXI_ACLK ) begin
|
||||
if ( S_AXI_ARESETN == 1'b0 ) begin
|
||||
axi_awaddr <= 0;
|
||||
end
|
||||
else begin
|
||||
if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en) begin
|
||||
// Write Address latching
|
||||
axi_awaddr <= S_AXI_AWADDR;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Implement axi_wready generation
|
||||
// axi_wready is asserted for one S_AXI_ACLK clock cycle when both
|
||||
// S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is
|
||||
// de-asserted when reset is low.
|
||||
always @( posedge S_AXI_ACLK ) begin
|
||||
if ( S_AXI_ARESETN == 1'b0 ) begin
|
||||
axi_wready <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
if (~axi_wready && S_AXI_WVALID && S_AXI_AWVALID && aw_en ) begin
|
||||
axi_wready <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
axi_wready <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Implement write response logic generation
|
||||
// The write response and response valid signals are asserted by the slave
|
||||
// when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted.
|
||||
// This marks the acceptance of address and indicates the status of
|
||||
// write transaction.
|
||||
|
||||
always @( posedge S_AXI_ACLK ) begin
|
||||
if ( S_AXI_ARESETN == 1'b0 ) begin
|
||||
axi_bvalid <= 0;
|
||||
axi_bresp <= 2'b0;
|
||||
end
|
||||
else begin
|
||||
if (axi_awready && S_AXI_AWVALID && ~axi_bvalid && axi_wready && S_AXI_WVALID) begin
|
||||
// indicates a valid write response is available
|
||||
axi_bvalid <= 1'b1;
|
||||
axi_bresp <= 2'b0; // 'OKAY' response
|
||||
end // work error responses in future
|
||||
else begin
|
||||
if (S_AXI_BREADY && axi_bvalid) begin
|
||||
axi_bvalid <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Implement axi_arready generation
|
||||
// axi_arready is asserted for one S_AXI_ACLK clock cycle when
|
||||
// S_AXI_ARVALID is asserted. axi_awready is
|
||||
// de-asserted when reset (active low) is asserted.
|
||||
// The read address is also latched when S_AXI_ARVALID is
|
||||
// asserted. axi_araddr is reset to zero on reset assertion.
|
||||
|
||||
always @( posedge S_AXI_ACLK ) begin
|
||||
if ( S_AXI_ARESETN == 1'b0 ) begin
|
||||
axi_arready <= 1'b0;
|
||||
axi_araddr <= 32'b0;
|
||||
end
|
||||
else begin
|
||||
if (~axi_arready && S_AXI_ARVALID) begin
|
||||
// indicates that the slave has acceped the valid read address
|
||||
axi_arready <= 1'b1;
|
||||
// Read address latching
|
||||
axi_araddr <= S_AXI_ARADDR;
|
||||
end
|
||||
else begin
|
||||
axi_arready <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Implement axi_arvalid generation
|
||||
// axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both
|
||||
// S_AXI_ARVALID and axi_arready are asserted. The slave registers
|
||||
// data are available on the axi_rdata bus at this instance. The
|
||||
// assertion of axi_rvalid marks the validity of read data on the
|
||||
// bus and axi_rresp indicates the status of read transaction.axi_rvalid
|
||||
// is deasserted on reset (active low). axi_rresp and axi_rdata are
|
||||
// cleared to zero on reset (active low).
|
||||
always @( posedge S_AXI_ACLK ) begin
|
||||
if ( S_AXI_ARESETN == 1'b0 ) begin
|
||||
axi_rvalid <= 0;
|
||||
axi_rresp <= 0;
|
||||
end
|
||||
else begin
|
||||
if (axi_arready && S_AXI_ARVALID && ~axi_rvalid) begin
|
||||
// Valid read data is available at the read data bus
|
||||
axi_rvalid <= 1'b1;
|
||||
axi_rresp <= 2'b0; // 'OKAY' response
|
||||
end
|
||||
else if (axi_rvalid && S_AXI_RREADY) begin
|
||||
// Read data is accepted by the master
|
||||
axi_rvalid <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Output register or memory read data
|
||||
always @( posedge S_AXI_ACLK ) begin
|
||||
if ( S_AXI_ARESETN == 1'b0 ) begin
|
||||
axi_rdata <= 0;
|
||||
end
|
||||
else begin
|
||||
if (slv_reg_rden) begin
|
||||
axi_rdata <= reg_data_out; // register read data
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Implement memory mapped register select and write logic generation
|
||||
// The write data is accepted and written to memory mapped registers when
|
||||
// axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to
|
||||
// select byte enables of slave registers while writing.
|
||||
// These registers are cleared when reset (active low) is applied.
|
||||
// Slave register write enable is asserted when valid address and data are available
|
||||
// and the slave is ready to accept the write address and write data.
|
||||
assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID;
|
||||
|
||||
always @( posedge S_AXI_ACLK ) begin
|
||||
if ( S_AXI_ARESETN == 1'b0 ) begin
|
||||
slv_reg0 <= 0;
|
||||
slv_reg1 <= 0;
|
||||
slv_reg2 <= 0;
|
||||
slv_reg3 <= 0;
|
||||
end
|
||||
else begin
|
||||
if (slv_reg_wren) begin
|
||||
case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
|
||||
4'd0:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
|
||||
if ( S_AXI_WSTRB[byte_index] == 1 ) begin
|
||||
slv_reg0[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
|
||||
end
|
||||
4'd1:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
|
||||
if ( S_AXI_WSTRB[byte_index] == 1 ) begin
|
||||
slv_reg1[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
|
||||
end
|
||||
4'd2:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
|
||||
if ( S_AXI_WSTRB[byte_index] == 1 ) begin
|
||||
slv_reg2[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
|
||||
end
|
||||
4'd3:for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
|
||||
if ( S_AXI_WSTRB[byte_index] == 1 ) begin
|
||||
slv_reg3[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
|
||||
end
|
||||
default :
|
||||
begin
|
||||
slv_reg0 <= slv_reg0;
|
||||
slv_reg1 <= slv_reg1;
|
||||
slv_reg2 <= slv_reg2;
|
||||
slv_reg3 <= slv_reg3;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Implement memory mapped register select and read logic generation
|
||||
// Slave register read enable is asserted when valid address is available
|
||||
// and the slave is ready to accept the read address.
|
||||
assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid;
|
||||
always @(*) begin
|
||||
case ( axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
|
||||
4'd0 : reg_data_out <= slv_reg0;
|
||||
4'd1 : reg_data_out <= slv_reg1;
|
||||
4'd2 : reg_data_out <= slv_reg2;
|
||||
4'd3 : reg_data_out <= slv_reg3;
|
||||
default : reg_data_out <= 0;
|
||||
endcase
|
||||
end
|
||||
|
||||
// Add user logic here
|
||||
|
||||
// User logic ends
|
||||
|
||||
endmodule
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user