commit bd773b88412e01ad66e4faaba09d364175cf35d5 Author: zhaohe Date: Wed Dec 13 10:53:13 2023 +0800 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..16ca7ee --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +sim/behav/work/_lib.qdb +generate_bitstream/ +pango_sim_libraries/ +sim/ +place_route/ +synthesize/ +compile/ +constraint_backup/ +device_map/logbackup/ +logbackup/ +log/ +pds.log +run.log +device_map/bak/ +device_map/ +report_timing/ +ipcore/ram/ram.idf diff --git a/impl.tcl b/impl.tcl new file mode 100644 index 0000000..9e654f4 --- /dev/null +++ b/impl.tcl @@ -0,0 +1,58 @@ +#Generated by Fabric Compiler ( version 2021.1-SP7 ) at Fri Dec 8 16:54:29 2023 + +add_design "D:/workspace/fpga_demo/led_test/source/led_test.v" +set_arch -family Logos -device PGL22G -speedgrade -6 -package MBG324 +compile -top_module led_test +add_constraint "D:/workspace/fpga_demo/led_test/led_test.fdc" +synthesize -ads -selected_syn_tool_opt 2 +dev_map +pnr +pnr +pnr +pnr +pnr +pnr +synthesize -ads -selected_syn_tool_opt 2 +dev_map +pnr +report_timing +gen_bit_stream +synthesize -ads -selected_syn_tool_opt 2 +dev_map +pnr +report_timing +gen_bit_stream +add_design D:/workspace/fpga_demo/led_test/ipcore/clk_wiz_0/clk_wiz_0.idf +add_design D:/workspace/fpga_demo/led_test/ipcore/ram/ram.idf +remove_design -force D:/workspace/fpga_demo/led_test/ipcore/clk_wiz_0/clk_wiz_0.idf +gen_bit_stream +gen_bit_stream +gen_bit_stream +gen_bit_stream +set_arch -family Logos -device PGL22G -speedgrade -6 -package MBG324 +compile -top_module led_test +synthesize -ads -selected_syn_tool_opt 2 +dev_map +pnr +report_timing +gen_bit_stream +set_arch -family Logos -device PGL22G -speedgrade -6 -package MBG324 +compile -top_module led_test +synthesize -ads -selected_syn_tool_opt 2 +dev_map +pnr +report_timing +gen_bit_stream +set_arch -family Logos -device PGL22G -speedgrade -6 -package MBG324 +compile -top_module led_test +set_arch -family Logos -device PGL22G -speedgrade -6 -package MBG324 +compile -top_module led_test +synthesize -ads -selected_syn_tool_opt 2 +dev_map +pnr +report_timing +gen_bit_stream +add_simulation "D:/workspace/fpga_demo/led_test/source/vtf_led.test.v" +remove_simulation -force "D:/workspace/fpga_demo/led_test/source/vtf_led.test.v" +add_simulation "D:/workspace/fpga_demo/led_test/source/test.v" +add_design "D:/workspace/fpga_demo/led_test/source/source/async.v" diff --git a/led_test.fdc b/led_test.fdc new file mode 100644 index 0000000..9a22682 --- /dev/null +++ b/led_test.fdc @@ -0,0 +1,60 @@ +#define_attribute {p:led[3]} {PAP_IO_DIRECTION} {OUTPUT} +#define_attribute {p:led[3]} {PAP_IO_LOC} {U12} +#define_attribute {p:led[3]} {PAP_IO_VCCIO} {3.3} +#define_attribute {p:led[3]} {PAP_IO_STANDARD} {LVCMOS33} +#define_attribute {p:led[3]} {PAP_IO_DRIVE} {4} +#define_attribute {p:led[3]} {PAP_IO_SLEW} {SLOW} +#define_attribute {p:led[2]} {PAP_IO_DIRECTION} {OUTPUT} +#define_attribute {p:led[2]} {PAP_IO_LOC} {B5} +#define_attribute {p:led[2]} {PAP_IO_VCCIO} {3.3} +#define_attribute {p:led[2]} {PAP_IO_STANDARD} {LVCMOS33} +#define_attribute {p:led[2]} {PAP_IO_DRIVE} {4} +#define_attribute {p:led[2]} {PAP_IO_SLEW} {SLOW} +#define_attribute {p:led[1]} {PAP_IO_DIRECTION} {OUTPUT} +#define_attribute {p:led[1]} {PAP_IO_LOC} {U10} +#define_attribute {p:led[1]} {PAP_IO_VCCIO} {3.3} +#define_attribute {p:led[1]} {PAP_IO_STANDARD} {LVCMOS33} +#define_attribute {p:led[1]} {PAP_IO_DRIVE} {4} +#define_attribute {p:led[1]} {PAP_IO_SLEW} {SLOW} +define_attribute {p:led[0]} {PAP_IO_DIRECTION} {OUTPUT} +define_attribute {p:led[0]} {PAP_IO_LOC} {U10} +define_attribute {p:led[0]} {PAP_IO_VCCIO} {3.3} +define_attribute {p:led[0]} {PAP_IO_STANDARD} {LVCMOS33} +define_attribute {p:led[0]} {PAP_IO_DRIVE} {4} +define_attribute {p:led[0]} {PAP_IO_SLEW} {SLOW} +#define_attribute {p:rst_n} {PAP_IO_DIRECTION} {INPUT} +#define_attribute {p:rst_n} {PAP_IO_LOC} {U11} +#define_attribute {p:rst_n} {PAP_IO_VCCIO} {3.3} +#define_attribute {p:rst_n} {PAP_IO_STANDARD} {LVTTL33} +#define_attribute {p:sys_clk} {PAP_IO_DIRECTION} {INPUT} +#define_attribute {p:sys_clk} {PAP_IO_LOC} {V11} +#define_attribute {p:sys_clk} {PAP_IO_VCCIO} {3.3} +#define_attribute {p:sys_clk} {PAP_IO_STANDARD} {LVTTL33} +define_attribute {p:led[3]} {PAP_IO_DIRECTION} {OUTPUT} +define_attribute {p:led[3]} {PAP_IO_LOC} {V11} +define_attribute {p:led[3]} {PAP_IO_VCCIO} {3.3} +define_attribute {p:led[3]} {PAP_IO_STANDARD} {LVCMOS33} +define_attribute {p:led[3]} {PAP_IO_DRIVE} {4} +define_attribute {p:led[3]} {PAP_IO_SLEW} {SLOW} +define_attribute {p:led[2]} {PAP_IO_DIRECTION} {OUTPUT} +define_attribute {p:led[2]} {PAP_IO_LOC} {U11} +define_attribute {p:led[2]} {PAP_IO_VCCIO} {3.3} +define_attribute {p:led[2]} {PAP_IO_STANDARD} {LVCMOS33} +define_attribute {p:led[2]} {PAP_IO_DRIVE} {4} +define_attribute {p:led[2]} {PAP_IO_SLEW} {SLOW} +define_attribute {p:led[1]} {PAP_IO_DIRECTION} {OUTPUT} +define_attribute {p:led[1]} {PAP_IO_LOC} {V10} +define_attribute {p:led[1]} {PAP_IO_VCCIO} {3.3} +define_attribute {p:led[1]} {PAP_IO_STANDARD} {LVCMOS33} +define_attribute {p:led[1]} {PAP_IO_DRIVE} {4} +define_attribute {p:led[1]} {PAP_IO_SLEW} {SLOW} +define_attribute {p:rst_n} {PAP_IO_DIRECTION} {INPUT} +define_attribute {p:rst_n} {PAP_IO_LOC} {U12} +define_attribute {p:rst_n} {PAP_IO_VCCIO} {3.3} +define_attribute {p:rst_n} {PAP_IO_STANDARD} {LVTTL33} +define_attribute {p:sys_clk} {PAP_IO_DIRECTION} {INPUT} +define_attribute {p:sys_clk} {PAP_IO_LOC} {B5} +define_attribute {p:sys_clk} {PAP_IO_VCCIO} {3.3} +define_attribute {p:sys_clk} {PAP_IO_STANDARD} {LVTTL33} +#create_clock -name {} -period {10.000} -waveform {0.000 5.000} +#define_attribute {p:sys_clk} {PAP_IO_HYS_DRIVE_MODE} {NOHYS} diff --git a/led_test.pds b/led_test.pds new file mode 100644 index 0000000..df26307 --- /dev/null +++ b/led_test.pds @@ -0,0 +1,249 @@ +(_flow fab_demo "2021.1-SP7" + (_comment "Generated by Fabric Compiler (version on 2021.1-SP7) at Wed Dec 13 10:46:05 2023") + (_version "1.0.5") + (_status "initial") + (_project + ) + (_task tsk_setup + (_widget wgt_select_arch + (_input + (_part + (_family Logos) + (_device PGL22G) + (_speedgrade -6) + (_package MBG324) + ) + ) + ) + (_widget wgt_my_design_src + (_input + (_file "source/led_test.v" + "led_test" + (_format verilog) + (_timespec "2023-12-12T18:38:54") + ) + (_file "source/source/async.v" + (_format verilog) + (_timespec "2023-12-13T10:42:04") + ) + ) + ) + (_widget wgt_my_ips_src + ) + (_widget wgt_import_logic_con_file + (_input + (_file "led_test.fdc" + (_format fdc) + (_timespec "2023-12-08T19:12:53") + ) + ) + ) + (_widget wgt_edit_user_cons + (_attribute _click_to_run (_switch ON)) + ) + (_widget wgt_simulation + (_input + (_file "source/test.v" + "vtf_led_test" + (_format verilog) + (_timespec "2023-12-12T18:47:34") + ) + ) + ) + ) + (_task tsk_compile + (_command cmd_compile + (_gci_state (_integer 3)) + (_db_output + (_file "compile/led_test_comp.adf" + (_format adif) + (_timespec "2023-12-12T18:39:06") + ) + ) + (_output + (_file "compile/led_test.cmr" + (_format verilog) + (_timespec "2023-12-12T18:39:06") + ) + (_file "compile/cmr.db" + (_format text) + (_timespec "2023-12-12T18:39:06") + ) + ) + ) + (_widget wgt_rtl_view + (_attribute _click_to_run (_switch ON)) + ) + ) + (_task tsk_synthesis + (_command cmd_synthesize + (_gci_state (_integer 3)) + (_option ads (_switch ON)) + (_option selected_syn_tool_opt (_integer 2)) + (_db_output + (_file "synthesize/led_test_syn.adf" + (_format adif) + (_timespec "2023-12-12T18:39:08") + ) + ) + (_output + (_file "synthesize/led_test_syn.vm" + (_format structural_verilog) + (_timespec "2023-12-12T18:39:08") + ) + (_file "synthesize/led_test.snr" + (_format text) + (_timespec "2023-12-12T18:39:08") + ) + (_file "synthesize/snr.db" + (_format text) + (_timespec "2023-12-12T18:39:09") + ) + ) + ) + (_widget wgt_tech_view + (_attribute _click_to_run (_switch ON)) + ) + (_widget wgt_map_constraint + ) + (_widget wgt_my_fic_src + ) + (_widget wgt_inserter_gui_view + (_attribute _click_to_run (_switch ON)) + ) + ) + (_task tsk_devmap + (_command cmd_devmap + (_gci_state (_integer 3)) + (_db_output + (_file "device_map/led_test_map.adf" + (_format adif) + (_timespec "2023-12-12T18:39:11") + ) + ) + (_output + (_file "device_map/led_test_dmr.prt" + (_format text) + (_timespec "2023-12-12T18:39:11") + ) + (_file "device_map/led_test.dmr" + (_format text) + (_timespec "2023-12-12T18:39:11") + ) + (_file "device_map/dmr.db" + (_format text) + (_timespec "2023-12-12T18:39:11") + ) + ) + ) + (_widget wgt_edit_placement_cons + (_attribute _click_to_run (_switch ON)) + (_input + (_file "device_map/led_test.pcf" + (_format pcf) + (_timespec "2023-12-12T18:39:11") + ) + ) + ) + (_widget wgt_edit_route_cons + (_attribute _click_to_run (_switch ON)) + ) + ) + (_task tsk_pnr + (_command cmd_pnr + (_gci_state (_integer 3)) + (_db_output + (_file "place_route/led_test_pnr.adf" + (_format adif) + (_timespec "2023-12-12T18:39:16") + ) + ) + (_output + (_file "place_route/led_test.prr" + (_format text) + (_timespec "2023-12-12T18:39:16") + ) + (_file "place_route/led_test_prr.prt" + (_format text) + (_timespec "2023-12-12T18:39:16") + ) + (_file "place_route/clock_utilization.txt" + (_format text) + (_timespec "2023-12-12T18:39:16") + ) + (_file "place_route/led_test_plc.adf" + (_format adif) + (_timespec "2023-12-12T18:39:15") + ) + (_file "place_route/led_test_pnr.netlist" + (_format text) + (_timespec "2023-12-12T18:39:16") + ) + (_file "place_route/prr.db" + (_format text) + (_timespec "2023-12-12T18:39:16") + ) + ) + ) + (_widget wgt_power_calculator + (_attribute _click_to_run (_switch ON)) + ) + (_widget wgt_timing_analysis + (_attribute _click_to_run (_switch ON)) + ) + (_command cmd_report_post_pnr_timing + (_gci_state (_integer 3)) + (_attribute _auto_exe_lock (_switch OFF)) + (_db_output + (_file "report_timing/led_test_rtp.adf" + (_format adif) + (_timespec "2023-12-12T18:39:19") + ) + ) + (_output + (_file "report_timing/led_test.rtr" + (_format text) + (_timespec "2023-12-12T18:39:19") + ) + (_file "report_timing/rtr.db" + (_format text) + (_timespec "2023-12-12T18:39:19") + ) + ) + ) + (_widget wgt_arch_browser + (_attribute _click_to_run (_switch ON)) + ) + (_command cmd_report_power + (_gci_state (_integer 0)) + (_attribute _auto_exe_lock (_switch OFF)) + (_attribute _auto_exe (_switch OFF)) + ) + (_command cmd_gen_netlist + (_gci_state (_integer 0)) + (_attribute _auto_exe_lock (_switch OFF)) + (_attribute _auto_exe (_switch OFF)) + ) + ) + (_task tsk_gen_bitstream + (_command cmd_gen_bitstream + (_gci_state (_integer 3)) + (_output + (_file "generate_bitstream/led_test.sbit" + (_format text) + (_timespec "2023-12-12T18:39:23") + ) + (_file "generate_bitstream/led_test.smsk" + (_format text) + (_timespec "2023-12-12T18:39:23") + ) + (_file "generate_bitstream/led_test.bgr" + (_format text) + (_timespec "2023-12-12T18:39:23") + ) + (_file "generate_bitstream/bgr.db" + (_format text) + (_timespec "2023-12-12T18:39:23") + ) + ) + ) + ) +) diff --git a/source/async.v b/source/async.v new file mode 100644 index 0000000..baba942 --- /dev/null +++ b/source/async.v @@ -0,0 +1,202 @@ +//////////////////////////////////////////////////////// +// RS-232 RX and TX module +// (c) fpga4fun.com & KNJN LLC - 2003 to 2016 + +// The RS-232 settings are fixed +// TX: 8-bit data, 2 stop, no-parity +// RX: 8-bit data, 1 stop, no-parity (the receiver can accept more stop bits of course) + +//`define SIMULATION // in this mode, TX outputs one bit per clock cycle + // and RX receives one bit per clock cycle (for fast simulations) + +//////////////////////////////////////////////////////// +module async_transmitter( + input clk, + input TxD_start, + input [7:0] TxD_data, + output TxD, + output TxD_busy +); + +// Assert TxD_start for (at least) one clock cycle to start transmission of TxD_data +// TxD_data is latched so that it doesn't have to stay valid while it is being sent + +parameter ClkFrequency = 50000000; // 50MHz +parameter Baud = 115200; + +generate + if(ClkFrequency> 1); + + case(TxD_state) + 4'b0000: if(TxD_start) TxD_state <= 4'b0100; + 4'b0100: if(BitTick) TxD_state <= 4'b1000; // start bit + 4'b1000: if(BitTick) TxD_state <= 4'b1001; // bit 0 + 4'b1001: if(BitTick) TxD_state <= 4'b1010; // bit 1 + 4'b1010: if(BitTick) TxD_state <= 4'b1011; // bit 2 + 4'b1011: if(BitTick) TxD_state <= 4'b1100; // bit 3 + 4'b1100: if(BitTick) TxD_state <= 4'b1101; // bit 4 + 4'b1101: if(BitTick) TxD_state <= 4'b1110; // bit 5 + 4'b1110: if(BitTick) TxD_state <= 4'b1111; // bit 6 + 4'b1111: if(BitTick) TxD_state <= 4'b0010; // bit 7 + 4'b0010: if(BitTick) TxD_state <= 4'b0011; // stop1 + 4'b0011: if(BitTick) TxD_state <= 4'b0000; // stop2 + default: if(BitTick) TxD_state <= 4'b0000; + endcase +end + +assign TxD = (TxD_state<4) | (TxD_state[3] & TxD_shift[0]); // put together the start, data and stop bits +endmodule + + +//////////////////////////////////////////////////////// +module async_receiver( + input clk, + input RxD, + output reg RxD_data_ready = 0, + output reg [7:0] RxD_data = 0, // data received, valid only (for one clock cycle) when RxD_data_ready is asserted + + // We also detect if a gap occurs in the received stream of characters + // That can be useful if multiple characters are sent in burst + // so that multiple characters can be treated as a "packet" + output RxD_idle, // asserted when no data has been received for a while + output reg RxD_endofpacket = 0 // asserted for one clock cycle when a packet has been detected (i.e. RxD_idle is going high) +); + +parameter ClkFrequency = 25000000; // 25MHz +parameter Baud = 115200; + +parameter Oversampling = 8; // needs to be a power of 2 +// we oversample the RxD line at a fixed rate to capture each RxD data bit at the "right" time +// 8 times oversampling by default, use 16 for higher quality reception + +generate + if(ClkFrequency>log2) log2=log2+1; end endfunction +localparam l2o = log2(Oversampling); +reg [l2o-2:0] OversamplingCnt = 0; +always @(posedge clk) if(OversamplingTick) OversamplingCnt <= (RxD_state==0) ? 1'd0 : OversamplingCnt + 1'd1; +wire sampleNow = OversamplingTick && (OversamplingCnt==Oversampling/2-1); +`endif + +// now we can accumulate the RxD bits in a shift-register +always @(posedge clk) +case(RxD_state) + 4'b0000: if(~RxD_bit) RxD_state <= `ifdef SIMULATION 4'b1000 `else 4'b0001 `endif; // start bit found? + 4'b0001: if(sampleNow) RxD_state <= 4'b1000; // sync start bit to sampleNow + 4'b1000: if(sampleNow) RxD_state <= 4'b1001; // bit 0 + 4'b1001: if(sampleNow) RxD_state <= 4'b1010; // bit 1 + 4'b1010: if(sampleNow) RxD_state <= 4'b1011; // bit 2 + 4'b1011: if(sampleNow) RxD_state <= 4'b1100; // bit 3 + 4'b1100: if(sampleNow) RxD_state <= 4'b1101; // bit 4 + 4'b1101: if(sampleNow) RxD_state <= 4'b1110; // bit 5 + 4'b1110: if(sampleNow) RxD_state <= 4'b1111; // bit 6 + 4'b1111: if(sampleNow) RxD_state <= 4'b0010; // bit 7 + 4'b0010: if(sampleNow) RxD_state <= 4'b0000; // stop bit + default: RxD_state <= 4'b0000; +endcase + +always @(posedge clk) +if(sampleNow && RxD_state[3]) RxD_data <= {RxD_bit, RxD_data[7:1]}; + +//reg RxD_data_error = 0; +always @(posedge clk) +begin + RxD_data_ready <= (sampleNow && RxD_state==4'b0010 && RxD_bit); // make sure a stop bit is received + //RxD_data_error <= (sampleNow && RxD_state==4'b0010 && ~RxD_bit); // error if a stop bit is not received +end + +`ifdef SIMULATION +assign RxD_idle = 0; +`else +reg [l2o+1:0] GapCnt = 0; +always @(posedge clk) if (RxD_state!=0) GapCnt<=0; else if(OversamplingTick & ~GapCnt[log2(Oversampling)+1]) GapCnt <= GapCnt + 1'h1; +assign RxD_idle = GapCnt[l2o+1]; +always @(posedge clk) RxD_endofpacket <= OversamplingTick & ~GapCnt[l2o+1] & &GapCnt[l2o:0]; +`endif + +endmodule + + +//////////////////////////////////////////////////////// +// dummy module used to be able to raise an assertion in Verilog +module ASSERTION_ERROR(); +endmodule + + +//////////////////////////////////////////////////////// +module BaudTickGen( + input clk, enable, + output tick // generate a tick at the specified baud rate * oversampling +); +parameter ClkFrequency = 25000000; +parameter Baud = 115200; +parameter Oversampling = 1; + +function integer log2(input integer v); begin log2=0; while(v>>log2) log2=log2+1; end endfunction +localparam AccWidth = log2(ClkFrequency/Baud)+8; // +/- 2% max timing error over a byte +reg [AccWidth:0] Acc = 0; +localparam ShiftLimiter = log2(Baud*Oversampling >> (31-AccWidth)); // this makes sure Inc calculation doesn't overflow +localparam Inc = ((Baud*Oversampling << (AccWidth-ShiftLimiter))+(ClkFrequency>>(ShiftLimiter+1)))/(ClkFrequency>>ShiftLimiter); +always @(posedge clk) if(enable) Acc <= Acc[AccWidth-1:0] + Inc[AccWidth:0]; else Acc <= Inc[AccWidth:0]; +assign tick = Acc[AccWidth]; +endmodule + + +//////////////////////////////////////////////////////// diff --git a/source/led_test.v b/source/led_test.v new file mode 100644 index 0000000..ef50315 --- /dev/null +++ b/source/led_test.v @@ -0,0 +1,44 @@ +`timescale 1ns/1ns +module led_test +( + sys_clk, // system clock 50Mhz on board + rst_n, // reset ,low active + led // LED,use for control the LED signal on board + ); + +input sys_clk; +input rst_n; +output [3:0] led; + +//define the time counter +reg [31:0] timer; +reg [3:0] led; + + + always @(posedge sys_clk or negedge rst_n) + begin + if (~rst_n) + timer <= 32'd0; // when the reset signal valid,time counter clearing + else if (timer == 32'd199_9999_9) //4 seconds count(50M*4-1=199999999) + timer <= 32'd0; //count done,clearing the time counter + else + timer <= timer + 1'b1; //timer counter = timer counter + 1 + end + + always @(posedge sys_clk or negedge rst_n) + begin + if (~rst_n) + led <= 4'b0000; //when the reset signal active + else if (timer == 32'd49_999_9) //time counter count to 1st sec,LED1 Extinguish + led <= 4'b0001; + else if (timer == 32'd99_999_9) //time counter count to 2nd sec,LED2 Extinguish + begin + led <= 4'b0010; + end + else if (timer == 32'd149_999_9) //time counter count to 3nd sec,LED3 Extinguish + led <= 4'b0100; + else if (timer == 32'd199_999_9) //time counter count to 4nd sec,LED4 Extinguish + led <= 4'b1000; + end + +endmodule diff --git a/source/source/async.v b/source/source/async.v new file mode 100644 index 0000000..baba942 --- /dev/null +++ b/source/source/async.v @@ -0,0 +1,202 @@ +//////////////////////////////////////////////////////// +// RS-232 RX and TX module +// (c) fpga4fun.com & KNJN LLC - 2003 to 2016 + +// The RS-232 settings are fixed +// TX: 8-bit data, 2 stop, no-parity +// RX: 8-bit data, 1 stop, no-parity (the receiver can accept more stop bits of course) + +//`define SIMULATION // in this mode, TX outputs one bit per clock cycle + // and RX receives one bit per clock cycle (for fast simulations) + +//////////////////////////////////////////////////////// +module async_transmitter( + input clk, + input TxD_start, + input [7:0] TxD_data, + output TxD, + output TxD_busy +); + +// Assert TxD_start for (at least) one clock cycle to start transmission of TxD_data +// TxD_data is latched so that it doesn't have to stay valid while it is being sent + +parameter ClkFrequency = 50000000; // 50MHz +parameter Baud = 115200; + +generate + if(ClkFrequency> 1); + + case(TxD_state) + 4'b0000: if(TxD_start) TxD_state <= 4'b0100; + 4'b0100: if(BitTick) TxD_state <= 4'b1000; // start bit + 4'b1000: if(BitTick) TxD_state <= 4'b1001; // bit 0 + 4'b1001: if(BitTick) TxD_state <= 4'b1010; // bit 1 + 4'b1010: if(BitTick) TxD_state <= 4'b1011; // bit 2 + 4'b1011: if(BitTick) TxD_state <= 4'b1100; // bit 3 + 4'b1100: if(BitTick) TxD_state <= 4'b1101; // bit 4 + 4'b1101: if(BitTick) TxD_state <= 4'b1110; // bit 5 + 4'b1110: if(BitTick) TxD_state <= 4'b1111; // bit 6 + 4'b1111: if(BitTick) TxD_state <= 4'b0010; // bit 7 + 4'b0010: if(BitTick) TxD_state <= 4'b0011; // stop1 + 4'b0011: if(BitTick) TxD_state <= 4'b0000; // stop2 + default: if(BitTick) TxD_state <= 4'b0000; + endcase +end + +assign TxD = (TxD_state<4) | (TxD_state[3] & TxD_shift[0]); // put together the start, data and stop bits +endmodule + + +//////////////////////////////////////////////////////// +module async_receiver( + input clk, + input RxD, + output reg RxD_data_ready = 0, + output reg [7:0] RxD_data = 0, // data received, valid only (for one clock cycle) when RxD_data_ready is asserted + + // We also detect if a gap occurs in the received stream of characters + // That can be useful if multiple characters are sent in burst + // so that multiple characters can be treated as a "packet" + output RxD_idle, // asserted when no data has been received for a while + output reg RxD_endofpacket = 0 // asserted for one clock cycle when a packet has been detected (i.e. RxD_idle is going high) +); + +parameter ClkFrequency = 25000000; // 25MHz +parameter Baud = 115200; + +parameter Oversampling = 8; // needs to be a power of 2 +// we oversample the RxD line at a fixed rate to capture each RxD data bit at the "right" time +// 8 times oversampling by default, use 16 for higher quality reception + +generate + if(ClkFrequency>log2) log2=log2+1; end endfunction +localparam l2o = log2(Oversampling); +reg [l2o-2:0] OversamplingCnt = 0; +always @(posedge clk) if(OversamplingTick) OversamplingCnt <= (RxD_state==0) ? 1'd0 : OversamplingCnt + 1'd1; +wire sampleNow = OversamplingTick && (OversamplingCnt==Oversampling/2-1); +`endif + +// now we can accumulate the RxD bits in a shift-register +always @(posedge clk) +case(RxD_state) + 4'b0000: if(~RxD_bit) RxD_state <= `ifdef SIMULATION 4'b1000 `else 4'b0001 `endif; // start bit found? + 4'b0001: if(sampleNow) RxD_state <= 4'b1000; // sync start bit to sampleNow + 4'b1000: if(sampleNow) RxD_state <= 4'b1001; // bit 0 + 4'b1001: if(sampleNow) RxD_state <= 4'b1010; // bit 1 + 4'b1010: if(sampleNow) RxD_state <= 4'b1011; // bit 2 + 4'b1011: if(sampleNow) RxD_state <= 4'b1100; // bit 3 + 4'b1100: if(sampleNow) RxD_state <= 4'b1101; // bit 4 + 4'b1101: if(sampleNow) RxD_state <= 4'b1110; // bit 5 + 4'b1110: if(sampleNow) RxD_state <= 4'b1111; // bit 6 + 4'b1111: if(sampleNow) RxD_state <= 4'b0010; // bit 7 + 4'b0010: if(sampleNow) RxD_state <= 4'b0000; // stop bit + default: RxD_state <= 4'b0000; +endcase + +always @(posedge clk) +if(sampleNow && RxD_state[3]) RxD_data <= {RxD_bit, RxD_data[7:1]}; + +//reg RxD_data_error = 0; +always @(posedge clk) +begin + RxD_data_ready <= (sampleNow && RxD_state==4'b0010 && RxD_bit); // make sure a stop bit is received + //RxD_data_error <= (sampleNow && RxD_state==4'b0010 && ~RxD_bit); // error if a stop bit is not received +end + +`ifdef SIMULATION +assign RxD_idle = 0; +`else +reg [l2o+1:0] GapCnt = 0; +always @(posedge clk) if (RxD_state!=0) GapCnt<=0; else if(OversamplingTick & ~GapCnt[log2(Oversampling)+1]) GapCnt <= GapCnt + 1'h1; +assign RxD_idle = GapCnt[l2o+1]; +always @(posedge clk) RxD_endofpacket <= OversamplingTick & ~GapCnt[l2o+1] & &GapCnt[l2o:0]; +`endif + +endmodule + + +//////////////////////////////////////////////////////// +// dummy module used to be able to raise an assertion in Verilog +module ASSERTION_ERROR(); +endmodule + + +//////////////////////////////////////////////////////// +module BaudTickGen( + input clk, enable, + output tick // generate a tick at the specified baud rate * oversampling +); +parameter ClkFrequency = 25000000; +parameter Baud = 115200; +parameter Oversampling = 1; + +function integer log2(input integer v); begin log2=0; while(v>>log2) log2=log2+1; end endfunction +localparam AccWidth = log2(ClkFrequency/Baud)+8; // +/- 2% max timing error over a byte +reg [AccWidth:0] Acc = 0; +localparam ShiftLimiter = log2(Baud*Oversampling >> (31-AccWidth)); // this makes sure Inc calculation doesn't overflow +localparam Inc = ((Baud*Oversampling << (AccWidth-ShiftLimiter))+(ClkFrequency>>(ShiftLimiter+1)))/(ClkFrequency>>ShiftLimiter); +always @(posedge clk) if(enable) Acc <= Acc[AccWidth-1:0] + Inc[AccWidth:0]; else Acc <= Inc[AccWidth:0]; +assign tick = Acc[AccWidth]; +endmodule + + +//////////////////////////////////////////////////////// diff --git a/source/test.v b/source/test.v new file mode 100644 index 0000000..3828628 --- /dev/null +++ b/source/test.v @@ -0,0 +1,35 @@ +`timescale 1ns / 1ns +////////////////////////////////////////////////////////////////////////////////// +// Module Name: vtf_led_test +////////////////////////////////////////////////////////////////////////////////// + +module vtf_led_test; + // Inputs + reg sys_clk; + reg rst_n; + + // Outputs + wire [3:0] led; + + // Instantiate the Unit Under Test (UUT) + led_test uut ( + .sys_clk(sys_clk), + .rst_n(rst_n), + .led(led) + ); + + initial begin + // Initialize Inputs + sys_clk = 0; + rst_n = 0; + + // Wait 100 ns for global reset to finish + #1000; + rst_n = 1; + // Add stimulus here + #20000; + // $stop; + end + + always #10 sys_clk = ~ sys_clk; //20ns +endmodule