Rough draft for each design
Signed-off-by: Joshua Fife <jpfife17@gmail.com>
This commit is contained in:
parent
96bbace913
commit
8cf20cd99f
|
@ -6,7 +6,7 @@ on the basys3 board. The number of presses will be given on the seven segment di
|
|||
by pressing the up button on the board. To build the design first navigate to the additional examples directory:
|
||||
|
||||
.. code-block:: bash
|
||||
:name: example-debouncer-basys3
|
||||
:name: additional-examples
|
||||
|
||||
cd additional_examples
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 24 MiB |
|
@ -0,0 +1,41 @@
|
|||
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||
current_dir := $(patsubst %/,%,$(dir $(mkfile_path)))
|
||||
TOP := top
|
||||
SOURCES := ${current_dir}/*.sv
|
||||
SOURCES += ${current_dir}/*.v
|
||||
DEVICE := xc7a50t_test
|
||||
BITSTREAM_DEVICE := artix7
|
||||
BUILDDIR:=build
|
||||
|
||||
PARTNAME := xc7a35tcpg236-1
|
||||
BOARD_BUILDDIR := ${BUILDDIR}/basys3
|
||||
XDC:=${current_dir}/*.xdc
|
||||
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
|
||||
all: ${BOARD_BUILDDIR}/${TOP}.bit
|
||||
|
||||
${BOARD_BUILDDIR}:
|
||||
mkdir -p ${BOARD_BUILDDIR}
|
||||
|
||||
${BOARD_BUILDDIR}/${TOP}.eblif: | ${BOARD_BUILDDIR}
|
||||
cd ${BOARD_BUILDDIR} && symbiflow_synth -t ${TOP} -v ${SOURCES} -d ${BITSTREAM_DEVICE} -p ${PARTNAME} -x ${XDC} 2>&1 > /dev/null
|
||||
|
||||
${BOARD_BUILDDIR}/${TOP}.net: ${BOARD_BUILDDIR}/${TOP}.eblif
|
||||
cd ${BOARD_BUILDDIR} && symbiflow_pack -e ${TOP}.eblif -d ${DEVICE} 2>&1 > /dev/null
|
||||
|
||||
${BOARD_BUILDDIR}/${TOP}.place: ${BOARD_BUILDDIR}/${TOP}.net
|
||||
cd ${BOARD_BUILDDIR} && symbiflow_place -e ${TOP}.eblif -d ${DEVICE} -n ${TOP}.net -P ${PARTNAME} 2>&1 > /dev/null
|
||||
|
||||
${BOARD_BUILDDIR}/${TOP}.route: ${BOARD_BUILDDIR}/${TOP}.place
|
||||
cd ${BOARD_BUILDDIR} && symbiflow_route -e ${TOP}.eblif -d ${DEVICE} 2>&1 > /dev/null
|
||||
|
||||
${BOARD_BUILDDIR}/${TOP}.fasm: ${BOARD_BUILDDIR}/${TOP}.route
|
||||
cd ${BOARD_BUILDDIR} && symbiflow_write_fasm -e ${TOP}.eblif -d ${DEVICE}
|
||||
|
||||
${BOARD_BUILDDIR}/${TOP}.bit: ${BOARD_BUILDDIR}/${TOP}.fasm
|
||||
cd ${BOARD_BUILDDIR} && symbiflow_write_bitstream -d ${BITSTREAM_DEVICE} -f ${TOP}.fasm -p ${PARTNAME} -b ${TOP}.bit
|
||||
|
||||
clean:
|
||||
rm -rf ${BUILDDIR}
|
|
@ -0,0 +1,45 @@
|
|||
Registers
|
||||
~~~~~~~~~~
|
||||
|
||||
This module implements eight 4-bit registers, one
|
||||
3:8 decoder, and two 8:1 multiplexors to create a triple ported
|
||||
register file. This example also demonstrates symbiflows ability to parse a combination of verilog and system verilog files together as well as testing a few primitives.
|
||||
|
||||
|
||||
.. code-block:: bash
|
||||
:name: additional-example
|
||||
|
||||
cd additional_examples
|
||||
|
||||
Then run make to compile the design:
|
||||
|
||||
.. code-block:: bash
|
||||
:name: example-registers-basys3
|
||||
|
||||
make -C uart_receiver
|
||||
|
||||
|
||||
At completion, the bitstream is located in the build directory:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cd uart_receiver/build/arty_35
|
||||
|
||||
Now, you can upload the design with:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
openocd -f ${INSTALL_DIR}/${FPGA_FAM}/conda/envs/${FPGA_FAM}/share/openocd/scripts/board/digilent_arty.cfg -c "init; pld load 0 top.bit; exit"
|
||||
|
||||
Once the bitstream has been downloaded to the board, you can load different registers by toggling different switches on and off. Switches 0-4 on the basys define the binary value
|
||||
to be written to the register speciefied by switches 4-6. Switches 4-6 also act as the first read address on the triple ported register file.
|
||||
switches 6-9 define the second read address. The center button on the board is the write
|
||||
enable signal. The value being read is displayed on the basys3's seven segment display in hex.
|
||||
You can chose to display the first or second btnl and the values of reg 1 and 2 together, btnu-reg2+reg1, btnd-reg1-reg2. The value
|
||||
you chose will be output o the first segment of the basys board.
|
||||
|
||||
.. image:: ../images/registers.gif
|
||||
:align: center
|
||||
:width: 50%
|
||||
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# Clock
|
||||
set_property -dict { PACKAGE_PIN W5 IOSTANDARD LVCMOS33 } [get_ports { clk }];
|
||||
create_clock -period 10.00 [get_ports {clk}];
|
||||
|
||||
# Buttons
|
||||
set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { btnc }];
|
||||
set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { btnu }];
|
||||
set_property -dict { PACKAGE_PIN W19 IOSTANDARD LVCMOS33 } [get_ports { btnl }];
|
||||
set_property -dict { PACKAGE_PIN T17 IOSTANDARD LVCMOS33 } [get_ports { btnr }];
|
||||
set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { btnd }];
|
||||
|
||||
# Switches
|
||||
set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }];
|
||||
set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }];
|
||||
set_property -dict { PACKAGE_PIN W16 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }];
|
||||
set_property -dict { PACKAGE_PIN W17 IOSTANDARD LVCMOS33 } [get_ports { sw[3] }];
|
||||
set_property -dict { PACKAGE_PIN W15 IOSTANDARD LVCMOS33 } [get_ports { sw[4] }];
|
||||
set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { sw[5] }];
|
||||
set_property -dict { PACKAGE_PIN W14 IOSTANDARD LVCMOS33 } [get_ports { sw[6] }];
|
||||
set_property -dict { PACKAGE_PIN W13 IOSTANDARD LVCMOS33 } [get_ports { sw[7] }];
|
||||
set_property -dict { PACKAGE_PIN V2 IOSTANDARD LVCMOS33 } [get_ports { sw[8] }];
|
||||
set_property -dict { PACKAGE_PIN T3 IOSTANDARD LVCMOS33 } [get_ports { sw[9] }];
|
||||
|
||||
|
||||
# Seven-Segment Display
|
||||
set_property -dict { PACKAGE_PIN W7 IOSTANDARD LVCMOS33 } [get_ports { segment[0] }];
|
||||
set_property -dict { PACKAGE_PIN W6 IOSTANDARD LVCMOS33 } [get_ports { segment[1] }];
|
||||
set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS33 } [get_ports { segment[2] }];
|
||||
set_property -dict { PACKAGE_PIN V8 IOSTANDARD LVCMOS33 } [get_ports { segment[3] }];
|
||||
set_property -dict { PACKAGE_PIN U5 IOSTANDARD LVCMOS33 } [get_ports { segment[4] }];
|
||||
set_property -dict { PACKAGE_PIN V5 IOSTANDARD LVCMOS33 } [get_ports { segment[5] }];
|
||||
set_property -dict { PACKAGE_PIN U7 IOSTANDARD LVCMOS33 } [get_ports { segment[6] }];
|
||||
set_property -dict { PACKAGE_PIN V7 IOSTANDARD LVCMOS33 } [get_ports { segment[7] }];
|
||||
set_property -dict { PACKAGE_PIN U2 IOSTANDARD LVCMOS33 } [get_ports { anode[0] }];
|
||||
set_property -dict { PACKAGE_PIN U4 IOSTANDARD LVCMOS33 } [get_ports { anode[1] }];
|
||||
set_property -dict { PACKAGE_PIN V4 IOSTANDARD LVCMOS33 } [get_ports { anode[2] }];
|
||||
set_property -dict { PACKAGE_PIN W4 IOSTANDARD LVCMOS33 } [get_ports { anode[3] }];
|
|
@ -0,0 +1,10 @@
|
|||
module register4(
|
||||
input logic clk, we,
|
||||
input logic[3:0] datain,
|
||||
output logic[3:0] dataout
|
||||
);
|
||||
FDCE my_ff1 (.Q(dataout[0]), .C(clk), .CE(we), .CLR(1'b0), .D(datain[0]));
|
||||
FDCE my_ff2 (.Q(dataout[1]), .C(clk), .CE(we), .CLR(1'b0), .D(datain[1]));
|
||||
FDCE my_ff3 (.Q(dataout[2]), .C(clk), .CE(we), .CLR(1'b0), .D(datain[2]));
|
||||
FDCE my_ff4 (.Q(dataout[3]), .C(clk), .CE(we), .CLR(1'b0), .D(datain[3]));
|
||||
endmodule
|
|
@ -0,0 +1,33 @@
|
|||
module register_file_8x4(
|
||||
input logic clk, we,
|
||||
input logic[3:0] datain,
|
||||
input logic[2:0] waddr, raddr1, raddr2,
|
||||
output logic[3:0] dataout1, dataout2
|
||||
);
|
||||
logic[7:0] RWS;
|
||||
logic[3:0] reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7;
|
||||
assign RWS = {8{we}} & (8'b00000001 << waddr);
|
||||
register4 R1 (.clk(clk), .we(RWS[0]), .datain(datain), .dataout(reg0));
|
||||
register4 R2 (.clk(clk), .we(RWS[1]), .datain(datain), .dataout(reg1));
|
||||
register4 R3 (.clk(clk), .we(RWS[2]), .datain(datain), .dataout(reg2));
|
||||
register4 R4 (.clk(clk), .we(RWS[3]), .datain(datain), .dataout(reg3));
|
||||
register4 R5 (.clk(clk), .we(RWS[4]), .datain(datain), .dataout(reg4));
|
||||
register4 R6 (.clk(clk), .we(RWS[5]), .datain(datain), .dataout(reg5));
|
||||
register4 R7 (.clk(clk), .we(RWS[6]), .datain(datain), .dataout(reg6));
|
||||
register4 R8 (.clk(clk), .we(RWS[7]), .datain(datain), .dataout(reg7));
|
||||
assign dataout1 = (raddr1 == 0)?reg0:
|
||||
(raddr1 == 1)?reg1:
|
||||
(raddr1 == 2)?reg2:
|
||||
(raddr1 == 3)?reg3:(raddr1 == 4)?reg4:
|
||||
(raddr1 == 5)?reg5:
|
||||
(raddr1 == 6)?reg6:
|
||||
reg7;
|
||||
assign dataout2= (raddr2 == 0)?reg0:
|
||||
(raddr2 == 1)?reg1:
|
||||
(raddr2 == 2)?reg2:
|
||||
(raddr2 == 3)?reg3:
|
||||
(raddr2 == 4)?reg4:
|
||||
(raddr2 == 5)?reg5:
|
||||
(raddr2 == 6)?reg6:
|
||||
reg7;
|
||||
endmodule
|
|
@ -0,0 +1,18 @@
|
|||
module top(
|
||||
input logic clk, btnc, btnr, btnu, btnd, btnl,
|
||||
input logic[9:0] sw,
|
||||
output logic[7:0] segment,
|
||||
output logic[3:0] anode
|
||||
);
|
||||
logic[3:0] dataout1, dataout2, outdata;
|
||||
register_file_8x4 R0(.clk(clk), .we(btnc), .datain(sw[3:0]), .waddr(sw[6:4]),
|
||||
.raddr1(sw[6:4]), .raddr2(sw[9:7]), .dataout1(dataout1), .dataout2(dataout2));
|
||||
assign outdata = (btnr == 1) ? dataout2:
|
||||
(btnu == 1)? dataout2 + dataout1:
|
||||
(btnd == 1)? dataout1 - dataout2:
|
||||
(btnl == 1)? dataout1&dataout2:
|
||||
dataout1;
|
||||
seven_segment S0(.data(outdata), .segment(segment[6:0]));
|
||||
assign anode = 4'b1110;
|
||||
assign segment[7] = 1;
|
||||
endmodule
|
|
@ -0,0 +1,39 @@
|
|||
module seven_segment(
|
||||
input [3:0] data,
|
||||
output [6:0] segment
|
||||
);
|
||||
wire [3:0] CA;
|
||||
wire [4:0] CB;
|
||||
wire [3:0] ND;
|
||||
|
||||
not(ND[3], data[3]);
|
||||
not(ND[2], data[2]);
|
||||
not(ND[1], data[1]);
|
||||
not(ND[0], data[0]);
|
||||
|
||||
and(CA[0], ND[3], ND[2], ND[1], data[0]);
|
||||
and(CA[1], ND[3], data[2], ND[1], ND[0]);
|
||||
and(CA[2], data[3], ND[2], data[1], data[0]);
|
||||
and(CA[3], data[3], data[2], ND[1], data[0]);
|
||||
|
||||
or(segment[0], CA[0], CA[1], CA[2], CA[3]);
|
||||
|
||||
and(CB[0], ND[3], data[2], ND[1], data[0]);
|
||||
and(CB[1], data[2], data[1], ND[0]);
|
||||
and(CB[2], data[3], data[2], ND[0]);
|
||||
and(CB[3], data[3], ND[2], data[1], data[0]);
|
||||
and(CB[4], data[3], data[2], data[1]);
|
||||
|
||||
or(segment[1], CB[0], CB[1], CB[2], CB[3], CB[4]);
|
||||
|
||||
LUT4 #(16'hd004) seg0(.O(segment[2]), .I0(data[0]), .I1(data[1]), .I2(data[2]), .I3(data[3]));
|
||||
LUT4 #(16'h8492) seg1(.O(segment[3]), .I0(data[0]), .I1(data[1]), .I2(data[2]), .I3(data[3]));
|
||||
LUT4 #(16'h02ba) seg2(.O(segment[4]), .I0(data[0]), .I1(data[1]), .I2(data[2]), .I3(data[3]));
|
||||
LUT4 #(16'h208e) seg3(.O(segment[5]), .I0(data[0]), .I1(data[1]), .I2(data[2]), .I3(data[3]));
|
||||
LUT4 #(16'h1083) seg4(.O(segment[6]), .I0(data[0]), .I1(data[1]), .I2(data[2]), .I3(data[3]));
|
||||
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
module top(
|
||||
input wire logic clk,
|
||||
input wire logic btnu, //reset button
|
||||
input wire logic btnu,
|
||||
input wire logic [7:0] sw,
|
||||
input wire logic btnc,
|
||||
output logic [3:0] anode,
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||
current_dir := $(patsubst %/,%,$(dir $(mkfile_path)))
|
||||
TOP := top
|
||||
SYSTEM_VERILOG := ${current_dir}/*.sv
|
||||
DEVICE := xc7a50t_test
|
||||
BITSTREAM_DEVICE := artix7
|
||||
BUILDDIR:=build
|
||||
|
||||
ifeq ($(TARGET),arty_35)
|
||||
PARTNAME := xc7a35tcsg324-1
|
||||
BOARD_BUILDDIR := ${BUILDDIR}/arty_35
|
||||
else ifeq ($(TARGET),arty_100)
|
||||
PARTNAME:= xc7a100tcsg324-1
|
||||
DEVICE:= xc7a100t_test
|
||||
BOARD_BUILDDIR := ${BUILDDIR}/arty_100
|
||||
else ifeq ($(TARGET),nexys4ddr)
|
||||
PARTNAME:= xc7a100tcsg324-1
|
||||
DEVICE:= xc7a100t_test
|
||||
BOARD_BUILDDIR := ${BUILDDIR}/nexys4ddr
|
||||
else ifeq ($(TARGET),zybo)
|
||||
PARTNAME:= xc7z010clg400-1
|
||||
DEVICE:= xc7z010_test
|
||||
BITSTREAM_DEVICE:= zynq7
|
||||
BOARD_BUILDDIR := ${BUILDDIR}/zybo
|
||||
else ifeq ($(TARGET),nexys_video)
|
||||
PARTNAME:= xc7a200tsbg484-1
|
||||
DEVICE:= xc7a200t_test
|
||||
BOARD_BUILDDIR := ${BUILDDIR}/nexys_video
|
||||
else
|
||||
PARTNAME:= xc7a35tcpg236-1
|
||||
BOARD_BUILDDIR := ${BUILDDIR}/basys3
|
||||
endif
|
||||
|
||||
XDC:=${current_dir}/*.xdc
|
||||
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
|
||||
all: ${BOARD_BUILDDIR}/${TOP}.bit
|
||||
|
||||
${BOARD_BUILDDIR}:
|
||||
mkdir -p ${BOARD_BUILDDIR}
|
||||
|
||||
${BOARD_BUILDDIR}/${TOP}.eblif: | ${BOARD_BUILDDIR}
|
||||
cd ${BOARD_BUILDDIR} && symbiflow_synth -t ${TOP} -v ${SYSTEM_VERILOG} -d ${BITSTREAM_DEVICE} -p ${PARTNAME} -x ${XDC} 2>&1 > /dev/null
|
||||
|
||||
${BOARD_BUILDDIR}/${TOP}.net: ${BOARD_BUILDDIR}/${TOP}.eblif
|
||||
cd ${BOARD_BUILDDIR} && symbiflow_pack -e ${TOP}.eblif -d ${DEVICE} 2>&1 > /dev/null
|
||||
|
||||
${BOARD_BUILDDIR}/${TOP}.place: ${BOARD_BUILDDIR}/${TOP}.net
|
||||
cd ${BOARD_BUILDDIR} && symbiflow_place -e ${TOP}.eblif -d ${DEVICE} -n ${TOP}.net -P ${PARTNAME} 2>&1 > /dev/null
|
||||
|
||||
${BOARD_BUILDDIR}/${TOP}.route: ${BOARD_BUILDDIR}/${TOP}.place
|
||||
cd ${BOARD_BUILDDIR} && symbiflow_route -e ${TOP}.eblif -d ${DEVICE} 2>&1 > /dev/null
|
||||
|
||||
${BOARD_BUILDDIR}/${TOP}.fasm: ${BOARD_BUILDDIR}/${TOP}.route
|
||||
cd ${BOARD_BUILDDIR} && symbiflow_write_fasm -e ${TOP}.eblif -d ${DEVICE}
|
||||
|
||||
${BOARD_BUILDDIR}/${TOP}.bit: ${BOARD_BUILDDIR}/${TOP}.fasm
|
||||
cd ${BOARD_BUILDDIR} && symbiflow_write_bitstream -d ${BITSTREAM_DEVICE} -f ${TOP}.fasm -p ${PARTNAME} -b ${TOP}.bit
|
||||
|
||||
clean:
|
||||
rm -rf ${BUILDDIR}
|
|
@ -0,0 +1,43 @@
|
|||
UART Receiver
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This UART receiver on the basys3 board.
|
||||
|
||||
.. code-block:: bash
|
||||
:name: additional-example
|
||||
|
||||
cd additional_examples
|
||||
|
||||
Then run make to compile the design:
|
||||
|
||||
.. code-block:: bash
|
||||
:name: example-uarttx-basys3
|
||||
|
||||
make -C uart_receiver
|
||||
|
||||
|
||||
At completion, the bitstream is located in the build directory:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cd uart_receiver/build/arty_35
|
||||
|
||||
Now, you can upload the design with:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
openocd -f ${INSTALL_DIR}/${FPGA_FAM}/conda/envs/${FPGA_FAM}/share/openocd/scripts/board/digilent_arty.cfg -c "init; pld load 0 top.bit; exit"
|
||||
|
||||
Once the code has been downloaded to the board open a Putty terminal and choose the serial connection line for your board.
|
||||
Also set the baud rate to 19200, data bits to 8, stop bits to 1, the parity to ODD, and the flow control to NONE. You can
|
||||
change these properties by looking under the serial settings on the left hand side.
|
||||
|
||||
After configuring Putty, open a session and type some characters. The ASKII values of the keys you press will be displayed
|
||||
on the basys3 board in hex. The LEDs are used to notify of any reception errors. You can also transmit ASKII characters to putty
|
||||
by following the same procedures as in the uart_receiver example. The following is an example of the receiver:
|
||||
|
||||
.. image:: ../images/uart_tx.gif
|
||||
:align: center
|
||||
:width: 50%
|
||||
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
`default_nettype none
|
||||
module SevenSegmentControl(
|
||||
input wire logic clk,
|
||||
input wire logic reset,
|
||||
input wire logic [15:0] dataIn,
|
||||
input wire logic [3:0] digitDisplay,
|
||||
input wire logic [3:0] digitPoint,
|
||||
output logic [3:0] anode,
|
||||
output logic [7:0] segment
|
||||
);
|
||||
|
||||
parameter integer COUNT_BITS = 17;
|
||||
|
||||
logic [COUNT_BITS-1:0] count_val;
|
||||
logic [1:0] anode_select;
|
||||
logic [3:0] cur_anode;
|
||||
logic [3:0] cur_data_in;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset)
|
||||
count_val <= 0;
|
||||
else
|
||||
count_val <= count_val + 1;
|
||||
end
|
||||
|
||||
assign anode_select = count_val[COUNT_BITS-1:COUNT_BITS-2];
|
||||
|
||||
assign cur_anode =
|
||||
(anode_select == 2'b00) ? 4'b1110 :
|
||||
(anode_select == 2'b01) ? 4'b1101 :
|
||||
(anode_select == 2'b10) ? 4'b1011 :
|
||||
4'b0111;
|
||||
|
||||
assign anode = cur_anode | (~digitDisplay);
|
||||
|
||||
assign cur_data_in =
|
||||
(anode_select == 2'b00) ? dataIn[3:0] :
|
||||
(anode_select == 2'b01) ? dataIn[7:4] :
|
||||
(anode_select == 2'b10) ? dataIn[11:8] :
|
||||
dataIn[15:12] ;
|
||||
|
||||
assign segment[7] =
|
||||
(anode_select == 2'b00) ? ~digitPoint[0] :
|
||||
(anode_select == 2'b01) ? ~digitPoint[1] :
|
||||
(anode_select == 2'b10) ? ~digitPoint[2] :
|
||||
~digitPoint[3] ;
|
||||
|
||||
assign segment[6:0] =
|
||||
(cur_data_in == 0) ? 7'b1000000 :
|
||||
(cur_data_in == 1) ? 7'b1111001 :
|
||||
(cur_data_in == 2) ? 7'b0100100 :
|
||||
(cur_data_in == 3) ? 7'b0110000 :
|
||||
(cur_data_in == 4) ? 7'b0011001 :
|
||||
(cur_data_in == 5) ? 7'b0010010 :
|
||||
(cur_data_in == 6) ? 7'b0000010 :
|
||||
(cur_data_in == 7) ? 7'b1111000 :
|
||||
(cur_data_in == 8) ? 7'b0000000 :
|
||||
(cur_data_in == 9) ? 7'b0010000 :
|
||||
(cur_data_in == 10) ? 7'b0001000 :
|
||||
(cur_data_in == 11) ? 7'b0000011 :
|
||||
(cur_data_in == 12) ? 7'b1000110 :
|
||||
(cur_data_in == 13) ? 7'b0100001 :
|
||||
(cur_data_in == 14) ? 7'b0000110 :
|
||||
7'b0001110;
|
||||
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,107 @@
|
|||
|
||||
module rx #(parameter CLK_FREQUENCY = 100000000, BAUD_RATE =
|
||||
19200)(
|
||||
input wire logic clk, odd, rx_in,
|
||||
output logic[7:0] dout,
|
||||
output logic data_strobe, error, busy
|
||||
);
|
||||
logic ResetTimer, EnableTimer, LastCycle, HalfCycle, LastBit, NextBit = 0,
|
||||
ResetCounter,
|
||||
Shift, Stop, Parity;
|
||||
localparam ONE_BIT_CNT = CLK_FREQUENCY / BAUD_RATE;
|
||||
localparam HALF_CNT = ONE_BIT_CNT / 2;
|
||||
function integer clogb2;
|
||||
input [31:0] value;
|
||||
begin
|
||||
value = value - 1;
|
||||
for (clogb2 = 0; value > 0; clogb2 = clogb2 + 1) begin
|
||||
value = value >> 1;
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
localparam NUM_BITS_FULL_CNT = clogb2(ONE_BIT_CNT);
|
||||
logic[NUM_BITS_FULL_CNT - 1:0] count = 0;
|
||||
|
||||
always_ff@ (posedge clk)
|
||||
begin
|
||||
if(ResetTimer || count == ONE_BIT_CNT)
|
||||
count <= 0;
|
||||
else if(EnableTimer)
|
||||
count <= count + 1;
|
||||
end
|
||||
assign LastCycle = (count == ONE_BIT_CNT) ? 1'b1:1'b0;
|
||||
|
||||
assign HalfCycle = (count == HALF_CNT) ? 1'b1:1'b0;
|
||||
|
||||
assign error = ~(((^dout)^odd)==Parity)||(~Stop);
|
||||
logic[3:0] countBit = 0;
|
||||
always_ff @(posedge clk)
|
||||
begin
|
||||
if(NextBit)
|
||||
countBit <= countBit + 1;
|
||||
else if(ResetCounter || LastBit)
|
||||
countBit <= 0;
|
||||
end
|
||||
assign LastBit = (countBit == 4'b1011) ? 1'b1:1'b0;
|
||||
|
||||
logic[9:0] shift = 10'b1111111111;
|
||||
always_ff @(posedge clk)
|
||||
begin
|
||||
if(Shift)
|
||||
shift <= {rx_in, shift[9:1]};
|
||||
end
|
||||
assign Stop = shift[9];assign Parity = shift[8];
|
||||
assign dout = shift[7:0];
|
||||
|
||||
typedef enum {IDLE, HALF, FULL, LOAD} stateType;
|
||||
stateType ns, cs;
|
||||
always_comb
|
||||
begin
|
||||
ns = cs;
|
||||
Shift = 0;
|
||||
busy = 1;
|
||||
EnableTimer = 0;
|
||||
ResetTimer = 0;
|
||||
ResetCounter = 0;
|
||||
data_strobe = 0;
|
||||
NextBit = 0;
|
||||
case(cs)
|
||||
IDLE:
|
||||
begin
|
||||
ResetTimer = 1;ResetCounter = 1;
|
||||
busy = 0;
|
||||
if(!rx_in)
|
||||
ns = HALF;
|
||||
end
|
||||
HALF:
|
||||
begin
|
||||
EnableTimer = 1;
|
||||
if(!HalfCycle && rx_in)
|
||||
ns = IDLE;
|
||||
else if(HalfCycle)
|
||||
ns = LOAD;
|
||||
end
|
||||
LOAD:
|
||||
begin
|
||||
busy = 1;
|
||||
Shift = 1;
|
||||
NextBit = 1;ResetTimer = 1;
|
||||
ns = FULL;
|
||||
end
|
||||
FULL:
|
||||
begin
|
||||
busy = 1;
|
||||
EnableTimer = 1;
|
||||
if(LastCycle)
|
||||
ns = LOAD;
|
||||
else if(LastBit)
|
||||
begin
|
||||
data_strobe = 1;
|
||||
ns = IDLE;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
always_ff @(posedge clk)
|
||||
cs <= ns;endmodule
|
|
@ -0,0 +1,108 @@
|
|||
module tx #(parameter CLK_FREQUENCY = 100000000, BAUD_RATE = 19200)(
|
||||
input wire logic clk, send, odd,
|
||||
input wire logic[7:0] din,
|
||||
output logic busy, tx_out,
|
||||
output logic[4:0] state
|
||||
);
|
||||
logic EnableTimer, ResetTimer, LastCycle, LastBit, NextBit, ResetCounter,
|
||||
Shift, Load, ParityBit;
|
||||
localparam MAX_COUNT = CLK_FREQUENCY / BAUD_RATE;
|
||||
function integer clogb2;
|
||||
input [31:0] value;
|
||||
begin
|
||||
value = value - 1;
|
||||
for (clogb2 = 0; value > 0; clogb2 = clogb2 + 1) begin
|
||||
value = value >> 1;
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
localparam NUM_BITS = clogb2(MAX_COUNT);
|
||||
logic[NUM_BITS - 1:0] count = 0;
|
||||
|
||||
always_ff@ (posedge clk)
|
||||
begin
|
||||
if(ResetTimer || count == MAX_COUNT)
|
||||
count <= 0;
|
||||
else if(EnableTimer)
|
||||
count <= count + 1;
|
||||
end
|
||||
assign LastCycle = (count == MAX_COUNT) ? 1'b1:1'b0;
|
||||
|
||||
assign ParityBit = ((^din)^odd);
|
||||
|
||||
logic[3:0] countBit = 0;
|
||||
always_ff @(posedge clk)
|
||||
begin
|
||||
if(NextBit)
|
||||
countBit <= countBit + 1;
|
||||
else if(ResetCounter == 1'b1 || countBit == 4'd10)
|
||||
countBit <= 0;
|
||||
end
|
||||
assign LastBit = (countBit == 4'b1001) ? 1'b1:1'b0;
|
||||
|
||||
logic[9:0] shift = 10'b1111111111;
|
||||
always_ff @(posedge clk)
|
||||
begin
|
||||
if(Load)
|
||||
shift <= {ParityBit, din, 1'b0};
|
||||
else if(Shift)
|
||||
shift <= {1'b1, shift[9:1]};
|
||||
end
|
||||
assign tx_out = shift[0];
|
||||
|
||||
localparam Id = 5'b00001;
|
||||
localparam Lo = 5'b00010;
|
||||
localparam Co = 5'b00100;
|
||||
localparam Sh = 5'b01000;
|
||||
localparam Wa = 5'b10000;
|
||||
|
||||
logic [4:0] ns, cs=Id;
|
||||
assign state = cs;
|
||||
always_comb
|
||||
begin
|
||||
ns = cs;
|
||||
Load = 0;
|
||||
busy = 0;
|
||||
ResetCounter = 0;
|
||||
ResetTimer = 0;
|
||||
Shift = 0;
|
||||
ResetTimer = 0;
|
||||
NextBit = 0;
|
||||
EnableTimer =0;
|
||||
case(cs)
|
||||
Id:
|
||||
if(send)
|
||||
ns = Lo;
|
||||
Lo:
|
||||
begin
|
||||
Load = 1;
|
||||
busy = 1;
|
||||
ResetCounter = 1;
|
||||
ResetTimer = 1;
|
||||
ns = Co;
|
||||
end
|
||||
Co:
|
||||
begin
|
||||
busy = 1;
|
||||
EnableTimer = 1;
|
||||
if(LastCycle)
|
||||
ns = Sh;
|
||||
end
|
||||
Sh:begin
|
||||
Shift = 1;
|
||||
ResetTimer = 1;
|
||||
NextBit = 1;
|
||||
busy = 1;
|
||||
if(~LastBit)
|
||||
ns = Co;
|
||||
else
|
||||
ns = Wa;
|
||||
end
|
||||
Wa:
|
||||
if(~send)
|
||||
ns = Id;
|
||||
endcase
|
||||
end
|
||||
always_ff @(posedge clk)
|
||||
cs <= ns;
|
||||
endmodule
|
|
@ -0,0 +1,45 @@
|
|||
# Clock
|
||||
set_property -dict { PACKAGE_PIN W5 IOSTANDARD LVCMOS33 } [get_ports { clk }];
|
||||
create_clock -period 10.0 [get_ports {clk}]
|
||||
|
||||
# Buttons
|
||||
set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { btnc }];
|
||||
|
||||
# Switches
|
||||
set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }];
|
||||
set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }];
|
||||
set_property -dict { PACKAGE_PIN W16 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }];
|
||||
set_property -dict { PACKAGE_PIN W17 IOSTANDARD LVCMOS33 } [get_ports { sw[3] }];
|
||||
set_property -dict { PACKAGE_PIN W15 IOSTANDARD LVCMOS33 } [get_ports { sw[4] }];
|
||||
set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { sw[5] }];
|
||||
set_property -dict { PACKAGE_PIN W14 IOSTANDARD LVCMOS33 } [get_ports { sw[6] }];
|
||||
set_property -dict { PACKAGE_PIN W13 IOSTANDARD LVCMOS33 } [get_ports { sw[7] }];
|
||||
|
||||
|
||||
# LEDs
|
||||
set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { debugLED[0] }];
|
||||
set_property -dict { PACKAGE_PIN E19 IOSTANDARD LVCMOS33 } [get_ports { debugLED[1] }];
|
||||
set_property -dict { PACKAGE_PIN U19 IOSTANDARD LVCMOS33 } [get_ports { debugLED[2] }];
|
||||
set_property -dict { PACKAGE_PIN V19 IOSTANDARD LVCMOS33 } [get_ports { debugLED[3] }];
|
||||
set_property -dict { PACKAGE_PIN W18 IOSTANDARD LVCMOS33 } [get_ports { debugLED[4] }];
|
||||
|
||||
|
||||
# Seven Segment Display
|
||||
set_property -dict { PACKAGE_PIN W7 IOSTANDARD LVCMOS33 } [get_ports { segment[0] }];
|
||||
set_property -dict { PACKAGE_PIN W6 IOSTANDARD LVCMOS33 } [get_ports { segment[1] }];
|
||||
set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS33 } [get_ports { segment[2] }];
|
||||
set_property -dict { PACKAGE_PIN V8 IOSTANDARD LVCMOS33 } [get_ports { segment[3] }];
|
||||
set_property -dict { PACKAGE_PIN U5 IOSTANDARD LVCMOS33 } [get_ports { segment[4] }];
|
||||
set_property -dict { PACKAGE_PIN V5 IOSTANDARD LVCMOS33 } [get_ports { segment[5] }];
|
||||
set_property -dict { PACKAGE_PIN U7 IOSTANDARD LVCMOS33 } [get_ports { segment[6] }];
|
||||
set_property -dict { PACKAGE_PIN V7 IOSTANDARD LVCMOS33 } [get_ports { segment[7] }];
|
||||
set_property -dict { PACKAGE_PIN U2 IOSTANDARD LVCMOS33 } [get_ports { anode[0] }];
|
||||
set_property -dict { PACKAGE_PIN U4 IOSTANDARD LVCMOS33 } [get_ports { anode[1] }];
|
||||
set_property -dict { PACKAGE_PIN V4 IOSTANDARD LVCMOS33 } [get_ports { anode[2] }];
|
||||
set_property -dict { PACKAGE_PIN W4 IOSTANDARD LVCMOS33 } [get_ports { anode[3] }];
|
||||
|
||||
# UART
|
||||
set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 } [get_ports { rx_in }];
|
||||
set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { tx_out }];
|
||||
set_property -dict { PACKAGE_PIN J1 IOSTANDARD LVCMOS33 } [get_ports { tx_debug }];
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
module top(
|
||||
input wire logic clk, btnc, rx_in,
|
||||
input wire logic[7:0] sw,
|
||||
output logic[7:0] segment,
|
||||
output logic[3:0] anode,
|
||||
output logic tx_debug, tx_out,
|
||||
output logic[4:0] debugLED
|
||||
);
|
||||
logic rx_error, rx_debug;
|
||||
|
||||
logic busyByBy, tx_mid, send, btn[1:0];
|
||||
tx T0(.tx_out(tx_mid), .odd(1'b0), .busy(busyByBy), .din(sw), .clk(clk), .send(btn[1]),
|
||||
.state(debugLED));
|
||||
assign tx_out = tx_mid;
|
||||
assign tx_debug = tx_mid;
|
||||
|
||||
logic busyByByRx, dataGoner, btnRx[1:0];
|
||||
logic[7:0] rx_data;
|
||||
rx R0(.rx_in(rx_in), .odd(1'b0), .busy(busyByByRx), .data_strobe(dataGoner),
|
||||
.dout(rx_data), .error(rx_error), .clk(clk));
|
||||
assign rx_debug = rx_in;
|
||||
|
||||
SevenSegmentControl S1(.dataIn({rx_data[7:0],
|
||||
sw[7:0]}), .reset(0), .digitDisplay(4'hf), .digitPoint(4'h4), .anode(anode),
|
||||
.segment(segment), .clk(clk));
|
||||
always_ff @(posedge clk)
|
||||
btn[0] <= btnc;
|
||||
always_ff @(posedge clk)
|
||||
btn[1] <= btn[0];
|
||||
|
||||
endmodule
|
|
@ -6,7 +6,7 @@ demonstrates a PWM that drives the RGB leds on the board. To build this example
|
|||
commands:
|
||||
|
||||
.. code-block:: bash
|
||||
:name: example-watch-basys3
|
||||
:name: example-pulse-arty-35t
|
||||
|
||||
make -C pulse_width_led
|
||||
|
||||
|
|
Loading…
Reference in New Issue