Skip to content
Snippets Groups Projects
Commit 3b12bd25 authored by Jean-Noël Bazin's avatar Jean-Noël Bazin
Browse files

1st version of working synthe

parent 1ae367a1
No related branches found
No related tags found
No related merge requests found
Showing
with 2684 additions and 87 deletions
# Ignore vivado project files
proj/Synthe*
proj/.Xil
# tp-synthe-etudiant
## Getting started
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
## Add your files
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
- [ ] [Add files using the command line](https://docs.gitlab.com/topics/git/add_files/#add-files-to-a-git-repository) or push an existing Git repository with the following command:
```
cd existing_repo
git remote add origin https://gitlab.imt-atlantique.fr/tp-vhdl/tp-synthe-etudiant.git
git branch -M main
git push -uf origin main
```
## Integrate with your tools
- [ ] [Set up project integrations](https://gitlab.imt-atlantique.fr/tp-vhdl/tp-synthe-etudiant/-/settings/integrations)
## Collaborate with your team
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
- [ ] [Set auto-merge](https://docs.gitlab.com/user/project/merge_requests/auto_merge/)
## Test and Deploy
Use the built-in continuous integration in GitLab.
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/)
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
***
# Editing this README
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template.
## Suggestions for a good README
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
## Name
Choose a self-explaining name for your project.
# Synthe
## Description
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
## Badges
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
## Visuals
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
## Installation
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
## Usage
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
## Support
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
## Roadmap
If you have ideas for releases in the future, it is a good idea to list them in the README.
## Contributing
State if you are open to contributions and what your requirements are for accepting them.
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
Project to build a digital synthesizer in VHDL.
4 types of waveform can be played: sine, square, triangle, saw-tooth.
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
## Play with USB keyboard
Keys A Z E R T are used to play 5 tones:
- A = Sol : 392 Hz
- Z = Si-b : 466 Hz
- E = Do : 523 Hz
- R = Mi : 659 Hz
- T = Fa : 698 Hz
## Authors and acknowledgment
Show your appreciation to those who have contributed to the project.
You can play the famous part of "Funky town" by Lipps Inc.
## License
For open source projects, say how it is licensed.
Do Do Si-b Do Sol Sol Do Fa Mi Do
E E Z E A A E T R E
## Project status
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
The switches are use to configure the waveform:
- sw1 sw0 : selects the fundamental waveform
- sw
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/26.2.2 Chrome/134.0.6998.178 Electron/35.1.2 Safari/537.36" version="26.2.2">
<diagram name="Page-1" id="ZRCvXX_TBlFcA-i0oMmK">
<mxGraphModel dx="3237" dy="1203" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="liv1zIGuVtiVySRaDl_v-15" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;fontColor=#333333;strokeColor=#666666;arcSize=3;" parent="1" vertex="1">
<mxGeometry y="40" width="1320" height="720" as="geometry" />
</mxCell>
<mxCell id="liv1zIGuVtiVySRaDl_v-1" value="A" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Ubuntu Mono;fontSize=40;" parent="1" vertex="1">
<mxGeometry x="160" y="80" width="280" height="160" as="geometry" />
</mxCell>
<mxCell id="liv1zIGuVtiVySRaDl_v-2" value="D" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Ubuntu Mono;fontSize=40;" parent="1" vertex="1">
<mxGeometry x="160" y="320" width="280" height="160" as="geometry" />
</mxCell>
<mxCell id="liv1zIGuVtiVySRaDl_v-3" value="B" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Ubuntu Mono;fontSize=40;" parent="1" vertex="1">
<mxGeometry x="520" y="80" width="280" height="160" as="geometry" />
</mxCell>
<mxCell id="liv1zIGuVtiVySRaDl_v-4" value="I" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Ubuntu Mono;fontSize=40;" parent="1" vertex="1">
<mxGeometry x="880" y="560" width="280" height="160" as="geometry" />
</mxCell>
<mxCell id="liv1zIGuVtiVySRaDl_v-5" value="F" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Ubuntu Mono;fontSize=40;" parent="1" vertex="1">
<mxGeometry x="880" y="320" width="280" height="160" as="geometry" />
</mxCell>
<mxCell id="liv1zIGuVtiVySRaDl_v-6" value="C" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Ubuntu Mono;fontSize=40;" parent="1" vertex="1">
<mxGeometry x="880" y="80" width="280" height="160" as="geometry" />
</mxCell>
<mxCell id="liv1zIGuVtiVySRaDl_v-7" value="G" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Ubuntu Mono;fontSize=40;" parent="1" vertex="1">
<mxGeometry x="160" y="560" width="280" height="160" as="geometry" />
</mxCell>
<mxCell id="liv1zIGuVtiVySRaDl_v-8" value="H" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Ubuntu Mono;fontSize=40;" parent="1" vertex="1">
<mxGeometry x="520" y="560" width="280" height="160" as="geometry" />
</mxCell>
<mxCell id="liv1zIGuVtiVySRaDl_v-9" value="E" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Ubuntu Mono;fontSize=40;" parent="1" vertex="1">
<mxGeometry x="520" y="320" width="280" height="160" as="geometry" />
</mxCell>
<mxCell id="liv1zIGuVtiVySRaDl_v-10" value="I_clk" style="shape=step;perimeter=stepPerimeter;whiteSpace=wrap;html=1;fixedSize=1;fillColor=#f0a30a;strokeColor=#BD7000;fontColor=#000000;fontFamily=Ubuntu Mono;fontSize=18;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="-40" y="120" width="160" height="40" as="geometry" />
</mxCell>
<mxCell id="liv1zIGuVtiVySRaDl_v-11" value="I_rst" style="shape=step;perimeter=stepPerimeter;whiteSpace=wrap;html=1;fixedSize=1;fillColor=#f0a30a;strokeColor=#BD7000;fontColor=#000000;fontFamily=Ubuntu Mono;fontSize=18;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="-40" y="200" width="160" height="40" as="geometry" />
</mxCell>
<mxCell id="liv1zIGuVtiVySRaDl_v-12" value="I_wave_sel" style="shape=step;perimeter=stepPerimeter;whiteSpace=wrap;html=1;fixedSize=1;fillColor=#f0a30a;strokeColor=#BD7000;fontColor=#000000;fontFamily=Ubuntu Mono;fontSize=18;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="-40" y="280" width="160" height="40" as="geometry" />
</mxCell>
<mxCell id="liv1zIGuVtiVySRaDl_v-14" value="O_wav" style="shape=step;perimeter=stepPerimeter;whiteSpace=wrap;html=1;fixedSize=1;fillColor=#f0a30a;strokeColor=#BD7000;fontColor=#000000;fontFamily=Ubuntu Mono;fontSize=18;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="1200" y="120" width="160" height="40" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
@echo off
rem delete all files from subfolders
for /d /r %%i in (*) do del /f /q %%i\*
rem delete all subfolders
for /d %%i in (*) do rd /S /Q %%i
rem unmark read only from all files
attrib -R .\* /S
rem mark read only those we wish to keep
attrib +R .\create_project.tcl
attrib +R .\cleanup.sh
attrib +R .\cleanup.cmd
attrib +R .\.gitignore
attrib +R .\_READ_ME_.txt
attrib +R .\tb_wave_generator_behav.wcfg
rem delete all non read-only
del /Q /A:-R .\*
rem unmark read-only
attrib -R .\*
# This script is useful for cleaning up the 'project'
# directory of a Digilent Vivado-project git repository
###
# Run the following command to change permissions of
# this 'cleanup' file if needed:
# chmod u+x cleanup.sh
###
# Remove directories/subdirectories
find . -mindepth 1 -type d -exec rm -rf {} +
# Remove any other files than:
find . -type f ! -name 'cleanup.sh' \
! -name 'cleanup.cmd' \
! -name 'create_project.tcl' \
! -name '.gitignore' \
! -name 'tb_wave_generator_behav.wcfg' \
-exec rm -rf {} +
# Run this script to create the Vivado project files in the WORKING DIRECTORY
# If ::create_path global variable is set, the project is created under that path instead of the working dir
if {[info exists ::create_path]} {
set dest_dir $::create_path
} else {
set dest_dir [pwd]
}
puts "INFO: Creating new project in $dest_dir"
# Set the reference directory for source file relative paths (by default the value is script directory path)
set proj_name "Synthe"
# Set the reference directory for source file relative paths (by default the value is script directory path)
set origin_dir ".."
# Set the directory path for the original project from where this script was exported
set orig_proj_dir "[file normalize "$origin_dir/proj"]"
set src_dir $origin_dir/src
set repo_dir $origin_dir/repo
# Set the board part number
set part_num "xc7a200tsbg484-1"
# Create project
create_project $proj_name $dest_dir
# Set the directory path for the new project
set proj_dir [get_property directory [current_project]]
# Set project properties
set obj [get_projects $proj_name]
set_property "default_lib" "xil_defaultlib" $obj
set_property "part" "$part_num" $obj
set_property "simulator_language" "Mixed" $obj
set_property "target_language" "VHDL" $obj
# Create 'sources_1' fileset (if not found)
if {[string equal [get_filesets -quiet sources_1] ""]} {
create_fileset -srcset sources_1
}
# Create 'constrs_1' fileset (if not found)
if {[string equal [get_filesets -quiet constrs_1] ""]} {
create_fileset -constrset constrs_1
}
# Set IP repository paths
set obj [get_filesets sources_1]
set_property "ip_repo_paths" "[file normalize $repo_dir]" $obj
# Add IPs
add_files -quiet [glob -nocomplain ../src/ip/*/*.xci]
# Add constraints
add_files -fileset constrs_1 -quiet $src_dir/constraints
# Add conventional sources
add_files -quiet $src_dir/hdl
# Set all VHDL files to 2008
set_property file_type {VHDL 2008} [get_files -filter {FILE_TYPE == VHDL}]
# Set testbenches as simulation only
set_property used_in_synthesis false [get_files $src_dir/hdl/tb_wave_generator.vhd]
set_property used_in_synthesis false [get_files $src_dir/hdl/tb_ADSR_module.vhd]
set_property used_in_synthesis false [get_files $src_dir/hdl/tb_module_B.vhd]
set_property used_in_synthesis false [get_files $src_dir/hdl/tb_module_C.vhd]
set_property used_in_synthesis false [get_files $src_dir/hdl/tb_module_D.vhd]
set_property used_in_synthesis false [get_files $src_dir/hdl/tb_module_E.vhd]
set_property used_in_synthesis false [get_files $src_dir/hdl/tb_module_F.vhd]
set_property used_in_synthesis false [get_files $src_dir/hdl/tb_module_G.vhd]
set_property used_in_synthesis false [get_files $src_dir/hdl/tb_module_H.vhd]
set_property used_in_synthesis false [get_files $src_dir/hdl/tb_module_I.vhd]
#Set TOP module as not used in simulation
set_property used_in_simulation false [get_files $src_dir/hdl/audioProc.v]
# Refresh IP Repositories
#update_ip_catalog
# Create 'synth_1' run (if not found)
if {[string equal [get_runs -quiet synth_1] ""]} {
create_run -name synth_1 -part $part_num -flow {Vivado Synthesis 2014} -strategy "Flow_PerfOptimized_High" -constrset constrs_1
} else {
set_property strategy "Flow_PerfOptimized_High" [get_runs synth_1]
set_property flow "Vivado Synthesis 2014" [get_runs synth_1]
}
set obj [get_runs synth_1]
set_property "part" "$part_num" $obj
set_property "steps.synth_design.args.fanout_limit" "400" $obj
set_property "steps.synth_design.args.fsm_extraction" "one_hot" $obj
set_property "steps.synth_design.args.keep_equivalent_registers" "1" $obj
set_property "steps.synth_design.args.resource_sharing" "off" $obj
set_property "steps.synth_design.args.no_lc" "1" $obj
set_property "steps.synth_design.args.shreg_min_size" "5" $obj
# set the current synth run
current_run -synthesis [get_runs synth_1]
# Create 'impl_1' run (if not found)
if {[string equal [get_runs -quiet impl_1] ""]} {
create_run -name impl_1 -part $part_num -flow {Vivado Implementation 2014} -strategy "Vivado Implementation Defaults" -constrset constrs_1 -parent_run synth_1
} else {
set_property strategy "Vivado Implementation Defaults" [get_runs impl_1]
set_property flow "Vivado Implementation 2014" [get_runs impl_1]
}
set obj [get_runs impl_1]
set_property "part" "$part_num" $obj
set_property "steps.write_bitstream.args.bin_file" "1" $obj
# set the current impl run
current_run -implementation [get_runs impl_1]
# set tb_wave_generator as default test bench
set_property top tb_module_B [get_filesets sim_1]
set_property top_lib xil_defaultlib [get_filesets sim_1]
update_compile_order -fileset sources_1
#puts "INFO: Project created:$proj_name"
# Comment the following section, if there is no block design
# Create block design
#source $origin_dir/src/bd/bt_gpio.tcl
# Generate the wrapper
#set design_name [get_bd_designs]
#make_wrapper -files [get_files $design_name.bd] -top -import
#set obj [get_filesets sources_1]
#set_property "top" "bt_gpio_top" $obj
#puts "INFO: Block design created: $design_name.bd"
<?xml version="1.0" encoding="UTF-8"?>
<wave_config>
<wave_state>
</wave_state>
<db_ref_list>
<db_ref path="tb_wave_generator_behav.wdb" id="1">
<top_modules>
<top_module name="tb_wave_generator" />
<top_module name="wave_package" />
</top_modules>
</db_ref>
</db_ref_list>
<zoom_setting>
<ZoomStartTime time="0.000000 us"></ZoomStartTime>
<ZoomEndTime time="16.000001 us"></ZoomEndTime>
<Cursor1Time time="16.000000 us"></Cursor1Time>
</zoom_setting>
<column_width_setting>
<NameColumnWidth column_width="276"></NameColumnWidth>
<ValueColumnWidth column_width="112"></ValueColumnWidth>
</column_width_setting>
<WVObjectSize size="29" />
<wvobject type="logic" fp_name="/tb_wave_generator/clk">
<obj_property name="ElementShortName">clk</obj_property>
<obj_property name="ObjectShortName">clk</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/tb_wave_generator/rst">
<obj_property name="ElementShortName">rst</obj_property>
<obj_property name="ObjectShortName">rst</obj_property>
</wvobject>
<wvobject type="array" fp_name="/tb_wave_generator/wave_sel">
<obj_property name="ElementShortName">wave_sel[1:0]</obj_property>
<obj_property name="ObjectShortName">wave_sel[1:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/tb_wave_generator/wav">
<obj_property name="ElementShortName">wav[7:0]</obj_property>
<obj_property name="ObjectShortName">wav[7:0]</obj_property>
</wvobject>
<wvobject type="other" fp_name="/tb_wave_generator/N">
<obj_property name="ElementShortName">N</obj_property>
<obj_property name="ObjectShortName">N</obj_property>
</wvobject>
<wvobject type="other" fp_name="/tb_wave_generator/f0">
<obj_property name="ElementShortName">f0</obj_property>
<obj_property name="ObjectShortName">f0</obj_property>
</wvobject>
<wvobject type="other" fp_name="/tb_wave_generator/fs">
<obj_property name="ElementShortName">fs</obj_property>
<obj_property name="ObjectShortName">fs</obj_property>
</wvobject>
<wvobject type="other" fp_name="/tb_wave_generator/clk_period">
<obj_property name="ElementShortName">clk_period</obj_property>
<obj_property name="ObjectShortName">clk_period</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/tb_wave_generator/uut/I_clk">
<obj_property name="ElementShortName">I_clk</obj_property>
<obj_property name="ObjectShortName">I_clk</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/tb_wave_generator/uut/I_rst">
<obj_property name="ElementShortName">I_rst</obj_property>
<obj_property name="ObjectShortName">I_rst</obj_property>
</wvobject>
<wvobject type="array" fp_name="/tb_wave_generator/uut/I_wave_sel">
<obj_property name="ElementShortName">I_wave_sel[1:0]</obj_property>
<obj_property name="ObjectShortName">I_wave_sel[1:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/tb_wave_generator/uut/O_wav">
<obj_property name="ElementShortName">O_wav[7:0]</obj_property>
<obj_property name="ObjectShortName">O_wav[7:0]</obj_property>
<obj_property name="Radix">SIGNEDDECRADIX</obj_property>
<obj_property name="WaveformStyle">STYLE_ANALOG</obj_property>
<obj_property name="CellHeight">400</obj_property>
<obj_property name="AnalogYRangeType">ANALOG_YRANGETYPE_AUTO</obj_property>
<obj_property name="AnalogYRangeMin">0.000000</obj_property>
<obj_property name="AnalogYRRangeMax">0.000000</obj_property>
<obj_property name="AnalogInterpolation">ANALOG_INTERPOLATION_HOLD</obj_property>
<obj_property name="AnalogOffscale">ANALOG_OFFSCALE_HIDE</obj_property>
<obj_property name="AnalogHorizLine">0.000000</obj_property>
</wvobject>
<wvobject type="array" fp_name="/tb_wave_generator/uut/S_addr">
<obj_property name="ElementShortName">S_addr[5:0]</obj_property>
<obj_property name="ObjectShortName">S_addr[5:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/tb_wave_generator/uut/S_sine_out_lut">
<obj_property name="ElementShortName">S_sine_out_lut[7:0]</obj_property>
<obj_property name="ObjectShortName">S_sine_out_lut[7:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/tb_wave_generator/uut/S_square">
<obj_property name="ElementShortName">S_square[7:0]</obj_property>
<obj_property name="ObjectShortName">S_square[7:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/tb_wave_generator/uut/S_triangle_out_lut">
<obj_property name="ElementShortName">S_triangle_out_lut[7:0]</obj_property>
<obj_property name="ObjectShortName">S_triangle_out_lut[7:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/tb_wave_generator/uut/S_saw_tooth_out_lut">
<obj_property name="ElementShortName">S_saw_tooth_out_lut[7:0]</obj_property>
<obj_property name="ObjectShortName">S_saw_tooth_out_lut[7:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/tb_wave_generator/uut/S_opposite_wave_sample">
<obj_property name="ElementShortName">S_opposite_wave_sample[7:0]</obj_property>
<obj_property name="ObjectShortName">S_opposite_wave_sample[7:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/tb_wave_generator/uut/S_wave_value">
<obj_property name="ElementShortName">S_wave_value[7:0]</obj_property>
<obj_property name="ObjectShortName">S_wave_value[7:0]</obj_property>
</wvobject>
<wvobject type="array" fp_name="/tb_wave_generator/uut/S_wave_sample">
<obj_property name="ElementShortName">S_wave_sample[7:0]</obj_property>
<obj_property name="ObjectShortName">S_wave_sample[7:0]</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/tb_wave_generator/uut/S_last">
<obj_property name="ElementShortName">S_last</obj_property>
<obj_property name="ObjectShortName">S_last</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/tb_wave_generator/uut/S_middle">
<obj_property name="ElementShortName">S_middle</obj_property>
<obj_property name="ObjectShortName">S_middle</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/tb_wave_generator/uut/S_u_d">
<obj_property name="ElementShortName">S_u_d</obj_property>
<obj_property name="ObjectShortName">S_u_d</obj_property>
</wvobject>
<wvobject type="logic" fp_name="/tb_wave_generator/uut/S_sign_sel">
<obj_property name="ElementShortName">S_sign_sel</obj_property>
<obj_property name="ObjectShortName">S_sign_sel</obj_property>
</wvobject>
<wvobject type="other" fp_name="/tb_wave_generator/uut/G_N">
<obj_property name="ElementShortName">G_N</obj_property>
<obj_property name="ObjectShortName">G_N</obj_property>
</wvobject>
<wvobject type="other" fp_name="/tb_wave_generator/uut/G_f0">
<obj_property name="ElementShortName">G_f0</obj_property>
<obj_property name="ObjectShortName">G_f0</obj_property>
</wvobject>
<wvobject type="other" fp_name="/tb_wave_generator/uut/G_fs">
<obj_property name="ElementShortName">G_fs</obj_property>
<obj_property name="ObjectShortName">G_fs</obj_property>
</wvobject>
<wvobject type="other" fp_name="/tb_wave_generator/uut/C_addr_half_w">
<obj_property name="ElementShortName">C_addr_half_w</obj_property>
<obj_property name="ObjectShortName">C_addr_half_w</obj_property>
</wvobject>
<wvobject type="other" fp_name="/tb_wave_generator/uut/A_inst/state_reg">
<obj_property name="ElementShortName">state_reg</obj_property>
<obj_property name="ObjectShortName">state_reg</obj_property>
</wvobject>
</wave_config>
This diff is collapsed.
-- Attack (0-100%) - Decay (100-70%) -- Sustain (70%) -- Release (70-0%) (ADSR) module
-- made up of
-- a finite-state machine to control the ADSR sequence
-- a time counter to measure time
-- a gain that varies linearily and will be multiplied by the tone
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.MATH_REAL.ALL;
entity ADSR_module is
generic (
N: natural := 8; -- number of bits in the output signal
N_t: natural := 16; --number of bits to count the time
A_t: real := 20.0; -- length of the attack in ms
D_t: real := 5.0; -- length of the decay in ms
R_t: real := 700.0; -- length of the release in ms
fs: real := 48000.0 -- sampling frequency
);
port (
clk: in std_logic;
rst: in std_logic;
key: in std_logic ; -- key input
gain: out std_logic_vector(N-1 downto 0) -- unsigned value
);
end ADSR_module;
architecture archi of ADSR_module is
-- constants for the time calculations
constant A_cycles: unsigned(N_t-1 downto 0) := to_unsigned(integer(A_t * fs / 1000.0), N_t);
constant D_cycles: unsigned(N_t-1 downto 0) := to_unsigned(integer(D_t * fs / 1000.0), N_t);
constant R_cycles: unsigned(N_t-1 downto 0) := to_unsigned(integer(R_t * fs / 1000.0), N_t);
constant A_coeff : unsigned(N_t-1 downto 0) := to_unsigned(integer(real(2**N-1)/(A_t * fs / 1000.0)*real(2**N_t-1)), N_t);
constant D_coeff : unsigned(N_t-1 downto 0) := to_unsigned(integer(0.3*real(2**N-1)/(D_t * fs / 1000.0)*real(2**N_t-1)), N_t);
constant R_coeff : unsigned(N_t-1 downto 0) := to_unsigned(integer(real(2**N-1)/(R_t * fs / 1000.0)*real(2**N_t-1)), N_t);
-- states of the FSM
-- key_off, attack, decay, sustain, release
type state_type is (key_off, attack, decay, sustain, release_st );
signal state: state_type := key_off;
signal counter: unsigned(N_t-1 downto 0) := (others =>'0'); -- time counter
signal gain_u : signed(2*N_t downto 0) := (others =>'0');
begin
-- When the key is pressed, the cycles begins
process(clk, rst)
-- counter for the time
begin
if rst = '1' then
state <= key_off;
gain_u <= (others => '0');
counter <= (others =>'0');
elsif rising_edge(clk) then
case state is
when key_off =>
if key = '1' then
state <= attack;
counter <= (others =>'0');
end if;
when attack =>
if counter < A_cycles then
gain_u <= signed('0'&(counter*A_coeff));
counter <= counter + 1;
else
state <= decay;
counter <= (others =>'0');
end if;
when decay =>
if counter < D_cycles then
gain_U <= signed('0'&(A_cycles*A_coeff)) - signed('0'&(counter * D_coeff));
counter <= counter + 1;
else
state <= sustain;
end if;
when sustain =>
if key = '0' then
state <= release_st;
counter <= (others =>'0');
end if;
when release_st =>
if counter < R_cycles then
gain_u <= signed('0'&(A_cycles*A_coeff)) - signed('0'&(D_cycles * D_coeff)) - signed('0'&(R_cycles*counter));
counter <= counter + 1;
else
state <= key_off;
gain_u <= (others => '0');
end if;
end case;
end if;
end process;
gain <= std_logic_vector(gain_u(N_t+N-1 downto N_t)) when gain_u>0 else (others => '0');
end archi ;
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: Digilent Inc.
// Engineer: Thomas Kappenman
//
// Create Date: 03/03/2015 09:33:36 PM
// Design Name:
// Module Name: PS2Receiver
// Project Name: Nexys4DDR Keyboard Demo
// Target Devices: Nexys4DDR
// Tool Versions:
// Description: PS2 Receiver module used to shift in keycodes from a keyboard plugged into the PS2 port
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module PS2Receiver(
input clk,
input kclk,
input kdata,
output reg [15:0] keycode=0,
output reg oflag
);
wire kclkf, kdataf;
reg [7:0]datacur=0;
reg [7:0]dataprev=0;
reg [3:0]cnt=0;
reg flag=0;
debouncer #(
.COUNT_MAX(19),
.COUNT_WIDTH(5)
) db_clk(
.clk(clk),
.I(kclk),
.O(kclkf)
);
debouncer #(
.COUNT_MAX(19),
.COUNT_WIDTH(5)
) db_data(
.clk(clk),
.I(kdata),
.O(kdataf)
);
always@(negedge(kclkf))begin
case(cnt)
0:;//Start bit
1:datacur[0]<=kdataf;
2:datacur[1]<=kdataf;
3:datacur[2]<=kdataf;
4:datacur[3]<=kdataf;
5:datacur[4]<=kdataf;
6:datacur[5]<=kdataf;
7:datacur[6]<=kdataf;
8:datacur[7]<=kdataf;
9:flag<=1'b1;
10:flag<=1'b0;
endcase
if(cnt<=9) cnt<=cnt+1;
else if(cnt==10) cnt<=0;
end
reg pflag;
always@(posedge clk) begin
if (flag == 1'b1 && pflag == 1'b0) begin
keycode <= {dataprev, datacur};
oflag <= 1'b1;
dataprev <= datacur;
end else
oflag <= 'b0;
pflag <= flag;
end
endmodule
----------------------------------------------------------------------------------
-- Company: Digilent Ro
-- Engineer: Elod Gyorgy
--
-- Create Date: 14:55:31 04/07/2011
-- Design Name:
-- Module Name: TWIUtils - Package
-- Project Name: TWI Master Controller Reference Design
-- Target Devices:
-- Tool versions:
-- Description: This package provides enumeration types for TWI (Two-Wire
-- Interface) bus status and error conditions.
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
package TWIUtils is
type busState_type is (busUnknown, busBusy, busFree);
type error_type is (errArb, errNAck);
end TWIUtils;
package body TWIUtils is
end TWIUtils;
----------------------------------------------------------------------------------
-- Company: Digilent Ro
-- Engineer: Elod Gyorgy
--
-- Create Date: 14:55:31 04/07/2011
-- Design Name:
-- Module Name: TWICtl - Behavioral
-- Project Name: TWI Master Controller Reference Design
-- Target Devices:
-- Tool versions:
-- Description: TWICtl is a reusabled Master Controller implementation of the
-- TWI protocol. It uses 7-bit addressing and was tested in STANDARD I2C mode.
-- FAST mode should also be theoretically possible, although it has not been
-- tested. It adheres to arbitration rules, thus supporting multi-master TWI
-- buses. Slave-wait is also supported.
--
--
-- Dependencies: digilent.TWIUtils package - TWICtl.vhd
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.math_real.all;
library digilent;
--use digilent.TWIUtils.ALL;
entity TWICtl is
----------------------------------------------------------------------------------
-- Title : Mode of operation
-- Description: The controller can be instructed to initiate/continue/stop a
-- data transfer using the strobe (STB_I, MSG_I) signals. Data flow management is
-- provided by the done (DONE_O) and error (ERR_O, ERRTYPE_O) signals. Output
-- signals are synchronous to CLK and input signals must also be synchronous to
-- CLK. Signals are active-high.
-- Fast-track instructions (single byte transfer):
-- -put the TWI address on A_I
-- -if data is written put it on D_I
-- -assert STB_I
-- -when DONE_O pulse arrives, read data is present on D_O, if any
-- -repeat, or deassert STB_I
-- Detailed data transfer flow:
-- -when DONE_O is low, the controller is ready to accept commands
-- -data transfer can be initiated by putting a TWI slave address on the A_I
-- bus and providing a strobe (STB_I)
-- -the direction of data transfer (read/write) is determined by the LSB of the
-- address (0-write, 1-read)
-- -in case of a 'write' the data byte should also be present on the D_I bus
-- prior to the arrival of the strobe (STB_I)
-- -once the data byte gets read/written, DONE_I pulses high for one CLK cycle
-- -in case of an error, ERR_O will pulse high together with DONE_I; ERR_O low
-- together with DONE_I high indicates success
-- -after DONE_I pulses high there is a 1/4 TWI period time frame when the next
-- strobe can be sent; this is useful, when multiple bytes are sent/received
-- in a single transfer packet; for ex. for write transfers, a new byte can
-- be put on the D_I and STB_I provided;
-- -if no new strobe is provided, the transfer will end
-- -if a new strobe is provided, but the address changed, the current transfer
-- will end and a new will begin
-- -starting a new transfer can be forced with the MSG_I pin; if asserted with
-- a strobe, the data byte will be written/read in a new packet; the advantage
-- of this is relevant only in multi-master buses: rather than waiting for the
-- current transfer to end and the bus to be released, a new transfer can be
-- initiated without giving up the control over the bus
----------------------------------------------------------------------------------
generic (CLOCKFREQ : natural := 50); -- input CLK frequency in MHz
port (
MSG_I : in STD_LOGIC; --new message
STB_I : in STD_LOGIC; --strobe
A_I : in STD_LOGIC_VECTOR (7 downto 0); --address input bus
D_I : in STD_LOGIC_VECTOR (7 downto 0); --data input bus
D_O : out STD_LOGIC_VECTOR (7 downto 0); --data output bus
DONE_O : out STD_LOGIC; --done status signal
ERR_O : out STD_LOGIC; --error status
CLK : in std_logic;
SRST : in std_logic;
----------------------------------------------------------------------------------
-- TWI bus signals
----------------------------------------------------------------------------------
SDA : inout std_logic; --TWI SDA
SCL : inout std_logic --TWI SCL
);
end TWICtl;
architecture Behavioral of TWICtl is
attribute fsm_encoding: string;
constant FSCL : natural := 400_000; --in Hz SCL clock frequency
constant TIMEOUT : natural := 10; --in ms TWI timeout for slave wait period
constant TSCL_CYCLES : natural :=
natural(ceil(real(CLOCKFREQ*1_000_000/FSCL)));
constant TIMEOUT_CYCLES : natural :=
natural(ceil(real(CLOCKFREQ*TIMEOUT*1_000)));
type state_type is (stIdle, stStart, stRead, stWrite, stError, stStop,
stSAck, stMAck, stMNAckStop, stMNAckStart, stStopError);
type busState_type is (busUnknown, busFree, busBusy);
type error_type is (errNAck, errArb);
signal state, nstate : state_type;
attribute fsm_encoding of state: signal is "gray";
signal dSda, ddSda, dScl, ddScl : std_logic;
signal fStart, fStop : std_logic;
signal busState : busState_type := busUnknown;
signal errTypeR, errType : error_type;
signal busFreeCnt, sclCnt : natural range TSCL_CYCLES downto 0 := TSCL_CYCLES;
signal timeOutCnt : natural range TIMEOUT_CYCLES downto 0 := TIMEOUT_CYCLES;
signal slaveWait, arbLost : std_logic;
signal dataByte, loadByte, currAddr : std_logic_vector(7 downto 0); --shift register and parallel load
signal rSda, rScl : std_logic := '1';
signal subState : std_logic_vector(1 downto 0) := "00";
signal latchData, latchAddr, iDone, iErr, iSda, iScl, shiftBit, dataBitOut, rwBit, addrNData : std_logic;
signal bitCount : natural range 0 to 7 := 7;
signal int_Rst : std_logic := '0';
begin
----------------------------------------------------------------------------------
--Bus State detection
----------------------------------------------------------------------------------
SYNC_FFS: process(CLK)
begin
if Rising_Edge(CLK) then
dSda <= SDA;
ddSda <= dSda;
dScl <= SCL;
end if;
end process;
fStart <= dSCL and not dSda and ddSda; --if SCL high while SDA falling, start condition
fStop <= dSCL and dSda and not ddSda; --if SCL high while SDA rising, stop condition
TWISTATE: process(CLK)
begin
if Rising_Edge(CLK) then
if (int_Rst = '1') then
busState <= busUnknown;
elsif (fStart = '1') then --If START condition detected, bus is busy
busState <= busBusy;
elsif (busFreeCnt = 0) then --We counted down tBUF, so it must be free
busState <= busFree;
end if;
end if;
end process;
TBUF_CNT: process(CLK)
begin
if Rising_Edge(CLK) then
if (dSCL = '0' or dSDA = '0' or int_Rst = '1') then
busFreeCnt <= TSCL_CYCLES;
elsif (dSCL = '1' and dSDA = '1') then
busFreeCnt <= busFreeCnt - 1; --counting down 1 SCL period on free bus
end if;
end if;
end process;
----------------------------------------------------------------------------------
--Slave devices can insert wait states by keeping SCL low
----------------------------------------------------------------------------------
slaveWait <= '1' when (dSCL = '0' and rScl = '1') else
'0';
----------------------------------------------------------------------------------
--If the SDA line does not correspond to the transmitted data while the SCL line
--is at the HIGH level the master lost an arbitration to another master.
----------------------------------------------------------------------------------
arbLost <= '1' when (dSCL = '1' and dSDA = '0' and rSda = '1') else
'0';
----------------------------------------------------------------------------------
-- Internal reset signal
----------------------------------------------------------------------------------
RST_PROC: process (CLK)
begin
if Rising_Edge(CLK) then
if (state = stIdle and SRST = '0') then
int_Rst <= '0';
elsif (SRST = '1') then
int_Rst <= '1';
end if;
end if;
end process;
----------------------------------------------------------------------------------
-- SCL period counter
----------------------------------------------------------------------------------
SCL_CNT: process (CLK)
begin
if Rising_Edge(CLK) then
if (sclCnt = 0 or state = stIdle) then
sclCnt <= TSCL_CYCLES/4;
elsif (slaveWait = '0') then -- clock synchronization with other masters
sclCnt <= sclCnt - 1;
end if;
end if;
end process;
----------------------------------------------------------------------------------
-- SCL period counter
----------------------------------------------------------------------------------
TIMEOUT_CNT: process (CLK)
begin
if Rising_Edge(CLK) then
if (timeOutCnt = 0 or slaveWait = '0') then
timeOutCnt <= TIMEOUT_CYCLES;
elsif (slaveWait = '1') then -- count timeout on wait period inserted by slave
timeOutCnt <= timeOutCnt - 1;
end if;
end if;
end process;
----------------------------------------------------------------------------------
-- Title: Data byte shift register
-- Description: Stores the byte to be written or the byte read depending on the
-- transfer direction.
----------------------------------------------------------------------------------
DATABYTE_SHREG: process (CLK)
begin
if Rising_Edge(CLK) then
if ((latchData = '1' or latchAddr = '1') and sclCnt = 0) then
dataByte <= loadByte; --latch address/data
bitCount <= 7;
--set flag so that we now what is the byte we are sending
if (latchData = '1') then
addrNData <= '0';
else
addrNData <= '1';
end if;
elsif (shiftBit = '1' and sclCnt = 0) then
dataByte <= dataByte(dataByte'high-1 downto 0) & dSDA;
bitCount <= bitCount - 1;
end if;
end if;
end process;
loadByte <= A_I when latchAddr = '1' else
D_I;
dataBitOut <= dataByte(dataByte'high);
D_O <= dataByte;
----------------------------------------------------------------------------------
-- Title: Current address register
-- Description: Stores the TWI slave address
----------------------------------------------------------------------------------
CURRADDR_REG: process (CLK)
begin
if Rising_Edge(CLK) then
if (latchAddr = '1') then
currAddr <= A_I; --latch address/data
end if;
end if;
end process;
rwBit <= currAddr(0);
----------------------------------------------------------------------------------
-- Title: Substate counter
-- Description: Divides each state into 4, to respect the setup and hold times of
-- the TWI bus.
----------------------------------------------------------------------------------
SUBSTATE_CNT: process (CLK)
begin
if Rising_Edge(CLK) then
if (state = stIdle) then
subState <= "00";
elsif (sclCnt = 0) then
subState <= subState + 1;
end if;
end if;
end process;
SYNC_PROC: process (CLK)
begin
if Rising_Edge(CLK) then
state <= nstate;
rSda <= iSda;
rScl <= iScl;
DONE_O <= iDone;
ERR_O <= iErr;
errTypeR <= errType;
end if;
end process;
OUTPUT_DECODE: process (nstate, subState, state, errTypeR, dataByte(0),
sclCnt, bitCount, rSda, rScl, dataBitOut, arbLost, dSda, addrNData)
begin
iSda <= rSda; --no change by default
iScl <= rScl;
iDone <= '0';
iErr <= '0';
errType <= errTypeR; --keep error type
shiftBit <= '0';
latchAddr <= '0';
latchData <= '0';
if (state = stStart) then
case (subState) is
when "00" =>
iSda <= '1';
--keep SCL
when "01" =>
iSda <= '1';
iScl <= '1';
when "10" =>
iSda <= '0';
iScl <= '1';
when "11" =>
iSda <= '0';
iScl <= '0';
when others =>
end case;
end if;
if (state = stStop or state = stStopError) then
case (subState) is
when "00" =>
iSda <= '0';
--keep SCL
when "01" =>
iSda <= '0';
iScl <= '1';
when "10" =>
iSda <= '1';
iScl <= '1';
when others =>
end case;
end if;
if (state = stRead or state = stSAck) then
case (subState) is
when "00" =>
iSda <= '1'; --this will be 'Z' on SDA
--keep SCL
when "01" =>
--keep SDA
iScl <= '1';
when "10" =>
--keep SDA
iScl <= '1';
when "11" =>
--keep SDA
iScl <= '0';
when others =>
end case;
end if;
if (state = stWrite) then
case (subState) is
when "00" =>
iSda <= dataBitOut;
--keep SCL
when "01" =>
--keep SDA
iScl <= '1';
when "10" =>
--keep SDA
iScl <= '1';
when "11" =>
--keep SDA
iScl <= '0';
when others =>
end case;
end if;
if (state = stMAck) then
case (subState) is
when "00" =>
iSda <= '0'; -- acknowledge by writing 0
--keep SCL
when "01" =>
--keep SDA
iScl <= '1';
when "10" =>
--keep SDA
iScl <= '1';
when "11" =>
--keep SDA
iScl <= '0';
when others =>
end case;
end if;
if (state = stMNAckStop or state = stMNAckStart) then
case (subState) is
when "00" =>
iSda <= '1'; -- not acknowledge by writing 1
--keep SCL
when "01" =>
--keep SDA
iScl <= '1';
when "10" =>
--keep SDA
iScl <= '1';
when "11" =>
--keep SDA
iScl <= '0';
when others =>
end case;
end if;
if (state = stSAck and sclCnt = 0 and subState = "01") then
if (dSda = '1') then
iDone <= '1';
iErr <= '1'; --not acknowledged
errType <= errNAck;
elsif (addrNData = '0') then
--we are done only when the data is sent too after the address
iDone <= '1';
end if;
end if;
if (state = stRead and subState = "01" and sclCnt = 0 and bitCount = 0) then
iDone <= '1'; --read done
end if;
if (state = stWrite and arbLost = '1') then
iDone <= '1'; --write done
iErr <= '1'; --we lost the arbitration
errType <= errArb;
end if;
if ((state = stWrite and sclCnt = 0 and subState = "11") or --shift at end of bit
((state = stSAck or state = stRead) and subState = "01")) then --read in middle of bit
shiftBit <= '1';
end if;
if (state = stStart) then
latchAddr <= '1';
end if;
if (state = stSAck and subState = "11") then --get the data byte for the next write
latchData <= '1';
end if;
end process;
NEXT_STATE_DECODE: process (state, busState, slaveWait, arbLost, STB_I, MSG_I,
SRST, subState, bitCount, int_Rst, dataByte, A_I, currAddr, rwBit, sclCnt, addrNData)
begin
nstate <= state; --default is to stay in current state
case (state) is
when stIdle =>
if (STB_I = '1' and busState = busFree and SRST = '0') then
nstate <= stStart;
end if;
when stStart =>
if (subState = "11" and sclCnt = 0) then
nstate <= stWrite;
end if;
when stWrite =>
if (arbLost = '1') then
nstate <= stIdle;
elsif (subState = "11" and sclCnt = 0 and bitCount = 0) then
nstate <= stSAck;
end if;
when stSAck =>
if (subState = "11" and sclCnt = 0) then
if (int_Rst = '1' or dataByte(0) = '1') then
nstate <= stStop;
else
if (addrNData = '1') then --if we have just sent the address, tx/rx the data too
if (rwBit = '1') then
nstate <= stRead;
else
nstate <= stWrite;
end if;
elsif (STB_I = '1') then
if (MSG_I = '1' or currAddr /= A_I) then
nstate <= stStart;
else
if (rwBit = '1') then
nstate <= stRead;
else
nstate <= stWrite;
end if;
end if;
else
nstate <= stStop;
end if;
end if;
end if;
when stStop =>
if (subState = "10" and sclCnt = 0) then
nstate <= stIdle;
end if;
when stRead =>
if (subState = "11" and sclCnt = 0 and bitCount = 7) then --bitCount will underflow
if (int_Rst = '0' and STB_I = '1') then
if (MSG_I = '1' or currAddr /= A_I) then
nstate <= stMNAckStart;
else
nstate <= stMAck;
end if;
else
nstate <= stMNAckStop;
end if;
end if;
when stMAck =>
if (subState = "11" and sclCnt = 0) then
nstate <= stRead;
end if;
when stMNAckStart =>
if (arbLost = '1') then
nstate <= stIdle; -- arbitration lost, back off, no error because we got all the data
elsif (subState = "11" and sclCnt = 0) then
nstate <= stStart;
end if;
when stMNAckStop =>
if (arbLost = '1') then
nstate <= stIdle; -- arbitration lost, back off, no error because we got all the data
elsif (subState = "11" and sclCnt = 0) then
nstate <= stStop;
end if;
when others =>
nstate <= stIdle;
end case;
end process;
----------------------------------------------------------------------------------
-- Open-drain outputs for bi-directional SDA and SCL
----------------------------------------------------------------------------------
SDA <= 'Z' when rSDA = '1' else
'0';
SCL <= 'Z' when rSCL = '1' else
'0';
end Behavioral;
\ No newline at end of file
// -*- Mode: Verilog -*-
// Filename : audioProc.v
// Description : Audio processing project for IMTA A1S2 Labs in digital electronics, based on looper project by Digilent Inc.
// Author : Matthieu Arzel
// Created On : Fri Feb 8 11:16:35 2019
// Last Modified By: Matthieu Arzel
// Last Modified On: Fri Feb 8 11:16:35 2019
// Update Count : 0
// Status : Unknown, Use with caution!
`timescale 1ns / 1ps
module audioProc(
input BTNL,
input BTNR,
input BTND,
input BTNC,
input BTNU,
// input JA1,
// input JA2,
// input JA3,
// input JA4,
input CLK100MHZ,
input rstn,
input sw0,
input sw1,
input sw2,
input sw3,
input sw4,
input sw5,
input sw6,
input sw7,
input PS2Data,
input PS2Clk,
output led0,
output led1,
output led2,
output led3,
output led4,
output led5,
output led6,
output led7,
inout scl,
inout sda,
output ac_mclk,
input ac_adc_sdata,
output ac_dac_sdata,
output ac_bclk,
output ac_lrclk
);
wire rst;
assign rst = ~rstn;
wire clk50;
parameter tenhz = 10000000;
wire [4:0] buttons_i;
assign buttons_i = {BTNU, BTNR, BTNC, BTND, BTNL};
reg [21:0] max_block=0;
wire set_max;
wire reset_max;
wire [4:0] buttons_db;//Debounced buttons
wire data_flag;
reg [23:0] sound_dataL;
reg [23:0] sound_dataR;
wire data_ready;
wire mix_data;
wire [21:0] block48KHz;
wire clk_out_100MHZ;
wire clk_out_200MHZ;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//// clk_wiz instantiation and wiring
//////////////////////////////////////////////////////////////////////////////////////////////////////////
clk_wiz_0 clk_1
(
// Clock in ports
.clk_in1(CLK100MHZ),
// Clock out ports
.clk_out1(clk_out_100MHZ),
.clk_out2(clk_out_200MHZ),
.clk_out3(ac_mclk),
.clk_out4(clk50),
// Status and control signals
.locked()
);
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//// Audio Initialization via TWI
//////////////////////////////////////////////////////////////////////////////////////////////////////////
audio_init initialize_audio
(
.clk(clk50),
.rst(rst),
.sda(sda),
.scl(scl)
);
wire [23:0] mixL;
wire [23:0] mixR;
debounce dbuttons(
.clock(clk_out_100MHZ),
.reset(rst),
.button(buttons_i),
.out(buttons_db)
);
/////////////
/// USB keyboard
/////////////////
reg [15:0] keycodev=0;
wire [15:0] keycode;
reg [ 2:0] bcount=0;
wire flag;
reg cn=0;
wire key_A;
reg start;
PS2Receiver uut (
.clk(clk50),
.kclk(PS2Clk),
.kdata(PS2Data),
.keycode(keycode),
.oflag(flag)
);
always@(keycode, keycodev)
if (keycode[7:0] == 8'hf0) begin
cn <= 1'b0;
bcount <= 3'd0;
end else if (keycode[15:8] == 8'hf0) begin
cn <= keycode != keycodev;
bcount <= 3'd5;
end else begin
cn <= keycode[7:0] != keycodev[7:0] || keycodev[15:8] == 8'hf0;
bcount <= 3'd2;
end
always@(posedge clk_out_100MHZ)
if (flag == 1'b1 && cn == 1'b1) begin
start <= 1'b1;
keycodev <= keycode;
end else
start <= 1'b0;
//assign key_A at 1 when keycodev is equal to 1C (key 'A')
// assign key_A = ((keycodev[7:0] == 8'h1C) && (keycodev[15:8] != 8'hf0)) ? 1'b1 : 1'b0;
// always@(keycodev)
// key_A
////////////////////////////////////////////////////////////////////////////////////////////////////////
// Audio input and output
////////////////////////////////////////////////////////////////////////////////////////////////////////
wire [23:0] in_audioL;
wire [23:0] in_audioR;
wire [23:0] out_audioL;
wire [23:0] out_audioR;
i2s_ctl audio_inout(
.CLK_I(clk_out_100MHZ), //Sys clk
.RST_I(rst), //Sys rst
.EN_TX_I(1), // Transmit Enable (push sound data into chip)
.EN_RX_I(1), //Receive enable (pull sound data out of chip)
.FS_I(4'b0101), //Sampling rate selector
.MM_I(0), //Audio controller Master mode select
.D_L_I(mixL), //Left channel data input from mix (mixed audio output)
.D_R_I(mixR), //Right channel data input from mix
.D_L_O(in_audioL), // Left channel data (input from mic input)
.D_R_O(in_audioR), // Right channel data (input from mic input)
.BCLK_O(ac_bclk), // serial CLK
.LRCLK_O(ac_lrclk), // channel CLK
.SDATA_O(ac_dac_sdata), // Output serial data
.SDATA_I(ac_adc_sdata) // Input serial data
);
reg lrclkD1=0;
reg lrclkD2=0;
always@(posedge(clk_out_100MHZ))begin
lrclkD1<=ac_lrclk;
lrclkD2<=lrclkD1;
end
reg pulse48kHz;
wire lrclkrise;
assign lrclkrise = lrclkD1 & ~lrclkD2;
reg[3:0] lrclkcnt=0;
always@(posedge(clk_out_100MHZ))begin
if (lrclkcnt==15)begin
pulse48kHz<=1;
lrclkcnt<=0;
end
else
pulse48kHz<=0;
if (lrclkrise)lrclkcnt<=lrclkcnt+1;
end
//////////////////////////////
// Synthe
// Marz
/////////////////////////////
wire [23:0] inputLeftSample, inputRightSample,outputLeftSample,outputRightSample;
wire [4:0] configSw;
wire [1:0] waveSw;
assign inputLeftSample = in_audioL;
assign inputRightSample = in_audioR;
assign waveSw[0]=sw0;
assign waveSw[1]=sw1;
assign configSw[0]=sw2;
assign configSw[1]=sw3;
assign configSw[2]=sw4;
assign configSw[3]=sw5;
assign configSw[4]=sw6;
assign led0=sw0;
assign led1=sw1;
assign led2=sw2;
assign led3=sw3;
assign led4=sw4;
assign led5=sw5;
assign led6=sw6;
assign led7=sw7;
synthesizer synthe
(
pulse48kHz, // : in std_logic;
rst,// : in std_logic;
waveSw[1:0],
configSw[3:0],
keycodev, //buttons_db[0],
outputLeftSample
// : in std_logic; -- signal de validation de din a la frequence des echantillons audio
);
assign mixL = buttons_db[2] ? in_audioL : outputLeftSample;
assign mixR = buttons_db[2] ? in_audioR : outputLeftSample;
////////////////////////////////////////////////////////////////////////////////////////////////////////
//// Data in latch
////////////////////////////////////////////////////////////////////////////////////////////////////////
//Latch audio data input when data_flag goes high
always@(posedge(clk_out_100MHZ))begin
if (data_flag==1)begin
sound_dataL<=in_audioL;
sound_dataR<=in_audioR;
end
end
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 07/08/2015 06:07:53 PM
// Design Name:
// Module Name: audio_init
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module audio_init(
input clk,
input rst,
inout sda,
inout scl
);
parameter stRegAddr1 = 4'b0000;
parameter stRegAddr2 = 4'b0001;
parameter stData1 = 4'b0010;
parameter stData2 = 4'b0011;
parameter stError = 4'b0100;
parameter stDone = 4'b0101;
parameter stIdle = 4'b0110;
parameter stDelay = 4'b0111;
parameter stPLLsecond = 4'b1111;
parameter INIT_VECTORS = 35;
parameter IRD = 1'b1;//init read
parameter IWR = 1'b0;//init write
parameter delay = 1000*24;
reg [3:0] state=stIdle;//State machine
reg [32:0] initWord;
reg initFbWe;
reg initEn;
reg [6:0]initA=0;
always @(posedge(clk))begin
case (initA)
0: initWord <= {IWR,31'h40150100};
1: initWord <= {IWR,31'h40160000};
2: initWord <= {IWR,31'h40170000};
3: initWord <= {IWR,31'h40F80000};
4: initWord <= {IWR,31'h40191300};
5: initWord <= {IWR,31'h402A0300};
6: initWord <= {IWR,31'h40290300};
7: initWord <= {IWR,31'h40F20100};
8: initWord <= {IWR,31'h40F97F00};
9: initWord <= {IWR,31'h40FA0300};
10: initWord <= {IWR,31'h40200300};
11: initWord <= {IWR,31'h40220100};
12: initWord <= {IWR,31'h40210900};
13: initWord <= {IWR,31'h4025E600};
14: initWord <= {IWR,31'h4026E600};
15: initWord <= {IWR,31'h40270300};
16: initWord <= {IWR,31'h40100100};
17: initWord <= {IWR,31'h40280000};
18: initWord <= {IWR,31'h4023E600};
19: initWord <= {IWR,31'h4024E600};
20: initWord <= {IWR,31'h400A0100};
21: initWord <= {IWR,31'h400B0500};
22: initWord <= {IWR,31'h400C0100};
23: initWord <= {IWR,31'h400D0500};
24: initWord <= {IWR,31'h400E0300};
25: initWord <= {IWR,31'h400F0300};
26: initWord <= {IWR,31'h401C2100};
27: initWord <= {IWR,31'h401D0000};
28: initWord <= {IWR,31'h401E4100};
29: initWord <= {IWR,31'h401F0000};
30: initWord <= {IWR,31'h40F30100};
31: initWord <= {IWR,31'h40F40000};
32: initWord <= {IWR,31'h40000F00};
33: initWord <= {IWR,31'h4002007D};//This sends the address of the PLL reg and the first config bits
34: initWord <= {IWR,31'h000C2101}; //These are the config bytes for the PLL reg
endcase
end
reg msg;//New message signal
reg stb;//Strobe signal
reg [7:0] data_i;//Data into TWI controller
wire [7:0] data_o;//Data out of TWI controller
wire done;
wire error;
wire errortype;
wire [7:0] twiAddr;//Address of device on TWI
reg [7:0] regData1;
reg delayEn=0;
integer delaycnt;
assign twiAddr[7:1] = 7'b0111011;
assign twiAddr[0] = 0;
TWICtl twi_controller(
.MSG_I(msg),
.STB_I(stb),
.A_I(twiAddr),
.D_I(data_i),
.D_O(data_o),
.DONE_O(done),
.ERR_O(error),
.CLK(clk),
.SRST(rst),
.SDA(sda),
.SCL(scl)
);
always @(posedge(clk))begin
if (delayEn==1)
delaycnt<=delaycnt-1;
else
delaycnt<=delay;
end
always @(posedge(clk))begin
if (state == stData1 && done == 1 && error != 1)
regData1 <= data_o;
end
always @(posedge(clk))begin
if (rst==1)begin
state<= stIdle;
delayEn <= 0;
initA <=0;
end
else begin
data_i <= "--------";
stb <= 0;
msg <= 0;
initFbWe <= 0;
case (state)
stRegAddr1: begin// Sends x40
if (done == 1)begin
if (error == 1)
state <= stError;
else
state <= stRegAddr2;
end
data_i <= initWord[31:24];
stb <= 1;
msg <= 1;
end
stRegAddr2: begin //Sends register address x40(XX)
if (done == 1)begin
if (error == 1)
state <= stError;
else
state <= stData1;
end
data_i <= initWord[23:16];
stb <= 1;
end
stData1: begin
if (done == 1) begin
if (error == 1)
state <= stError;
else begin
if (initWord[7:0]!=0)//If there is another byte, send it
state <= stData2;
else begin//no more bytes to send
initEn <= 1;
if (initA == INIT_VECTORS-1)//Done with all instructions
state <= stDone;
else //Only 3 bytes to send
state <= stDelay;
end
end
end
if (initWord[32] == 1) msg <= 1;
data_i <= initWord[15:8];
stb <= 1;
end
stData2: begin
if (done == 1)begin
if (error == 1)
state <= stError;
else begin
initEn<=1;
if (initWord[32] == 1) initFbWe <= 1;
if (initWord[23:16]== 8'h02)begin//If its the PLL register
initA<=initA+1;//Move initWord to the remaining PLL config bits
state <= stPLLsecond;//And send them
end
else if (initA == INIT_VECTORS-1)
state <= stDone;
else
state <= stDelay;
end
end
data_i <= initWord[7:0];
stb <= 1;
end
stPLLsecond:begin
if (done == 1)begin
if (error == 1)
state <= stError;
else
state <= stRegAddr2;
end
data_i <= initWord[31:24];
stb <= 1;
end
stError: begin
state <= stRegAddr1;
end
stDone: begin
end
stIdle:begin
state <= stRegAddr1;
end
stDelay:begin
delayEn <= 1;
if (delaycnt==0)begin
delayEn<=0;
if (initEn)begin
initA<=initA+1;
initEn <= 0;
end
state<=stRegAddr1;
end
end
endcase
end
end
endmodule
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 05/13/2015 09:14:14 PM
// Design Name:
// Module Name: debounce
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module debounce(
input clock,//100MHz clock
input reset,
input [4:0] button,//Buttons to debounce
output reg [4:0]out
);
reg [12:0] cnt0=0, cnt1=0, cnt2=0, cnt3=0, cnt4;
reg [4:0] IV = 0;
//parameter dbTime = 19;
parameter dbTime = 4000;
always @ (posedge(clock))begin
if(reset==1)begin
cnt0<=0;
cnt1<=0;
cnt2<=0;
cnt3<=0;
cnt4<=0;
out<=0;
end
else begin
if(button[0]==IV[0]) begin
if (cnt0==dbTime) begin
out[0]<=IV[0];
end
else begin
cnt0<=cnt0+1;
end
end
else begin
cnt0<=0;
IV[0]<=button[0];
end
if(button[1]==IV[1]) begin
if (cnt1==dbTime) begin
out[1]<=IV[1];
end
else begin
cnt1<=cnt1+1;
end
end
else begin
cnt1<=0;
IV[1]<=button[1];
end
if(button[2]==IV[2]) begin
if (cnt2==dbTime) begin
out[2]<=IV[2];
end
else begin
cnt2<=cnt2+1;
end
end
else begin
cnt2<=0;
IV[2]<=button[2];
end
if(button[3]==IV[3]) begin
if (cnt3==dbTime) begin
out[3]<=IV[3];
end
else begin
cnt3<=cnt3+1;
end
end
else begin
cnt3<=0;
IV[3]<=button[3];
end
if(button[4]==IV[4]) begin
if (cnt4==dbTime) begin
out[4]<=IV[4];
end
else begin
cnt4<=cnt4+1;
end
end
else begin
cnt4<=0;
IV[4]<=button[4];
end
end
end
endmodule
\ No newline at end of file
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 07/27/2016 02:04:22 PM
// Design Name:
// Module Name: debouncer
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module debouncer(
input clk,
input I,
output reg O
);
parameter COUNT_MAX=255, COUNT_WIDTH=8;
reg [COUNT_WIDTH-1:0] count;
reg Iv=0;
always@(posedge clk)
if (I == Iv) begin
if (count == COUNT_MAX)
O <= I;
else
count <= count + 1'b1;
end else begin
count <= 'b0;
Iv <= I;
end
endmodule
-------------------------------------------------------------------------------
--
-- COPYRIGHT (C) 2012, Digilent RO. All rights reserved
--
-------------------------------------------------------------------------------
-- FILE NAME : i2s_ctl.vhd
-- MODULE NAME : I2S Control
-- AUTHOR : Mihaita Nagy
-- AUTHOR'S EMAIL : mihaita.nagy@digilent.ro
-------------------------------------------------------------------------------
-- REVISION HISTORY
-- VERSION DATE AUTHOR DESCRIPTION
-- 1.0 2012-25-01 Mihaita Nagy Created
-- 2.0 2012-02-04 Mihaita Nagy Remade the i2s_transmitter.vhd and
-- i2s_receiver.vhd into one new module.
-- 3.0 2014-12-02 HegbeliC Implemented edge detection for the
-- master mode and the division rate
-- for the different sampling rates
-------------------------------------------------------------------------------
-- KEYWORDS : I2S
-------------------------------------------------------------------------------
-- DESCRIPTION : This module implements the I2S transmitter and receiver
-- interface, with a 32-bit Stereo data transmission. Parameter
-- C_DATA_WIDTH sets the width of the data to be transmitted,
-- with a maximum value of 32 bits. If a smaller width size is
-- used (i.e. 24) than the remaining bits that needs to be
-- transmitted to complete the 32-bit length, are automaticaly
-- set to 0.
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
------------------------------------------------------------------------
-- Module Declaration
------------------------------------------------------------------------
entity i2s_ctl is
generic (
-- Width of one Slot (24/20/18/16-bit wide)
C_DATA_WIDTH: integer := 24
);
port (
CLK_I : in std_logic; -- System clock (100 MHz)
RST_I : in std_logic; -- System reset
EN_TX_I : in std_logic; -- Transmit enable
EN_RX_I : in std_logic; -- Receive enable
FS_I : in std_logic_vector(3 downto 0); -- Sampling rate slector
MM_I : in std_logic; -- Audio controler Master Mode delcetor
D_L_I : in std_logic_vector(C_DATA_WIDTH-1 downto 0); -- Left channel data
D_R_I : in std_logic_vector(C_DATA_WIDTH-1 downto 0); -- Right channel data
-- OE_L_O : out std_logic; -- Left channel data output enable pulse
-- OE_R_O : out std_logic; -- Right channel data output enable pulse
-- WE_L_O : out std_logic; -- Left channel data write enable pulse
-- WE_R_O : out std_logic; -- Right channel data write enable pulse
D_L_O : out std_logic_vector(C_DATA_WIDTH-1 downto 0); -- Left channel data
D_R_O : out std_logic_vector(C_DATA_WIDTH-1 downto 0); -- Right channel data
BCLK_O : out std_logic; -- serial CLK
LRCLK_O : out std_logic; -- channel CLK
SDATA_O : out std_logic; -- Output serial data
SDATA_I : in std_logic -- Input serial data
);
end i2s_ctl;
architecture Behavioral of i2s_ctl is
------------------------------------------------------------------------
-- Signal Declarations
------------------------------------------------------------------------
-- Counter for the clock divider
signal Cnt_Bclk : integer range 0 to 31;
-- Counter for the L/R clock divider
signal Cnt_Lrclk : integer range 0 to 31;
-- Rising and Falling edge impulses of the serial clock
signal BCLK_Fall, BCLK_Rise : std_logic;
signal BCLK_Fall_int, BCLK_Rise_int : std_logic;
--signal BCLK_Fall_shot, BCLK_Rise_shot : std_logic;
-- Synchronisation signals for Rising and Falling edge
signal Q1R, Q2R, Q3R : std_logic;
signal Q1F, Q2F, Q3F : std_logic;
-- Internal synchronous BCLK signal
signal BCLK_int : std_logic;
-- Internal synchronous LRCLK signal
signal LRCLK_int : std_logic;
signal LRCLK : std_logic;
--
signal Data_Out_int : std_logic_vector(31 downto 0);
--
signal Data_In_int : std_logic_vector(31 downto 0);
--
signal D_L_O_int : std_logic_vector(C_DATA_WIDTH-1 downto 0);
--
signal D_R_O_int : std_logic_vector(C_DATA_WIDTH-1 downto 0);
--Internal synchronous OE signals
signal OE_R_int, OE_L_int : std_logic;
--Internal synchronous WE signals
signal WE_R_int, WE_L_int : std_logic;
-- Division rate for the BCLK and LRCLK
signal DIV_RATE : natural := 4;
------------------------------------------------------------------------
-- Module Implementation
------------------------------------------------------------------------
begin
------------------------------------------------------------------------
-- Sampling frequency and data width decoder (DIV_RATE, C_DATA_WIDTH)
------------------------------------------------------------------------
BIT_FS: process(CLK_I)
begin
if rising_edge(CLK_I) then
case (FS_I) is
when x"0" => DIV_RATE <= 24;
when x"1" => DIV_RATE <= 16;
when x"2" => DIV_RATE <= 12;
when x"3" => DIV_RATE <= 8;
when x"4" => DIV_RATE <= 6;
when x"5" => DIV_RATE <= 4;
when x"6" => DIV_RATE <= 2;
when others => DIV_RATE <= 4;
end case;
end if;
end process;
------------------------------------------------------------------------
-- Serial clock generator (BCLK_O, BCLK_Fall, BCLK_Rise)
------------------------------------------------------------------------
SER_CLK: process(CLK_I)
begin
if rising_edge(CLK_I) then
if RST_I = '1' then
Cnt_Bclk <= 0;
BCLK_int <= '0';
elsif Cnt_Bclk = ((DIV_RATE/2)-1) then
Cnt_Bclk <= 0;
BCLK_int <= not BCLK_int;
else
Cnt_Bclk <= Cnt_Bclk + 1;
end if;
end if;
end process SER_CLK;
-- Rising and Falling edges when in Slave mode
BCLK_Fall_int <= '1' when Cnt_Bclk = ((DIV_RATE/2)-1) and BCLK_int = '1' and (EN_RX_I = '1' or EN_TX_I = '1') else '0';
BCLK_Rise_int <= '1' when Cnt_Bclk = ((DIV_RATE/2)-1) and BCLK_int = '0' and (EN_RX_I = '1' or EN_TX_I = '1') else '0';
-- Falling edge selection with respect to Master Mode bit
BCLK_Fall <= BCLK_Fall_int;
-- Risesing edge selection with respect to Master Mode bit
BCLK_Rise <= BCLK_Rise_int;
-- Serial clock output
BCLK_O <= BCLK_int when EN_RX_I = '1' or EN_TX_I = '1' else '1';
------------------------------------------------------------------------
-- Left/Right clock generator (LRCLK_O, LRCLK_Pls)
------------------------------------------------------------------------
LRCLK_GEN: process(CLK_I)
begin
if rising_edge(CLK_I) then
if RST_I = '1' then
Cnt_Lrclk <= 0;
LRCLK <= '0'; -- Left channel active by default
elsif BCLK_Fall = '1' then
if Cnt_Lrclk = 31 then -- half of frame (64 bits)
Cnt_Lrclk <= 0;
LRCLK <= not LRCLK;
else
Cnt_Lrclk <= Cnt_Lrclk + 1;
end if;
end if;
end if;
end process LRCLK_GEN;
-- L/R clock output
LRCLK_O <= LRCLK when EN_TX_I = '1' or EN_RX_I = '1' else '0';
LRCLK_int <= LRCLK;
------------------------------------------------------------------------
-- Load in paralled data, shift out serial data (SDATA_O)
------------------------------------------------------------------------
SER_DATA_O: process(CLK_I)
begin
if rising_edge(CLK_I) then
if RST_I = '1' then
Data_Out_int(31) <= '0';
Data_Out_int(30 downto 31-C_DATA_WIDTH) <= D_L_I; -- Left channel data by default
Data_Out_int(30-C_DATA_WIDTH downto 0) <= (others => '0');
elsif Cnt_Lrclk = 0 and BCLK_Rise = '1' then -- load par. data
if LRCLK_int = '1' then
Data_Out_int(31) <= '0';
Data_Out_int(30 downto 31-C_DATA_WIDTH) <= D_R_I;
Data_Out_int(30-C_DATA_WIDTH downto 0) <= (others => '0');
else
Data_Out_int(31) <= '0';
Data_Out_int(30 downto 31-C_DATA_WIDTH) <= D_L_I;
Data_Out_int(30-C_DATA_WIDTH downto 0) <= (others => '0');
end if;
elsif BCLK_Fall = '1' then -- shift out ser. data
Data_Out_int <= Data_Out_int(30 downto 0) & '0';
end if;
end if;
end process SER_DATA_O;
-- Serial data output
SDATA_O <= Data_Out_int(31) when EN_TX_I = '1' else '0';
------------------------------------------------------------------------
-- Shift in serial data, load out parallel data (SDATA_I)
------------------------------------------------------------------------
SER_DATA_I: process(CLK_I)
begin
if rising_edge(CLK_I) then
if RST_I = '1' then
Data_In_int <= (others => '0');
D_L_O_int <= (others => '0');
D_R_O_int <= (others => '0');
elsif Cnt_Lrclk = 0 and BCLK_Fall = '1' then -- load par. data
if LRCLK_int = '1' then
D_L_O_int <= Data_In_int(31 downto 32-C_DATA_WIDTH);
Data_In_int <= (others => '0');
else
D_R_O_int <= Data_In_int(31 downto 32-C_DATA_WIDTH);
Data_In_int <= (others => '0');
end if;
elsif BCLK_Rise = '1' then -- shift in ser. data
Data_In_int <= Data_In_int(30 downto 0) & SDATA_I;
end if;
end if;
end process SER_DATA_I;
D_L_O <= D_L_O_int;
D_R_O <= D_R_O_int;
--------------------------------------------------------------------------
---- Output Enable signals (for FIFO)
--------------------------------------------------------------------------
-- OE_GEN: process(CLK_I)
-- begin
-- if rising_edge(CLK_I) then
-- if Cnt_Lrclk = 31 and BCLK_Fall = '1' then
-- if LRCLK_int = '1' then -- Right channel
-- OE_R_int <= '1';
-- else -- Left channel
-- OE_L_int <= '1';
-- end if;
-- else
-- OE_R_int <= '0';
-- OE_L_int <= '0';
-- end if;
-- end if;
-- end process OE_GEN;
-- OE_R_O <= OE_R_int when EN_TX_I = '1' else '0';
-- OE_L_O <= OE_L_int when EN_TX_I = '1' else '0';
--------------------------------------------------------------------------
---- Write Enable signals (for FIFO)
--------------------------------------------------------------------------
-- WE_GEN: process(CLK_I)
-- begin
-- if rising_edge(CLK_I) then
-- if Cnt_Lrclk = 1 and BCLK_Rise = '1' then
-- if LRCLK_int = '1' then -- Right channel
-- WE_R_int <= '1';
-- else -- Left channel
-- WE_L_int <= '1';
-- end if;
-- else
-- WE_R_int <= '0';
-- WE_L_int <= '0';
-- end if;
-- end if;
-- end process WE_GEN;
-- WE_R_O <= WE_R_int when EN_RX_I = '1' else '0';
-- WE_L_O <= WE_L_int when EN_RX_I = '1' else '0';
end Behavioral;
library ieee;
use ieee.std_logic_1164.all;
entity module_A is
port (
I_clk : in std_logic;
I_rst : in std_logic;
I_wave_sel : in std_logic_vector(1 downto 0);
I_middle : in std_logic;
I_last : in std_logic;
O_u_d : out std_logic;
O_sign_sel : out std_logic
);
end module_A;
architecture behavioral of module_A is
type state_type is (st_0_to_PI_2, st_PI_2_to_PI, st_PI_to_3_PI_2, st_3_PI_2_to_2_PI);
signal state_reg : state_type := st_0_to_PI_2;
begin
process (I_clk)
begin
if rising_edge(I_clk) then
if I_rst = '1' then
state_reg <= st_0_to_PI_2;
O_sign_sel <= '0';
else
case state_reg is
when st_0_to_PI_2 =>
if I_middle = '1' then
state_reg <= st_PI_2_to_PI;
end if;
when st_PI_2_to_PI =>
if I_last = '1' then
state_reg <= st_PI_to_3_PI_2;
end if;
when st_PI_to_3_PI_2 =>
if I_middle = '1' then
state_reg <= st_3_PI_2_to_2_PI;
end if;
when st_3_PI_2_to_2_PI =>
if I_last = '1' then
state_reg <= st_0_to_PI_2;
end if;
end case;
O_sign_sel <= '0' when state_reg = st_0_to_PI_2 or state_reg = st_PI_2_to_PI else '1';
end if;
end if;
end process;
O_u_d <= '1' when (I_wave_sel /= "11" and (state_reg = st_0_to_PI_2 or state_reg = st_PI_to_3_PI_2)) or (I_wave_sel = "11" and (state_reg = st_0_to_PI_2 or state_reg = st_PI_2_to_PI)) else
'0';
end behavioral;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
entity module_B is
generic (
G_MAX_VAL : natural := 25
);
port (
I_clk : in std_logic;
I_rst : in std_logic;
I_u_d : in std_logic;
O_val : out std_logic_vector(integer(ceil(log2(real(G_MAX_VAL)))) - 1 downto 0);
O_last : out std_logic;
O_middle : out std_logic
);
end module_B;
architecture behavioral of module_B is
signal SR_val_reg : natural range 0 to G_MAX_VAL := 0;
constant C_middle_val : natural := G_MAX_VAL/2;
begin
process(I_clk)
begin
if rising_edge(I_clk) then
if I_rst = '1' then
SR_val_reg <= 0;
else
if I_u_d = '1' then
SR_val_reg <= SR_val_reg + 1;
else
SR_val_reg <= SR_val_reg - 1;
end if;
end if;
end if;
end process;
O_last <= '1' when (I_u_d = '1' and SR_val_reg = G_MAX_VAL-1) or (I_u_d = '0' and SR_val_reg = 1) else '0';
O_middle <= '1' when (I_u_d = '1'and SR_val_reg = C_middle_val-1) or (I_u_d = '0' and SR_val_reg = C_middle_val+1) else '0';
O_val <= std_logic_vector(to_unsigned(SR_val_reg, integer(ceil(log2(real(G_MAX_VAL))))));
end behavioral;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
use work.wave_package.all;
entity module_C is
generic (
G_N : integer := 8;
G_f0 : real := 1.0;
G_fs : real := 100.0
);
port (
I_clk : in std_logic;
I_rst : in std_logic;
I_addr : in std_logic_vector(integer(ceil(log2(real(natural(floor(G_fs/(4.0*G_f0))))))) - 1 downto 0);
O_sine : out std_logic_vector(G_N-1 downto 0)
);
end module_C;
architecture behavioral of module_C is
constant C_LUT_SIZE : natural := natural(floor(G_fs/(4.0*G_f0)))+1; -- number of samples in the LUT for phases ranging from 0 to PI/2 (inclusive)
signal SR_lut : lut_type(0 to C_LUT_SIZE-1)(G_N-1 downto 0) := sine_table(C_LUT_SIZE, G_N, G_f0, G_fs);
signal SR_sine_out : signed(G_N-1 downto 0) := (others => '0');
signal SC_sat_addr : integer range 0 to C_LUT_SIZE - 1;
begin
SC_sat_addr <= to_integer(unsigned(I_addr)) when unsigned(I_addr) < C_LUT_SIZE else C_LUT_SIZE - 1;
process(I_clk)
begin
if rising_edge(I_clk) then
if I_rst = '1' then
SR_sine_out <= (others => '0');
else
SR_sine_out <= SR_lut(SC_sat_addr);
end if;
end if;
end process;
O_sine <= std_logic_vector(SR_sine_out);
end behavioral;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
use work.wave_package.all;
entity module_D is
generic (
G_N : integer := 8;
G_f0 : real := 1.0;
G_fs : real := 100.0
);
port (
I_clk : in std_logic;
I_rst : in std_logic;
I_addr : in std_logic_vector(integer(ceil(log2(real(natural(floor(G_fs/(4.0*G_f0))))))) - 1 downto 0);
O_triangle : out std_logic_vector(G_N-1 downto 0)
);
end module_D;
architecture behavioral of module_D is
constant C_LUT_SIZE : natural := natural(floor(G_fs/(4.0*G_f0))) + 1; -- number of samples in the LUT for phases ranging from 0 to PI/2 (inclusive)
signal SR_lut : lut_type(0 to C_LUT_SIZE-1)(G_N-1 downto 0) := triangle_table(C_LUT_SIZE, G_N, G_f0, G_fs);
signal SR_triangle_out : signed(G_N-1 downto 0) := (others => '0');
signal SC_sat_addr : integer range 0 to C_LUT_SIZE - 1;
begin
SC_sat_addr <= to_integer(unsigned(I_addr)) when unsigned(I_addr) < C_LUT_SIZE else C_LUT_SIZE - 1;
process(I_clk)
begin
if rising_edge(I_clk) then
if I_rst = '1' then
SR_triangle_out <= (others => '0');
else
SR_triangle_out <= SR_lut(SC_sat_addr);
end if;
end if;
end process;
O_triangle <= std_logic_vector(SR_triangle_out);
end behavioral;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment