├── .gitattributes ├── .gitignore ├── README.md ├── add_w_carry.v ├── adder.v ├── bin_to_bcd.v ├── counters.v ├── ddr ├── ddr3.v ├── ddr3.vh ├── ddr3 │ ├── ddr3.v │ ├── ddr3_doc.pdf │ ├── ddr3_glue.v │ ├── ddr3_top.v │ ├── doc │ │ ├── ddr3_doc.docx │ │ ├── usercontentimg1351221506.png │ │ └── usercontentimg1351223336.jpg │ ├── system.ucf │ └── unmodifyed │ │ └── ddr3.v ├── ddr3_core.v ├── memparts.csv └── memports.csv ├── divider.v ├── encryption_cores └── keccak.v ├── fft.v ├── flipflop.v ├── i2c.v ├── i2c_simulation.v ├── memory.v ├── multiplyer.v ├── pmods.vh ├── serdes.v ├── spi_master.v ├── string.v ├── uart_implementation.v ├── uart_rx.v ├── uart_simulation.v ├── uart_tx.v ├── util.v └── xmega_core ├── core1ROM.mem ├── core1ROMsym.mem ├── io ├── io.v ├── io_i2c.v ├── io_spi.v ├── io_uart.v └── pio.v ├── mega_alu.v ├── mega_alu_h.v ├── mega_core.v ├── mega_core_cfg_h.v ├── mega_core_h.v ├── mega_regs.v ├── sim_uc.v └── top_uc.v /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VerilogUtilIP 2 | 3 | # The project has been moved here https://git.morgothdisk.com/explore/projects 4 | 5 | Here is a bunch of util IPs 6 | 7 | All IPs from this project are licensed under GPL license until othervice is specified. 8 | -------------------------------------------------------------------------------- /add_w_carry.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This IP is the synthetizable adder with carry in implementation. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | `timescale 1ns / 1ps 22 | 23 | module add_w_carry # ( 24 | parameter WIDTH = 8)( 25 | input c_in, 26 | input [WIDTH-1:0]in_1, 27 | input [WIDTH-1:0]in_2, 28 | output [WIDTH-1:0]out, 29 | output c_out 30 | ); 31 | wire [WIDTH-1:0]carry; 32 | wire [WIDTH-1:0]p; 33 | wire [WIDTH-1:0]r; 34 | wire [WIDTH-1:0]s; 35 | assign c_out = carry[WIDTH-1]; 36 | genvar count_generate; 37 | generate 38 | for (count_generate = 0; count_generate < WIDTH; count_generate = count_generate + 1) 39 | begin: ADD 40 | xor (p[count_generate], in_1[count_generate], in_2[count_generate]); 41 | xor (out[count_generate], p[count_generate], count_generate ? carry[count_generate - 1] : c_in); 42 | 43 | and(r[count_generate], p[count_generate], count_generate ? carry[count_generate - 1] : c_in); 44 | and(s[count_generate], in_1[count_generate], in_2[count_generate]); 45 | or(carry[count_generate], r[count_generate], s[count_generate]); 46 | 47 | end 48 | endgenerate 49 | endmodule 50 | -------------------------------------------------------------------------------- /adder.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This IP is the synthetizable adder implementation. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | `timescale 1ns / 1ps 22 | 23 | module half_adder( 24 | input A, 25 | input B, 26 | output S, 27 | output C 28 | ); 29 | //Implement the Sum and Carry equations using Verilog Bit operators. 30 | assign S = A ^ B; //XOR operation 31 | assign C = A & B; //AND operation 32 | 33 | endmodule 34 | 35 | 36 | module full_adder( 37 | input A, //input A 38 | input B, //input B 39 | input C, //input C 40 | output Sum, 41 | output Carry 42 | ); 43 | 44 | //Internal variables 45 | wire ha1_sum; 46 | wire ha2_sum; 47 | wire ha1_carry; 48 | wire ha2_carry; 49 | wire Data_out_Sum; 50 | wire Data_out_Carry; 51 | 52 | //Instantiate the half adder 1 53 | half_adder ha1( 54 | .A(A), 55 | .B(B), 56 | .S(ha1_sum), 57 | .C(ha1_carry) 58 | ); 59 | 60 | //Instantiate the half adder 2 61 | half_adder ha2( 62 | .A(C), 63 | .B(ha1_sum), 64 | .S(ha2_sum), 65 | .C(ha2_carry) 66 | ); 67 | //sum output from 2nd half adder is connected to full adder output 68 | assign Sum = ha2_sum; 69 | //The carry's from both the half adders are OR'ed to get the final carry./ 70 | assign Carry = ha1_carry | ha2_carry; 71 | 72 | endmodule 73 | -------------------------------------------------------------------------------- /bin_to_bcd.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 08/15/2017 07:47:10 PM 7 | // Design Name: 8 | // Module Name: bin_to_bcd. 9 | // Project Name: Bin_To_Bcd IP. 10 | // Target Devices: All 11 | // Tool Versions: 12 | // Description: This is a bin_to_bcd IP library. 13 | // 14 | // Dependencies: None 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | module add3(in,out); 23 | input [3:0] in; 24 | output [3:0] out; 25 | reg [3:0] out; 26 | 27 | always @ (in) 28 | case (in) 29 | 4'b0000: out <= 4'b0000; 30 | 4'b0001: out <= 4'b0001; 31 | 4'b0010: out <= 4'b0010; 32 | 4'b0011: out <= 4'b0011; 33 | 4'b0100: out <= 4'b0100; 34 | 4'b0101: out <= 4'b1000; 35 | 4'b0110: out <= 4'b1001; 36 | 4'b0111: out <= 4'b1010; 37 | 4'b1000: out <= 4'b1011; 38 | 4'b1001: out <= 4'b1100; 39 | default: out <= 4'b0000; 40 | endcase 41 | endmodule 42 | 43 | 44 | module bin_to_bcd( 45 | input [7:0] in, 46 | output [3:0] ones, tens, 47 | output [1:0] hundreds 48 | ); 49 | 50 | wire [3:0] c1,c2,c3,c4,c5,c6,c7; 51 | wire [3:0] d1,d2,d3,d4,d5,d6,d7; 52 | 53 | assign d1 = {1'b0,in[7:5]}; 54 | assign d2 = {c1[2:0],in[4]}; 55 | assign d3 = {c2[2:0],in[3]}; 56 | assign d4 = {c3[2:0],in[2]}; 57 | assign d5 = {c4[2:0],in[1]}; 58 | assign d6 = {1'b0,c1[3],c2[3],c3[3]}; 59 | assign d7 = {c6[2:0],c4[3]}; 60 | add3 m1(d1,c1); 61 | add3 m2(d2,c2); 62 | add3 m3(d3,c3); 63 | add3 m4(d4,c4); 64 | add3 m5(d5,c5); 65 | add3 m6(d6,c6); 66 | add3 m7(d7,c7); 67 | assign ones = {c5[2:0],in[0]}; 68 | assign tens = {c7[2:0],c5[3]}; 69 | assign hundreds = {c6[3],c7[3]}; 70 | endmodule 71 | -------------------------------------------------------------------------------- /counters.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This IP is the synthetizable synchronous counters implementation. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | `timescale 1ns / 1ps 22 | 23 | module clk_div #(parameter WIDTH = 2)( 24 | input rst, 25 | input clk_in, 26 | input [WIDTH-1:0]divider, 27 | output clk_out 28 | ); 29 | reg [WIDTH-1:0]q; 30 | wire [WIDTH-1:0]pos_edge_loader = divider[WIDTH-1:1] + divider[0]; 31 | wire [WIDTH-1:0]neg_edge_loader = divider[WIDTH-1:1]; 32 | reg clk_out_int1; 33 | reg clk_out_int2; 34 | 35 | assign clk_out = (divider == 0) ? clk_in : 36 | (divider == 1) ? clk_out_int1 : clk_out_int2; 37 | 38 | always @ (posedge clk_in) 39 | begin 40 | if(rst) 41 | begin 42 | q <= {WIDTH{1'b0}}; 43 | clk_out_int1 <= 1'b0; 44 | clk_out_int2 <= 1'b0; 45 | end 46 | else if(divider == 1) clk_out_int1 <= ~clk_out_int1; 47 | else if(divider > 1) 48 | begin 49 | if(!q) 50 | begin 51 | q <= divider; 52 | clk_out_int2 <= ~clk_out_int2; 53 | end 54 | else 55 | q <= q - 1; 56 | end 57 | end 58 | 59 | endmodule 60 | 61 | module count_up #(parameter WIDTH = 2)( 62 | input rst, 63 | input clk, 64 | output reg[WIDTH-1:0]out 65 | ); 66 | 67 | always @ (negedge clk) 68 | begin 69 | if(rst) 70 | out <= {WIDTH{1'b0}}; 71 | else 72 | out <= out + 1; 73 | end 74 | endmodule 75 | 76 | module count_dn #(parameter WIDTH = 2)( 77 | input rst, 78 | input clk, 79 | output reg[WIDTH-1:0]out 80 | ); 81 | 82 | always @ (posedge clk) 83 | begin 84 | if(rst) 85 | out <= {WIDTH{1'b0}}; 86 | else 87 | out <= out - 1; 88 | end 89 | endmodule 90 | 91 | module count_up_ld #(parameter WIDTH = 2)( 92 | input rst, 93 | input clk, 94 | input load, 95 | input [WIDTH-1:0]value, 96 | output reg[WIDTH-1:0]out 97 | ); 98 | 99 | always @ (negedge clk) 100 | begin 101 | if(rst) 102 | out <= {WIDTH{1'b0}}; 103 | else if(load) 104 | out <= value; 105 | else 106 | out <= out + 1; 107 | end 108 | endmodule 109 | 110 | module count_dn_ld #(parameter WIDTH = 2)( 111 | input rst, 112 | input clk, 113 | input load, 114 | input [WIDTH-1:0]value, 115 | output reg[WIDTH-1:0]out 116 | ); 117 | 118 | always @ (posedge clk) 119 | begin 120 | if(rst) 121 | out <= {WIDTH{1'b0}}; 122 | else if(load) 123 | out <= value; 124 | else 125 | out <= out - 1; 126 | end 127 | endmodule 128 | 129 | module count_up_dn_ld #(parameter WIDTH = 2)( 130 | input rst, 131 | input clk, 132 | input dir, 133 | input load, 134 | input [WIDTH-1:0]value, 135 | output reg[WIDTH-1:0]out 136 | ); 137 | 138 | always @ (posedge dir ? ~clk : clk) 139 | begin 140 | if(rst) 141 | out <= {WIDTH{1'b0}}; 142 | else if(load) 143 | out <= value; 144 | else if(dir) 145 | out <= out + 1; 146 | else 147 | out <= out - 1; 148 | end 149 | endmodule 150 | 151 | module count_up_dn #(parameter WIDTH = 2)( 152 | input rst, 153 | input clk, 154 | input dir, 155 | input [WIDTH-1:0]value, 156 | output reg[WIDTH-1:0]out 157 | ); 158 | 159 | always @ (posedge dir ? ~clk : clk) 160 | begin 161 | if(rst) 162 | out <= {WIDTH{1'b0}}; 163 | else if(dir) 164 | out <= out + 1; 165 | else 166 | out <= out - 1; 167 | end 168 | endmodule 169 | -------------------------------------------------------------------------------- /ddr/ddr3.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This IP is the DDR3 implementation. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | `timescale 1ns / 1ps 22 | 23 | module ddr3 # ( 24 | parameter D_BUS_WIDTH = 16 25 | )( 26 | input rst, 27 | input clk, 28 | input clk90, 29 | input clkdiv, 30 | 31 | output [(D_BUS_WIDTH / 8) - 1:0]ddr3_dm_out, 32 | 33 | input [D_BUS_WIDTH - 1:0]ddr3_dq_in, 34 | output [D_BUS_WIDTH - 1:0]ddr3_dq_out, 35 | output ddr3_dq_oe, 36 | 37 | output [13:0]ddr3_addr_out, 38 | 39 | input [(D_BUS_WIDTH / 8) - 1:0]ddr3_dqs_in, 40 | output [1:0]ddr3_dqs_out, 41 | output ddr3_dqs_oe, 42 | 43 | output ddr3_ck_out, 44 | output ddr3_ck_oe, 45 | 46 | output ddr3_odt_out, 47 | output [2:0]ddr3_ba_out, 48 | output ddr3_cke_out, 49 | output ddr3_ras_out, 50 | output ddr3_cas_out, 51 | output ddr3_we_out, 52 | output ddr3_cs_out, 53 | output ddr3_reset_out 54 | ); 55 | 56 | assign ddr3_ck_out = ~clk90; 57 | /**********************************************************************************************************/ 58 | wire oserdes_oe; 59 | reg [3:0]oserdes_mask; 60 | reg ioserdes_clk_en; 61 | wire [(D_BUS_WIDTH * 8) - 1:0]pdata_out; 62 | wire [(D_BUS_WIDTH * 8) - 1:0]pdata_in; 63 | /**********************************************************************************************************/ 64 | genvar count; 65 | 66 | wire [D_BUS_WIDTH - 1:0]dq_in_ready; 67 | wire [D_BUS_WIDTH - 1:0]dq_out_busy; 68 | wire ddr3_pdata_write; 69 | wire ddr3_dq_receiver_en; 70 | generate 71 | for(count = 0; count < D_BUS_WIDTH; count = count + 1) 72 | begin : DQ_DES 73 | ddr_iserdes #( 74 | .DATA_RATE("DDR"), 75 | .DATA_WIDTH(8) 76 | )ddr_iserdes_dq_inst( 77 | .rst(rst), 78 | .clk(ddr3_dqs_in[count / 8]), 79 | .rec_en(ddr3_dq_receiver_en), 80 | .s_in(ddr3_dq_in), 81 | .data_rec({pdata_out[count + (D_BUS_WIDTH * 7)], pdata_out[count + (D_BUS_WIDTH * 6)], pdata_out[count+ (D_BUS_WIDTH * 5)], pdata_out[count + (D_BUS_WIDTH * 4)], 82 | pdata_out[count + (D_BUS_WIDTH * 3)], pdata_out[count + (D_BUS_WIDTH * 2)], pdata_out[count + (D_BUS_WIDTH * 1)], pdata_out[count]}), 83 | .ready(dq_in_ready[count]) 84 | ); 85 | end 86 | 87 | for(count = 0; count < D_BUS_WIDTH; count = count + 1) 88 | begin : DQ_SER 89 | ddr_oserdes #( 90 | .DATA_RATE("DDR"), 91 | .DATA_WIDTH(8) 92 | )ddr_oserdes_dq_inst( 93 | .rst(rst), 94 | .clk(clk), 95 | .write(ddr3_pdata_write), 96 | .s_out(ddr3_dq_out), 97 | .data_send({pdata_in[count + (D_BUS_WIDTH * 7)], pdata_in[count + (D_BUS_WIDTH * 6)], pdata_in[count+ (D_BUS_WIDTH * 5)], pdata_in[count + (D_BUS_WIDTH * 4)], 98 | pdata_in[count + (D_BUS_WIDTH * 3)], pdata_in[count + (D_BUS_WIDTH * 2)], pdata_in[count + (D_BUS_WIDTH * 1)], pdata_in[count]}), 99 | .ck_en_out(), 100 | .busy_sig(dq_out_busy[count]) 101 | ); 102 | end 103 | endgenerate 104 | 105 | ddr3_core ddr3_core_inst( 106 | .rst(rst), 107 | .clk(clk), 108 | .clk90(clk90), 109 | .clkdiv(clkdiv), 110 | 111 | .ddr3_dm_out(ddr3_dm_out), 112 | 113 | .ddr3_pdata_in(pdata_out), 114 | .ddr3_pdata_out(pdata_in), 115 | .ddr3_dq_oe(ddr3_dq_oe), 116 | .ddr3_pdata_write(ddr3_pdata_write), 117 | .ddr3_dq_receiver_en(ddr3_dq_receiver_en), 118 | 119 | .ddr3_dqs_in(ddr3_dqs_in), 120 | .ddr3_dqs_out(ddr3_dqs_out), 121 | .ddr3_dqs_oe(ddr3_dqs_oe), 122 | 123 | .ddr3_addr_out(ddr3_addr_out), 124 | 125 | .ddr3_ck_oe(ddr3_ck_oe), 126 | 127 | .ddr3_odt_out(ddr3_odt_out), 128 | .ddr3_ba_out(ddr3_ba_out), 129 | .ddr3_cke_out(ddr3_cke_out), 130 | .ddr3_ras_out(ddr3_ras_out), 131 | .ddr3_cas_out(ddr3_cas_out), 132 | .ddr3_we_out(ddr3_we_out), 133 | .ddr3_cs_out(ddr3_cs_out), 134 | .ddr3_reset_out(ddr3_reset_out) 135 | ); 136 | endmodule 137 | -------------------------------------------------------------------------------- /ddr/ddr3.vh: -------------------------------------------------------------------------------- 1 | /* 2 | * This IP is the DDR3 header declarations. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | `define DDR3_TOP \ 22 | output [1:0]ddr3_dm, \ 23 | inout [15:0]ddr3_dq, \ 24 | inout [13:0]ddr3_addr, \ 25 | output [1:0]ddr3_dqs_p, \ 26 | output [1:0]ddr3_dqs_n, \ 27 | output [0:0]ddr3_ck_p, \ 28 | output [0:0]ddr3_ck_n, \ 29 | output [2:0]ddr3_ba, \ 30 | output [0:0]ddr3_odt, \ 31 | output [0:0]ddr3_cke, \ 32 | output ddr3_ras_n, \ 33 | output ddr3_cas_n, \ 34 | output ddr3_we_n, \ 35 | output ddr3_cs_n, \ 36 | output ddr3_reset_n 37 | 38 | `define DDR3_IO \ 39 | \ 40 | wire [1:0]ddr3_dm_out; \ 41 | \ 42 | wire [15:0]ddr3_dq_in; \ 43 | wire [15:0]ddr3_dq_out; \ 44 | wire ddr3_dq_oe; \ 45 | \ 46 | wire [13:0]ddr3_addr_out; \ 47 | \ 48 | wire [1:0]ddr3_dqs_in; \ 49 | wire [1:0]ddr3_dqs_out; \ 50 | wire ddr3_dqs_oe; \ 51 | \ 52 | wire ddr3_ck_out; \ 53 | wire ddr3_ck_oe; \ 54 | \ 55 | wire ddr3_odt_out; \ 56 | \ 57 | wire [2:0]ddr3_ba_out; \ 58 | \ 59 | wire ddr3_cke_out; \ 60 | \ 61 | wire ddr3_ras_out; \ 62 | \ 63 | wire ddr3_cas_out; \ 64 | \ 65 | wire ddr3_we_out; \ 66 | \ 67 | wire ddr3_cs_out; \ 68 | \ 69 | wire ddr3_reset_out; \ 70 | \ 71 | OBUF #( \ 72 | .DRIVE(12), // Specify the output drive strength \ 73 | .SLEW("FAST") // Specify the output slew rate \ 74 | ) OBUF_DM_inst [1:0]( \ 75 | .O(ddr3_dm), // Buffer output (connect directly to top-level port) \ 76 | .I(ddr3_dm_out) // Buffer input \ 77 | ); \ 78 | \ 79 | IOBUF #( \ 80 | .DRIVE(12), // Specify the output drive strength \ 81 | .IBUF_LOW_PWR("FALSE"), // Low Power - "TRUE", High Performance = "FALSE" \ 82 | .SLEW("FAST") // Specify the output slew rate \ 83 | ) IOBUF_DQ_inst [15:0]( \ 84 | .O(ddr3_dq_in), // Buffer output \ 85 | .IO(ddr3_dq), // Buffer inout port (connect directly to top-level port) \ 86 | .I(ddr3_dq_out), // Buffer input \ 87 | .T({16{~ddr3_dq_oe}}) // 3-state enable input, high=input, low=output \ 88 | ); \ 89 | \ 90 | OBUF #(.SLEW("FAST")) OBUF_ADDR_inst [13:0]( \ 91 | .O(ddr3_addr), // Buffer output (connect directly to top-level port) \ 92 | .I(ddr3_addr_out) // Buffer input \ 93 | ); \ 94 | \ 95 | IOBUFDS #( \ 96 | .DIFF_TERM("TRUE"), // Differential Termination ("TRUE"/"FALSE") \ 97 | .IBUF_LOW_PWR("FALSE"), // Low Power - "TRUE", High Performance = "FALSE" \ 98 | .SLEW("FAST") // Specify the output slew rate \ 99 | ) IOBUFDS_DQS_inst [1:0]( \ 100 | .O(ddr3_dqs_in), // Buffer output \ 101 | .IO(ddr3_dqs_p), // Diff_p inout (connect directly to top-level port) \ 102 | .IOB(ddr3_dqs_n), // Diff_n inout (connect directly to top-level port) \ 103 | .I(ddr3_dqs_out), // Buffer input \ 104 | .T({2{~ddr3_dqs_oe}}) // 3-state enable input, high=input, low=output \ 105 | ); \ 106 | \ 107 | OBUFTDS #( \ 108 | .SLEW("FAST") // Specify the output slew rate \ 109 | ) OBUFTDS_CK_inst ( \ 110 | .O(ddr3_ck_p), // Diff_p output (connect directly to top-level port) \ 111 | .OB(ddr3_ck_n), // Diff_n output (connect directly to top-level port) \ 112 | .I(ddr3_ck_out), // Buffer input \ 113 | .T(~ddr3_ck_oe) // 3-state enable input \ 114 | ); \ 115 | \ 116 | OBUF #(.SLEW("FAST")) OBUF_ODT_inst ( \ 117 | .O(ddr3_odt), // Buffer output (connect directly to top-level port) \ 118 | .I(ddr3_odt_out) // Buffer input \ 119 | ); \ 120 | \ 121 | OBUF #(.SLEW("FAST")) OBUF_BA_inst [2:0]( \ 122 | .O(ddr3_ba), // Buffer output (connect directly to top-level port) \ 123 | .I(ddr3_ba_out) // Buffer input \ 124 | ); \ 125 | \ 126 | OBUF #(.SLEW("FAST")) OBUF_CKE_inst ( \ 127 | .O(ddr3_cke), // Buffer output (connect directly to top-level port) \ 128 | .I(ddr3_cke_out) // Buffer input \ 129 | ); \ 130 | \ 131 | OBUF #(.SLEW("FAST")) OBUF_RAS_inst ( \ 132 | .O(ddr3_ras_n), // Buffer output (connect directly to top-level port) \ 133 | .I(ddr3_ras_out) // Buffer input \ 134 | ); \ 135 | \ 136 | OBUF #(.SLEW("FAST")) OBUF_CAS_inst ( \ 137 | .O(ddr3_cas_n), // Buffer output (connect directly to top-level port) \ 138 | .I(ddr3_cas_out) // Buffer input \ 139 | ); \ 140 | \ 141 | OBUF #(.SLEW("FAST")) OBUF_WE_inst ( \ 142 | .O(ddr3_we_n), // Buffer output (connect directly to top-level port) \ 143 | .I(ddr3_we_out) // Buffer input \ 144 | ); \ 145 | \ 146 | OBUF #(.SLEW("FAST")) OBUF_CS_inst ( \ 147 | .O(ddr3_cs_n), // Buffer output (connect directly to top-level port) \ 148 | .I(ddr3_cs_out) // Buffer input \ 149 | ); \ 150 | \ 151 | OBUF #(.SLEW("FAST")) OBUF_RESET_inst ( \ 152 | .O(ddr3_reset_n), // Buffer output (connect directly to top-level port) \ 153 | .I(ddr3_reset_out) // Buffer input \ 154 | ); 155 | 156 | `define DDR3_CONNECT \ 157 | .rst(rst), \ 158 | .clk(clk_int), \ 159 | .clk90(clk90_int), \ 160 | .clkdiv(clkdiv_int), \ 161 | \ 162 | .ddr3_dm_out(ddr3_dm_out), \ 163 | \ 164 | .ddr3_dq_in(ddr3_dq_in), \ 165 | .ddr3_dq_out(ddr3_dq_out), \ 166 | .ddr3_dq_oe(ddr3_dq_oe), \ 167 | \ 168 | .ddr3_addr_out(ddr3_addr_out), \ 169 | \ 170 | .ddr3_dqs_in(ddr3_dqs_in), \ 171 | .ddr3_dqs_out(ddr3_dqs_out), \ 172 | .ddr3_dqs_oe(ddr3_dqs_oe), \ 173 | \ 174 | .ddr3_ck_out(ddr3_ck_out), \ 175 | .ddr3_ck_oe(ddr3_ck_oe), \ 176 | \ 177 | .ddr3_odt_out(ddr3_odt_out), \ 178 | \ 179 | .ddr3_ba_out(ddr3_ba_out), \ 180 | \ 181 | .ddr3_cke_out(ddr3_cke_out), \ 182 | \ 183 | .ddr3_ras_out(ddr3_ras_out), \ 184 | \ 185 | .ddr3_cas_out(ddr3_cas_out), \ 186 | \ 187 | .ddr3_we_out(ddr3_we_out), \ 188 | \ 189 | .ddr3_cs_out(ddr3_cs_out), \ 190 | \ 191 | .ddr3_reset_out(ddr3_reset_out) 192 | 193 | -------------------------------------------------------------------------------- /ddr/ddr3/ddr3_doc.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorgothCreator/VerilogUtilIP/51d779b69af9ff2e80f122c65c2a8ef47014ad1f/ddr/ddr3/ddr3_doc.pdf -------------------------------------------------------------------------------- /ddr/ddr3/ddr3_glue.v: -------------------------------------------------------------------------------- 1 | /* 2 | MicroBlaze MCS to DDR3 glue 3 | (C) Copyright 2012 Silicon On Inspiration 4 | www.sioi.com.au 5 | 86 Longueville Road 6 | Lane Cove 2066 7 | New South Wales 8 | AUSTRALIA 9 | 10 | This program is free software: you can redistribute it and/or modify 11 | it under the terms of the GNU Lesser General Public License as published by 12 | the Free Software Foundation, either version 3 of the License, or 13 | (at your option) any later version. 14 | 15 | This program is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | GNU Lesser General Public License for more details. 19 | 20 | You should have received a copy of the GNU Lesser General Public License 21 | along with this program. If not, see . 22 | */ 23 | 24 | `timescale 1ns / 1ps 25 | 26 | module adapter 27 | ( 28 | input ckmb, 29 | input ckdr, 30 | input reset, 31 | 32 | output srd, 33 | output swr, 34 | output [33:5] sa, 35 | output [255:0] swdat, 36 | output [31:0] smsk, 37 | input [255:0] srdat, 38 | input srdy, 39 | 40 | output IO_Ready, 41 | input IO_Addr_Strobe, 42 | input IO_Read_Strobe, 43 | input IO_Write_Strobe, 44 | output [31 : 0] IO_Read_Data, 45 | input [31 : 0] IO_Address, 46 | input [3 : 0] IO_Byte_Enable, 47 | input [31 : 0] IO_Write_Data, 48 | input [3 : 0] page, 49 | input [2:0] dbg_out 50 | ); 51 | 52 | reg [31 : 0] rdat; 53 | reg [255 : 0] wdat; 54 | reg [31 : 0] msk; 55 | reg [33 : 2] addr; 56 | reg rdy1; 57 | reg rdy2; 58 | reg read; 59 | reg write; 60 | 61 | wire [31:0] iowd; 62 | wire [3:0] mask; 63 | 64 | parameter BADBAD = 256'hBAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0BAD0; 65 | 66 | always @ (posedge ckmb) begin 67 | 68 | if (IO_Addr_Strobe && IO_Write_Strobe) begin 69 | case (IO_Address[4:2]) 70 | 0: wdat[31:0] <= iowd; 71 | 1: wdat[63:32] <= iowd; 72 | 2: wdat[95:64] <= iowd; 73 | 3: wdat[127:96] <= iowd; 74 | 4: wdat[159:128] <= iowd; 75 | 5: wdat[191:160] <= iowd; 76 | 6: wdat[223:192] <= iowd; 77 | 7: wdat[255:224] <= iowd; 78 | 79 | // BADBAD markers for bebugging byte masking 80 | // NB: This approach breaks the per-pin IODELAY2 software adjustment on the DQ lines 81 | // 0: wdat <= {BADBAD[255:32], iowd}; 82 | // 1: wdat <= {BADBAD[255:64], iowd, BADBAD[31:0]}; 83 | // 2: wdat <= {BADBAD[255:96], iowd, BADBAD[63:0]}; 84 | // 3: wdat <= {BADBAD[255:128], iowd, BADBAD[95:0]}; 85 | // 4: wdat <= {BADBAD[255:160], iowd, BADBAD[127:0]}; 86 | // 5: wdat <= {BADBAD[255:192], iowd, BADBAD[159:0]}; 87 | // 6: wdat <= {BADBAD[255:224], iowd, BADBAD[191:0]}; 88 | // 7: wdat <= {iowd, BADBAD[223:0]}; 89 | endcase 90 | 91 | case (IO_Address[4:2]) 92 | 93 | 0: msk <= {28'hFFFFFFF, mask}; 94 | 1: msk <= {24'hFFFFFF, mask, 4'hF}; 95 | 2: msk <= {20'hFFFFF, mask, 8'hFF}; 96 | 3: msk <= {16'hFFFF, mask, 12'hFFF}; 97 | 4: msk <= {12'hFFF, mask, 16'hFFFF}; 98 | 5: msk <= {8'hFF, mask, 20'hFFFFF}; 99 | 6: msk <= {4'hF, mask, 24'hFFFFFF}; 100 | 7: msk <= {mask, 28'hFFFFFFF}; 101 | /* 102 | ZZ - write full 256 bits during testing ! 103 | 0: msk <= {28'h0000000, mask}; 104 | 1: msk <= {24'h000000, mask, 4'h0}; 105 | 2: msk <= {20'h00000, mask, 8'h00}; 106 | 3: msk <= {16'h0000, mask, 12'h000}; 107 | 4: msk <= {12'h000, mask, 16'h0000}; 108 | 5: msk <= {8'h00, mask, 20'h00000}; 109 | 6: msk <= {4'h0, mask, 24'h000000}; 110 | 7: msk <= {mask, 28'h0000000}; 111 | */ 112 | endcase 113 | end 114 | 115 | if (IO_Addr_Strobe) 116 | addr <= {page[3:0], IO_Address[29:2]}; 117 | end 118 | 119 | always @ (posedge ckmb or posedge reset) begin 120 | if (reset) begin 121 | read <= 1'b0; 122 | write <= 1'b0; 123 | rdy2 <= 1'b0; 124 | end else begin 125 | if (IO_Addr_Strobe && IO_Read_Strobe) 126 | read <= 1'b1; 127 | else if (IO_Addr_Strobe && IO_Write_Strobe) 128 | write <= 1'b1; 129 | if (rdy1) begin 130 | read <= 1'b0; 131 | write <= 1'b0; 132 | rdy2 <= 1'b1; 133 | end 134 | if (rdy2) 135 | rdy2 <= 1'b0; 136 | end 137 | end 138 | 139 | always @ (posedge ckdr or posedge reset) begin 140 | if (reset) begin 141 | rdy1 <= 1'b0; 142 | end else begin 143 | if (srdy) 144 | rdy1 <= 1'b1; 145 | if (rdy2) 146 | rdy1 <= 1'b0; 147 | if (srdy) case (addr[4:2]) 148 | 0: rdat <= srdat[31:0]; 149 | 1: rdat <= srdat[63:32]; 150 | 2: rdat <= srdat[95:64]; 151 | 3: rdat <= srdat[127:96]; 152 | 4: rdat <= srdat[159:128]; 153 | 5: rdat <= srdat[191:160]; 154 | 6: rdat <= srdat[223:192]; 155 | 7: rdat <= srdat[255:224]; 156 | endcase 157 | end 158 | end 159 | 160 | assign iowd = IO_Write_Data; 161 | assign mask = ~IO_Byte_Enable; 162 | 163 | assign IO_Read_Data = rdat; 164 | assign IO_Ready = rdy2; 165 | assign srd = read; 166 | assign swr = write; 167 | assign swdat = wdat; 168 | assign smsk = msk; 169 | assign sa = addr[33:5]; 170 | 171 | endmodule -------------------------------------------------------------------------------- /ddr/ddr3/ddr3_top.v: -------------------------------------------------------------------------------- 1 | /* 2 | MicroBlaze MCS to DDR3 glue 3 | (C) Copyright 2012 Silicon On Inspiration 4 | www.sioi.com.au 5 | 86 Longueville Road 6 | Lane Cove 2066 7 | New South Wales 8 | AUSTRALIA 9 | 10 | This program is free software: you can redistribute it and/or modify 11 | it under the terms of the GNU Lesser General Public License as published by 12 | the Free Software Foundation, either version 3 of the License, or 13 | (at your option) any later version. 14 | 15 | This program is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | GNU Lesser General Public License for more details. 19 | 20 | You should have received a copy of the GNU Lesser General Public License 21 | along with this program. If not, see . 22 | */ 23 | 24 | `timescale 1ns / 1ps 25 | 26 | module top 27 | ( 28 | input rst, 29 | input clk, 30 | 31 | inout [16:0] ddr3_dq, 32 | inout [1:0] ddr3_dqs_p, 33 | inout [1:0] ddr3_dqs_n, 34 | output [1:0] ddr3_dm, 35 | output [15:0] ddr3_addr, 36 | output [2:0] ddr3_ba, 37 | output [0:0] ddr3_ras_n, 38 | output [0:0] ddr3_cas_n, 39 | output [0:0] ddr3_we_n, 40 | output [0:0] ddr3_cke, 41 | output [0:0] ddr3_cs_n, 42 | output [0:0] ddr3_ck_p, 43 | output [0:0] ddr3_ck_n, 44 | output [0:0] ddr3_odt, 45 | output ddr3_reset_n 46 | ); 47 | 48 | //assign ddr3_reset_n = rst; 49 | wire [2:0]dcmd; 50 | assign {ddr3_ras_n, ddr3_cas_n, ddr3_we_n} = dcmd; 51 | 52 | wire IO_Ready; 53 | wire IO_Addr_Strobe; 54 | wire IO_Read_Strobe; 55 | wire IO_Write_Strobe; 56 | wire [31 : 0] IO_Read_Data; 57 | wire [1 : 0] GPI1; 58 | wire [31 : 0] IO_Address; 59 | wire [3 : 0] IO_Byte_Enable; 60 | wire [31 : 0] IO_Write_Data; 61 | wire [1 : 0] GPO1; 62 | wire [3 : 0] page; 63 | 64 | wire srd; 65 | wire swr; 66 | wire [33:5] sa; 67 | wire [255:0] swdat; 68 | wire [31:0] smsk; 69 | wire [255:0] srdat; 70 | wire srdy; 71 | 72 | wire ck150; 73 | wire ck75; 74 | 75 | wire [0 : 31] Trace_Instruction; 76 | wire [0 : 31] Trace_PC; 77 | wire [0 : 4] Trace_Reg_Addr; 78 | wire [0 : 14] Trace_MSR_Reg; 79 | wire [0 : 31] Trace_New_Reg_Value; 80 | wire [0 : 31] Trace_Data_Address; 81 | wire [0 : 31] Trace_Data_Write_Value; 82 | wire [0 : 3] Trace_Data_Byte_Enable; 83 | 84 | wire [2:0] dbg_out; 85 | wire [7:0] dbg_in; 86 | 87 | ddr3 drac 88 | ( 89 | .ckin (clk), 90 | .ckout (ck150), 91 | .ckouthalf (ck75), 92 | .reset (rst), 93 | 94 | .ddq (ddr3_dq), 95 | .dqsp (ddr3_dqs_p), 96 | .dqsn (ddr3_dqs_n), 97 | .ddm (ddr3_dm), 98 | .da (ddr3_addr), 99 | .dba (ddr3_ba), 100 | .dcmd (dcmd), 101 | .dce (ddr3_cke), 102 | .dcs (ddr3_cs_n), 103 | .dckp (ddr3_ck_p), 104 | .dckn (ddr3_ck_n), 105 | .dodt (ddr3_odt), 106 | 107 | .srd (srd), 108 | .swr (swr), 109 | .sa (sa), 110 | .swdat (swdat), 111 | .smsk (smsk), 112 | .srdat (srdat), 113 | .srdy (srdy), 114 | 115 | .dbg_out (dbg_out), 116 | .dbg_in (dbg_in) 117 | ); 118 | 119 | /* adapter glue 120 | ( 121 | .ckmb (ck75), 122 | .ckdr (ck150), 123 | .reset (rst), 124 | 125 | .srd (srd), 126 | .swr (swr), 127 | .sa (sa), 128 | .swdat (swdat), 129 | .smsk (smsk), 130 | .srdat (srdat), 131 | .srdy (srdy), 132 | 133 | .IO_Ready (IO_Ready), 134 | .IO_Addr_Strobe (IO_Addr_Strobe), 135 | .IO_Read_Strobe (IO_Read_Strobe), 136 | .IO_Write_Strobe (IO_Write_Strobe), 137 | .IO_Read_Data (IO_Read_Data), 138 | .IO_Address (IO_Address), 139 | .IO_Byte_Enable (IO_Byte_Enable), 140 | .IO_Write_Data (IO_Write_Data), 141 | .page (page), 142 | .dbg_out (dbg_out) 143 | ); 144 | */ 145 | /* microblaze_mcs_v1_1 mcs_0 146 | ( 147 | .Clk (ck75), 148 | .Reset (Reset), 149 | .IO_Ready (IO_Ready), 150 | .UART_Rx (rxd), 151 | .IO_Addr_Strobe (IO_Addr_Strobe), 152 | .IO_Read_Strobe (IO_Read_Strobe), 153 | .IO_Write_Strobe (IO_Write_Strobe), 154 | .UART_Tx (txdraw), 155 | .IO_Read_Data (IO_Read_Data), 156 | .GPI1 (mbtn), 157 | .GPI2 (dbg_in), 158 | .IO_Address (IO_Address), 159 | .IO_Byte_Enable (IO_Byte_Enable), 160 | .IO_Write_Data (IO_Write_Data), 161 | .GPO1 (mled), 162 | .GPO2 (page), 163 | .GPO3 (dbg_out), 164 | .Trace_Instruction (Trace_Instruction), // Opcode 165 | .Trace_Valid_Instr (Trace_Valid_Instr), // valid opcode y/n 166 | .Trace_PC (Trace_PC), // PC 167 | .Trace_Reg_Write (Trace_Reg_Write), // output Trace_Reg_Write 168 | .Trace_Reg_Addr (Trace_Reg_Addr), // output [0 : 4] Trace_Reg_Addr 169 | .Trace_MSR_Reg (Trace_MSR_Reg), // output [0 : 14] Trace_MSR_Reg 170 | .Trace_New_Reg_Value (Trace_New_Reg_Value), // output [0 : 31] Trace_New_Reg_Value 171 | .Trace_Jump_Taken (Trace_Jump_Taken), // Jump Taken 172 | .Trace_Delay_Slot (Trace_Delay_Slot), // Delay Slot 173 | .Trace_Data_Address (Trace_Data_Address), // Data Address 174 | .Trace_Data_Access (Trace_Data_Access), // Data_Access y/n 175 | .Trace_Data_Read (Trace_Data_Read), // Data Read y/n 176 | .Trace_Data_Write (Trace_Data_Write), // Data Write y/n 177 | .Trace_Data_Write_Value (Trace_Data_Write_Value), // Data Write Value 178 | .Trace_Data_Byte_Enable (Trace_Data_Byte_Enable), // Data Byte Enables 179 | .Trace_MB_Halted (Trace_MB_Halted) // Halted 180 | );*/ 181 | 182 | //assign txd = ~txdraw; 183 | 184 | endmodule -------------------------------------------------------------------------------- /ddr/ddr3/doc/ddr3_doc.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorgothCreator/VerilogUtilIP/51d779b69af9ff2e80f122c65c2a8ef47014ad1f/ddr/ddr3/doc/ddr3_doc.docx -------------------------------------------------------------------------------- /ddr/ddr3/doc/usercontentimg1351221506.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorgothCreator/VerilogUtilIP/51d779b69af9ff2e80f122c65c2a8ef47014ad1f/ddr/ddr3/doc/usercontentimg1351221506.png -------------------------------------------------------------------------------- /ddr/ddr3/doc/usercontentimg1351223336.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MorgothCreator/VerilogUtilIP/51d779b69af9ff2e80f122c65c2a8ef47014ad1f/ddr/ddr3/doc/usercontentimg1351223336.jpg -------------------------------------------------------------------------------- /ddr/ddr3/system.ucf: -------------------------------------------------------------------------------- 1 | # For SiOI FS6484 Spartan 6 board 2 | # Copyright 2012 SiOI 3 | 4 | CONFIG VCCAUX=3.3; 5 | 6 | Net mck62M5 TNM_NET = sys_clk_pin; 7 | TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 16.000 ns HIGH 50% INPUT_JITTER 100.0ps; 8 | 9 | Net mck62M5 LOC=M3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50; 10 | Net mled<0> LOC=AB2 | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO; 11 | Net mled<1> LOC=AA2 | IOSTANDARD=LVCMOS33 | SLEW=QUIETIO; 12 | Net mbtn<0> LOC=Y3 | IOSTANDARD=LVCMOS33 | PULLUP; 13 | Net mbtn<1> LOC=AB3 | IOSTANDARD=LVCMOS33 | PULLUP; 14 | 15 | Net txd LOC=B10 | IOSTANDARD=LVCMOS33; 16 | Net rxd LOC=A10 | IOSTANDARD=LVCMOS33; 17 | 18 | #Net sda LOC=P2 | IOSTANDARD=SSTL15_II; 19 | #Net scl LOC=L4 | IOSTANDARD=SSTL15_II; 20 | 21 | # PAR usually gets the following right but use manual placement if it fails: 22 | #INST "*BUFPLLS[0].bufpll_625_18" LOC=BUFPLL_X0Y3; 23 | #INST "*BUFPLLS[1].bufpll_625_18" LOC=BUFPLL_X2Y3; 24 | 25 | # Ignore the timing of the GPIO outputs from the MicroBlaze: 26 | inst "mcs_0/U0/iomodule_0/IOModule_Core_I1/GPO_I?/gpo_io_i_?" TIG; 27 | 28 | # Apply TIGs to reset circuitry, allowing it to take multiple clock cycles 29 | inst "drac/rStarted" TIG; 30 | inst "drac/rClrPll" TIG; 31 | 32 | # It is OK for tristating of the data pins can take multiple clock cycles 33 | inst "drac/READ" TIG; 34 | 35 | # 20121011; OUT_TERM=UNTUNED_50 is too strong, use OUT_TERM=UNTUNED_25 36 | 37 | Net ddq<0> LOC=W3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 38 | Net ddq<1> LOC=W1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 39 | Net ddq<2> LOC=U3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 40 | Net ddq<3> LOC=T1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 41 | Net ddq<4> LOC=Y2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 42 | Net ddq<5> LOC=V2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 43 | Net ddq<6> LOC=U1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 44 | Net ddq<7> LOC=T2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 45 | Net ddq<8> LOC=T4 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 46 | Net ddq<9> LOC=R3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 47 | Net ddq<10> LOC=M1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 48 | Net ddq<11> LOC=L1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 49 | Net ddq<12> LOC=T3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 50 | Net ddq<13> LOC=R1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 51 | Net ddq<14> LOC=M2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 52 | Net ddq<15> LOC=L3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 53 | Net ddq<16> LOC=K1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 54 | Net ddq<17> LOC=K2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 55 | Net ddq<18> LOC=H2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT 56 | Net ddq<19> LOC=G1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT 57 | Net ddq<20> LOC=M5 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 58 | Net ddq<21> LOC=J3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 59 | Net ddq<22> LOC=H1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT 60 | Net ddq<23> LOC=G3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT 61 | Net ddq<24> LOC=F1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT 62 | Net ddq<25> LOC=E1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT 63 | Net ddq<26> LOC=C3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT 64 | Net ddq<27> LOC=B2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT 65 | Net ddq<28> LOC=F3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT 66 | Net ddq<29> LOC=F2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT 67 | Net ddq<30> LOC=C1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT 68 | Net ddq<31> LOC=B1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT 69 | Net ddq<32> LOC=C22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT 70 | Net ddq<33> LOC=C20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT 71 | Net ddq<34> LOC=E20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT 72 | Net ddq<35> LOC=F22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT 73 | Net ddq<36> LOC=C19 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT 74 | Net ddq<37> LOC=D21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT 75 | Net ddq<38> LOC=E22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT 76 | Net ddq<39> LOC=F21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT 77 | Net ddq<40> LOC=G22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT 78 | Net ddq<41> LOC=H21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT 79 | Net ddq<42> LOC=J20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 80 | Net ddq<43> LOC=K21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 81 | Net ddq<44> LOC=F20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT 82 | Net ddq<45> LOC=G20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT 83 | Net ddq<46> LOC=J22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 84 | Net ddq<47> LOC=K22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 85 | Net ddq<48> LOC=L20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 86 | Net ddq<49> LOC=M21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 87 | Net ddq<50> LOC=P21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 88 | Net ddq<51> LOC=R22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 89 | Net ddq<52> LOC=L22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 90 | Net ddq<53> LOC=M22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 91 | Net ddq<54> LOC=P22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 92 | Net ddq<55> LOC=R20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 93 | Net ddq<56> LOC=T22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 94 | Net ddq<57> LOC=U20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 95 | Net ddq<58> LOC=V21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 96 | Net ddq<59> LOC=W22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 97 | Net ddq<60> LOC=P19 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 98 | Net ddq<61> LOC=T21 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 99 | Net ddq<62> LOC=V22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 100 | Net ddq<63> LOC=W20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 101 | 102 | Net dqsp<0> LOC=U4 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 103 | Net dqsp<1> LOC=N1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 104 | Net dqsp<2> LOC=H3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT 105 | Net dqsp<3> LOC=D2 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT 106 | Net dqsp<4> LOC=D19 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT 107 | Net dqsp<5> LOC=J19 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT 108 | Net dqsp<6> LOC=N20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 109 | Net dqsp<7> LOC=T19 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 110 | 111 | Net dqsn<0> LOC=V3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 112 | Net dqsn<1> LOC=N3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 113 | Net dqsn<2> LOC=H4 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT 114 | Net dqsn<3> LOC=D1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT 115 | Net dqsn<4> LOC=D20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT 116 | Net dqsn<5> LOC=H20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT 117 | Net dqsn<6> LOC=N22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 118 | Net dqsn<7> LOC=T20 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 119 | 120 | # 121 | # DM signals are outputs during writes and tristated at both ends during reads. We use parallel 122 | # termination during reads on the assumption that it is better for the DM PCB traces not to float. 123 | # It probably is not necessary, but it does not hurt. 124 | # 125 | Net ddm<0> LOC=V1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 126 | Net ddm<1> LOC=P1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 127 | Net ddm<2> LOC=J1 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LB 128 | Net ddm<3> LOC=E3 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#LT 129 | Net ddm<4> LOC=D22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT 130 | Net ddm<5> LOC=H22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RT 131 | Net ddm<6> LOC=M19 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 132 | Net ddm<7> LOC=U22 | IOSTANDARD=SSTL15_II | IN_TERM=UNTUNED_SPLIT_50 | OUT_TERM=UNTUNED_25;#RB 133 | 134 | Net da<0> LOC=G19 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT 135 | Net da<1> LOC=A21 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT 136 | Net da<2> LOC=A20 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT 137 | Net da<3> LOC=A2 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT 138 | Net da<4> LOC=H8 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT 139 | Net da<5> LOC=G6 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT 140 | Net da<6> LOC=F5 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT 141 | Net da<7> LOC=G4 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT 142 | Net da<8> LOC=H6 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT 143 | Net da<9> LOC=J7 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT 144 | Net da<10> LOC=H19 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT 145 | Net da<11> LOC=H5 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT 146 | Net da<12> LOC=J6 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT 147 | Net da<13> LOC=M20 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RB 148 | Net da<14> LOC=K4 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT 149 | Net da<15> LOC=K3 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT 150 | 151 | Net dba<0> LOC=J17 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT 152 | Net dba<1> LOC=H18 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT 153 | Net dba<2> LOC=J4 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT 154 | 155 | Net dcmd<2> LOC=K17 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT # RAS 156 | Net dcmd<1> LOC=K18 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RB # CAS 157 | Net dcmd<0> LOC=K20 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT # WE 158 | 159 | Net dce<0> LOC=K5 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT 160 | Net dce<1> LOC=K6 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#LT 161 | 162 | Net dcs<0> LOC=K19 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT 163 | Net dcs<1> LOC=L17 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RB 164 | 165 | Net dckp<0> LOC=F18 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT 166 | Net dckp<1> LOC=B21 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT 167 | 168 | Net dckn<0> LOC=F19 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT 169 | Net dckn<1> LOC=B22 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RT 170 | 171 | Net dodt<0> LOC=L19 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RB 172 | Net dodt<1> LOC=P20 | IOSTANDARD=SSTL15_II | OUT_TERM=UNTUNED_25;#RB -------------------------------------------------------------------------------- /ddr/ddr3_core.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | 3 | module ddr3_core #(parameter FREQ_CKDIV_MHZ = 2)( 4 | input rst, 5 | input clk, 6 | input clk90, 7 | input clkdiv, 8 | 9 | output reg [1:0]ddr3_dm_out, 10 | 11 | input [127:0]ddr3_pdata_in, 12 | output reg [127:0]ddr3_pdata_out, 13 | output reg ddr3_dq_oe, 14 | output ddr3_pdata_write, 15 | output ddr3_dq_receiver_en, 16 | 17 | output reg [13:0]ddr3_addr_out, 18 | 19 | input [1:0]ddr3_dqs_in, 20 | output reg [1:0]ddr3_dqs_out, 21 | output reg ddr3_dqs_oe, 22 | 23 | output reg ddr3_ck_oe, 24 | 25 | output reg ddr3_odt_out, 26 | 27 | output reg [2:0]ddr3_ba_out, 28 | 29 | output reg ddr3_cke_out, 30 | 31 | output ddr3_ras_out, 32 | 33 | output ddr3_cas_out, 34 | 35 | output ddr3_we_out, 36 | 37 | output ddr3_cs_out, 38 | 39 | output reg ddr3_reset_out 40 | ); 41 | 42 | 43 | `define COMMAND_BANK_ACTIVE 4'b0011 44 | `define COMMAND_SINGLE_BANK_PRECHARGE 4'b0010 45 | `define COMMAND_ALL_BANKS_PRECHARGE 4'b0010 46 | `define COMMAND_WRITE 4'b0100 47 | `define COMMAND_READ 4'b0101 48 | `define COMMAND_DEVICE_DETECT 4'b1000 49 | `define COMMAND_NOP 4'b0111 50 | `define COMMAND_REFRESH 4'b0001 51 | `define COMMAND_SELF_REFRESH_ENTRY 4'b0001 52 | `define COMMAND_SELF_REFRESH_EXIT 4'b1000 53 | `define COMMAND_MRS 4'b0000 54 | `define COMMAND_ZQ_CAL 4'b0110 55 | 56 | reg [3:0]command_reg; 57 | assign {ddr3_cs_out, ddr3_ras_out, ddr3_cas_out, ddr3_we_out} = command_reg; 58 | 59 | reg [15:0]addrL; 60 | reg [15:0]addrH; 61 | 62 | /* 63 | * 1uS clk generator. 64 | */ 65 | reg [8:0]ck_1us_cnt; 66 | wire ck_1mhz = (ck_1us_cnt == FREQ_CKDIV_MHZ - 1); 67 | reg [9:0]us_cnt; 68 | 69 | always @ ( posedge clkdiv) 70 | begin 71 | if(rst) 72 | ck_1us_cnt <= 0; 73 | else 74 | begin 75 | if(ck_1mhz) 76 | ck_1us_cnt <= 0; 77 | else 78 | ck_1us_cnt <= ck_1us_cnt + 1; 79 | end 80 | end 81 | 82 | /* 83 | * DDR3 times definitions. 84 | */ 85 | localparam tXPR = 1; 86 | localparam tMRD = 4; 87 | localparam tMOD = 1; 88 | localparam tZQinit = 512; 89 | /* 90 | * DDR3 commands. 91 | */ 92 | 93 | `define MR0 0 94 | `define MRS0 0 95 | `define MR1 1 96 | `define MRS1 1 97 | `define MR2 2 98 | `define MRS2 2 99 | `define MR3 3 100 | `define MRS3 3 101 | 102 | 103 | /* 104 | * Sequence execution. 105 | */ 106 | 107 | `define INIT_RESET_TIME 200 108 | `define INIT_RESET_TO_CK_EN_TIME 500 109 | 110 | `define INIT_RESET_START_STAGE 0 111 | `define INIT_RESET_CK_EN_STAGE 1 112 | `define INIT_RESET_NOTE1_START_STAGE 2 113 | `define INIT_RESET_NOTE1_END_STAGE 3 114 | `define INIT_RESET_MR2_START_STAGE 4 115 | `define INIT_RESET_MR2_END_STAGE 5 116 | `define INIT_RESET_MR3_START_STAGE 6 117 | `define INIT_RESET_MR3_END_STAGE 7 118 | `define INIT_RESET_MR1_START_STAGE 8 119 | `define INIT_RESET_MR1_END_STAGE 9 120 | `define INIT_RESET_MR0_START_STAGE 10 121 | `define INIT_RESET_MR0_END_STAGE 11 122 | `define INIT_RESET_ZQCL_START_STAGE 12 123 | `define INIT_RESET_ZQCL_END_STAGE 13 124 | `define INIT_RESET_END_STAGE 14 125 | 126 | reg [9:0]us_init_cnt; 127 | reg [9:0]stage_cnt; 128 | 129 | always @ ( posedge clk90 ) 130 | begin 131 | if(rst) 132 | begin 133 | ddr3_dq_oe <= 0; 134 | ddr3_dqs_oe <= 0; 135 | ddr3_ck_oe <= 0; 136 | 137 | ddr3_reset_out <= 0; 138 | ddr3_cke_out <= 0; 139 | command_reg <= `COMMAND_NOP; 140 | 141 | us_init_cnt <= `INIT_RESET_TIME; 142 | stage_cnt <= 0; 143 | end 144 | else 145 | begin 146 | if(us_init_cnt) 147 | us_init_cnt <= us_init_cnt - 1; 148 | command_reg <= `COMMAND_NOP; 149 | case(stage_cnt) 150 | `INIT_RESET_START_STAGE: 151 | begin 152 | if(!us_init_cnt) 153 | begin 154 | ddr3_reset_out <= 1; 155 | ddr3_ck_oe <= 1; 156 | us_init_cnt <= `INIT_RESET_TO_CK_EN_TIME; 157 | stage_cnt <= `INIT_RESET_CK_EN_STAGE; 158 | end 159 | end 160 | `INIT_RESET_CK_EN_STAGE: 161 | begin 162 | if(!us_init_cnt) 163 | begin 164 | ddr3_cke_out <= 1; 165 | ddr3_odt_out <= 0; 166 | stage_cnt <= `INIT_RESET_MR2_START_STAGE; 167 | end 168 | end 169 | `INIT_RESET_MR2_START_STAGE: 170 | begin 171 | command_reg <= `COMMAND_MRS; 172 | ddr3_ba_out <= `MRS2; 173 | ddr3_addr_out <= `MR2; 174 | stage_cnt <= `INIT_RESET_MR2_END_STAGE; 175 | end 176 | `INIT_RESET_MR2_END_STAGE: 177 | begin 178 | //command_reg <= `COMMAND_NOP; 179 | us_init_cnt <= tMRD; 180 | stage_cnt <= `INIT_RESET_MR3_START_STAGE; 181 | end 182 | `INIT_RESET_MR3_START_STAGE: 183 | begin 184 | if(!us_init_cnt) 185 | begin 186 | command_reg <= `COMMAND_MRS; 187 | ddr3_ba_out <= `MRS3; 188 | ddr3_addr_out <= `MR3; 189 | stage_cnt <= `INIT_RESET_MR3_END_STAGE; 190 | end 191 | end 192 | `INIT_RESET_MR3_END_STAGE: 193 | begin 194 | //command_reg <= `COMMAND_NOP; 195 | us_init_cnt <= tMRD; 196 | stage_cnt <= `INIT_RESET_MR1_START_STAGE; 197 | end 198 | `INIT_RESET_MR1_START_STAGE: 199 | begin 200 | if(!us_init_cnt) 201 | begin 202 | command_reg <= `COMMAND_MRS; 203 | ddr3_ba_out <= `MRS1; 204 | ddr3_addr_out <= `MR1; 205 | stage_cnt <= `INIT_RESET_MR1_END_STAGE; 206 | end 207 | end 208 | `INIT_RESET_MR1_END_STAGE: 209 | begin 210 | //command_reg <= `COMMAND_NOP; 211 | us_init_cnt <= tMRD; 212 | stage_cnt <= `INIT_RESET_MR0_START_STAGE; 213 | end 214 | `INIT_RESET_MR0_START_STAGE: 215 | begin 216 | if(!us_init_cnt) 217 | begin 218 | command_reg <= `COMMAND_MRS; 219 | ddr3_ba_out <= `MRS0; 220 | ddr3_addr_out <= `MR0; 221 | stage_cnt <= `INIT_RESET_MR0_END_STAGE; 222 | end 223 | end 224 | `INIT_RESET_MR0_END_STAGE: 225 | begin 226 | //command_reg <= `COMMAND_NOP; 227 | us_init_cnt <= tMRD; 228 | stage_cnt <= `INIT_RESET_ZQCL_START_STAGE; 229 | end 230 | `INIT_RESET_ZQCL_START_STAGE: 231 | begin 232 | if(!us_init_cnt) 233 | begin 234 | command_reg <= `COMMAND_ZQ_CAL; 235 | us_init_cnt <= tZQinit; 236 | stage_cnt <= `INIT_RESET_ZQCL_END_STAGE; 237 | end 238 | end 239 | `INIT_RESET_ZQCL_END_STAGE: 240 | begin 241 | //command_reg <= `COMMAND_NOP; 242 | if(!us_init_cnt) 243 | begin 244 | ddr3_cke_out <= 0; 245 | stage_cnt <= `INIT_RESET_END_STAGE; 246 | end 247 | end 248 | endcase 249 | end 250 | end 251 | 252 | endmodule 253 | -------------------------------------------------------------------------------- /ddr/memparts.csv: -------------------------------------------------------------------------------- 1 | Part type,Part name,Rank,CA Mirror,Data mask,Row width,Column width,Bank width,CS width,CKE width,ODT width,CK width,Memory speed grade,Memory density,Component density,Memory device width,Memory component width,Data bits per strobe,IO Voltages,Data widths,Min period,Max period 2 | Components,MT41J512M8RH-093,1,0,1,"16 (12,13,14,15)","10 (11,12)",3,1,1,1,1,093,4Gb,4Gb,8,8,8,1.5V,"8,16,24,32,40,48,56,64,72",938,3300 3 | Components,MT41J256M16HA-093,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,093,4Gb,4Gb,16,16,8,1.5V,"8,16,24,32,40,48,56,64,72,80",938,3300 4 | Components,MT41J512M8RH-107,1,0,1,"16 (12,13,14,15)","10 (11,12)",3,1,1,1,1,107,4Gb,4Gb,8,8,8,1.5V,"8,16,24,32,40,48,56,64,72",1071,3300 5 | Components,MT41J256M16HA-107,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,107,4Gb,4Gb,16,16,8,1.5V,"8,16,24,32,40,48,56,64,72,80",1071,3300 6 | Components,MT41J512M8RA-125,1,0,1,"16 (12,13,14,15)","10 (11,12)",3,1,1,1,1,125,4Gb,4Gb,8,8,8,1.5V,"8,16,24,32,40,48,56,64,72",1250,3300 7 | Components,MT41J256M16HA-125,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,125,4Gb,4Gb,16,16,8,1.5V,"8,16,24,32,40,48,56,64,72,80",1250,3300 8 | Components,MT41J512M8RA-15E,1,0,1,"16 (12,13,14,15)","10 (11,12)",3,1,1,1,1,15E,4Gb,4Gb,8,8,8,1.5V,"8,16,24,32,40,48,56,64,72",1500,3300 9 | Components,MT41J256M16RE-15E,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,15E,4Gb,4Gb,16,16,8,1.5V,"8,16,24,32,40,48,56,64,72,80",1500,3300 10 | Components,MT41J256M8DA-093,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,093,2Gb,2Gb,8,8,8,1.5V,"8,16,24,32,40,48,56,64,72",938,3300 11 | Components,MT41J128M16JT-093,1,0,1,"14 (12,13,15,16)","10 (11,12)",3,1,1,1,1,093,2Gb,2Gb,16,16,8,1.5V,"8,16,24,32,40,48,56,64,72,80",938,3300 12 | Components,MT41J256M8DA-107,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,107,2Gb,2Gb,8,8,8,1.5V,"8,16,24,32,40,48,56,64,72",1071,3300 13 | Components,MT41J128M16JT-107,1,0,1,"14 (12,13,15,16)","10 (11,12)",3,1,1,1,1,107,2Gb,2Gb,16,16,8,1.5V,"8,16,24,32,40,48,56,64,72,80",1071,3300 14 | Components,MT41J256M8DA-125,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,125,2Gb,2Gb,8,8,8,1.5V,"8,16,24,32,40,48,56,64,72",1250,3300 15 | Components,MT41J128M16JT-125,1,0,1,"14 (12,13,15,16)","10 (11,12)",3,1,1,1,1,125,2Gb,2Gb,16,16,8,1.5V,"8,16,24,32,40,48,56,64,72,80",1250,3300 16 | Components,MT41J256M8HX-15E,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,15E,2Gb,2Gb,8,8,8,1.5V,"8,16,24,32,40,48,56,64,72",1500,3300 17 | Components,MT41J128M16HA-15E,1,0,1,"14 (12,13,15,16)","10 (11,12)",3,1,1,1,1,15E,2Gb,2Gb,16,16,8,1.5V,"8,16,24,32,40,48,56,64,72,80",1500,3300 18 | Components,MT41J128M8JP-125,1,0,1,"14 (12,13,15,16)","10 (11,12)",3,1,1,1,1,125,1Gb,1Gb,8,8,8,1.5V,"8,16,24,32,40,48,56,64,72",1250,3300 19 | Components,MT41J64M16JT-125,1,0,1,"13 (12,14,15,16)","10 (11,12)",3,1,1,1,1,125,1Gb,1Gb,16,16,8,1.5V,"8,16,24,32,40,48,56,64,72,80",1250,3300 20 | Components,MT41J128M8JP-15E,1,0,1,"14 (12,13,15,16)","10 (11,12)",3,1,1,1,1,15E,1Gb,1Gb,8,8,8,1.5V,"8,16,24,32,40,48,56,64,72",1500,3300 21 | Components,MT41J64M16JT-15E,1,0,1,"13 (12,14,15,16)","10 (11,12)",3,1,1,1,1,15E,1Gb,1Gb,16,16,8,1.5V,"8,16,24,32,40,48,56,64,72,80",1500,3300 22 | Components,MT41K512M8RH-107,1,0,1,"16 (12,13,14,15)","10 (11,12)",3,1,1,1,1,107,4Gb,4Gb,8,8,8,"1.35V,1.5V","8,16,24,32,40,48,56,64,72",1071,3300 23 | Components,MT41K256M16HA-107,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,107,4Gb,4Gb,16,16,8,"1.35V,1.5V","8,16,24,32,40,48,56,64,72,80",1071,3300 24 | Components,MT41K512M8RH-125,1,0,1,"16 (12,13,14,15)","10 (11,12)",3,1,1,1,1,125,4Gb,4Gb,8,8,8,"1.35V,1.5V","8,16,24,32,40,48,56,64,72",1250,3300 25 | Components,MT41K256M16HA-125,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,125,4Gb,4Gb,16,16,8,"1.35V,1.5V","8,16,24,32,40,48,56,64,72,80",1250,3300 26 | Components,MT41K512M8RA-15E,1,0,1,"16 (12,13,14,15)","10 (11,12)",3,1,1,1,1,15E,4Gb,4Gb,8,8,8,"1.35V,1.5V","8,16,24,32,40,48,56,64,72",1500,3300 27 | Components,MT41K256M16RE-15E,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,15E,4Gb,4Gb,16,16,8,"1.35V,1.5V","8,16,24,32,40,48,56,64,72,80",1500,3300 28 | Components,MT41K256M8DA-107,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,107,2Gb,2Gb,8,8,8,"1.35V,1.5V","8,16,24,32,40,48,56,64,72",1071,3300 29 | Components,MT41K128M16JT-107,1,0,1,"14 (12,13,15,16)","10 (11,12)",3,1,1,1,1,107,2Gb,2Gb,16,16,8,"1.35V,1.5V","8,16,24,32,40,48,56,64,72,80",1071,3300 30 | Components,MT41K256M8DA-125,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,125,2Gb,2Gb,8,8,8,"1.35V,1.5V","8,16,24,32,40,48,56,64,72",1250,3300 31 | Components,MT41K128M16JT-125,1,0,1,"14 (12,13,15,16)","10 (11,12)",3,1,1,1,1,125,2Gb,2Gb,16,16,8,"1.35V,1.5V","8,16,24,32,40,48,56,64,72,80",1250,3300 32 | Components,MT41K64M16JT-125,1,0,1,"13 (12,14,15,16)","10 (11,12)",3,1,1,1,1,125,1Gb,1Gb,16,16,8,"1.35V,1.5V","8,16,24,32,40,48,56,64,72,80",1250,3300 33 | Components,MT41K64M16JT-15E,1,0,1,"13 (12,14,15,16)","10 (11,12)",3,1,1,1,1,15E,1Gb,1Gb,16,16,8,"1.35V,1.5V","8,16,24,32,40,48,56,64,72,80",1500,3300 34 | Components,MT41K512M4DA-107,1,0,1,"15 (12,13,14,16)","11 (10,12)",3,1,1,1,1,107,2Gb,2Gb,4,4,4,"1.35V,1.5V","8,16,24,32",1071,3300 35 | Components,MT41K512M4DA-125,1,0,1,"15 (12,13,14,16)","11 (10,12)",3,1,1,1,1,125,2Gb,2Gb,4,4,4,"1.35V,1.5V","8,16,24,32",1250,3300 36 | Components,MT41K1G4RH-107,1,0,1,"16 (12,13,14,16)","11 (10,12)",3,1,1,1,1,107,4Gb,4Gb,4,4,4,"1.35V,1.5V","8,16,24,32",1071,3300 37 | Components,MT41K1G4RH-125,1,0,1,"16 (12,13,14,16)","11 (10,12)",3,1,1,1,1,125,4Gb,4Gb,4,4,4,"1.35V,1.5V","8,16,24,32",1250,3300 38 | Components,MT41K1G16DGA-125,2,0,1,"16 (12,13,14,15)","10 (11,12)",3,2,2,2,1,125,16Gb,4Gb,16,16,8,"1.35V,1.5V","8,16,24,32,40,48,56,64,72,80",1250,3300 39 | Components,MT41K2G8KJR-125,2,0,1,"16 (12,13,14,15)","11 (10,12)",3,2,2,2,1,125,16Gb,4Gb,8,8,8,"1.35V,1.5V","8,16,24,32,40,48,56,64,72",1250,3300 40 | Components,MT41K4G4KJR-125,2,0,1,"16 (12,13,14,16)","12 (10,11)",3,2,2,2,1,125,16Gb,4Gb,4,4,4,"1.35V,1.5V","8,16,24,32",1250,3300 41 | Components,MT41K1G8TRF-107,2,0,1,"16 (12,13,14,15)","10 (11,12)",3,2,2,2,1,107,8Gb,4Gb,8,8,8,"1.35V,1.5V","8,16,24,32,40,48,56,64,72",1071,3300 42 | Components,MT41K2G4TRF-107,2,0,1,"16 (12,13,14,15)","11 (10,12)",3,2,2,2,1,107,8Gb,4Gb,4,4,4,"1.35V,1.5V","8,16,24,32",1071,3300 43 | UDIMMs,MT8JTF51264AZ-1G6,1,0,1,"16 (12,13,14,15)","10 (11,12)",3,1,1,1,1,125,4GB,4Gb,64,8,8,1.5V,64,1250,3300 44 | UDIMMs,MT8JTF51264AZ-1G4,1,0,1,"16 (12,13,14,15)","10 (11,12)",3,1,1,1,1,15E,4GB,4Gb,64,8,8,1.5V,64,1500,3300 45 | UDIMMs,MT9JSF25672AZ-2G1,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,093,2GB,2Gb,72,8,8,1.5V,72,938,3300 46 | UDIMMs,MT9JSF25672AZ-1G9,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,107,2GB,2Gb,72,8,8,1.5V,72,1071,3300 47 | UDIMMs,MT9JSF25672AZ-1G6,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,125,2GB,2Gb,72,8,8,1.5V,72,1250,3300 48 | UDIMMs,MT9JSF25672AZ-1G4,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,15E,2GB,2Gb,72,8,8,1.5V,72,1500,3300 49 | UDIMMs,MT8JTF25664AZ-1G6,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,125,2GB,2Gb,64,8,8,1.5V,64,1250,3300 50 | UDIMMs,MT8JTF25664AZ-1G4,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,15E,2GB,2Gb,64,8,8,1.5V,64,1500,3300 51 | UDIMMs,MT4JTF25664AZ-1G6,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,125,2GB,4Gb,64,16,8,1.5V,64,1250,3300 52 | UDIMMs,MT8JTF12864AZ-1G4,1,0,1,"14 (12,13,15,16)","10 (11,12)",3,1,1,1,1,15E,1GB,1Gb,64,8,8,1.5V,64,1500,3300 53 | UDIMMs,MT9JSF12872AZ-1G4,1,0,1,"14 (12,13,15,16)","10 (11,12)",3,1,1,1,1,15E,1GB,1Gb,72,8,8,1.5V,72,1500,3300 54 | UDIMMs,MT8KTF51264AZ-1G9,1,0,1,"16 (12,13,14,15)","10 (11,12)",3,1,1,1,1,107,4GB,4Gb,64,8,8,"1.35V,1.5V",64,1071,3300 55 | UDIMMs,MT8KTF51264AZ-1G6,1,0,1,"16 (12,13,14,15)","10 (11,12)",3,1,1,1,1,125,4GB,4Gb,64,8,8,"1.35V,1.5V",64,1250,3300 56 | UDIMMs,MT9KSF51272AZ-1G6,1,0,1,"16 (12,13,14,15)","10 (11,12)",3,1,1,1,1,125,4GB,4Gb,72,8,8,"1.35V,1.5V",72,1250,3300 57 | UDIMMs,MT9KSF25672AZ-1G6,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,125,2GB,2Gb,72,8,8,"1.35V,1.5V",72,1250,3300 58 | UDIMMs,MT9KSF25672AZ-1G4,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,15E,2GB,2Gb,72,8,8,"1.35V,1.5V",72,1500,3300 59 | UDIMMs,MT8KTF25664AZ-1G6,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,125,2GB,2Gb,64,8,8,"1.35V,1.5V",64,1250,3300 60 | UDIMMs,MT8KTF25664AZ-1G4,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,15E,2GB,2Gb,64,8,8,"1.35V,1.5V",64,1500,3300 61 | UDIMMs,MT4KTF25664AZ-1G6,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,125,2GB,4Gb,64,16,8,"1.35V,1.5V",64,1250,3300 62 | UDIMMs,MT18JSF1G72AZ-1G9,2,1,1,"16 (12,13,14,15)","10 (11,12)",3,2,2,2,2,107,8GB,4Gb,72,8,8,1.5V,72,1071,3300 63 | UDIMMs,MT18JSF1G72AZ-1G6,2,1,1,"16 (12,13,14,15)","10 (11,12)",3,2,2,2,2,125,8GB,4Gb,72,8,8,1.5V,72,1250,3300 64 | UDIMMs,MT18JSF51272AZ-1G4,2,1,1,"16 (12,13,14,15)","10 (11,12)",3,2,2,2,2,15E,8GB,4Gb,72,8,8,1.5V,72,1500,3300 65 | UDIMMs,MT18KSF1G72AZ-1G6,2,1,1,"16 (12,13,14,15)","10 (11,12)",3,2,2,2,2,125,8GB,4Gb,72,8,8,"1.35V,1.5V",72,1250,3300 66 | UDIMMs,MT18KSF1G72AZ-1G4,2,1,1,"16 (12,13,14,15)","10 (11,12)",3,2,2,2,2,15E,8GB,4Gb,72,8,8,"1.35V,1.5V",72,1500,3300 67 | SODIMMs,MT8JTF51264HZ-1G6,1,0,1,"16 (12,13,14,15)","10 (11,12)",3,1,1,1,1,125,4GB,4Gb,64,8,8,1.5V,64,1250,3300 68 | SODIMMs,MT8JTF25664HZ-1G4,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,15E,2GB,2Gb,64,8,8,1.5V,64,1500,3300 69 | SODIMMs,MT4JTF12864HZ-1G4,1,0,1,"14 (12,13,15,16)","10 (11,12)",3,1,1,1,1,15E,1GB,2Gb,64,16,8,1.5V,64,1500,3300 70 | SODIMMs,MT8MTF51264HZ-1G6,1,0,1,"16 (12,13,14,15)","10 (11,12)",3,1,1,1,1,125,4GB,4Gb,64,8,8,"1.35V,1.5V",64,1250,3300 71 | SODIMMs,MT8KTF25664HZ-1G6,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,125,2GB,2Gb,64,8,8,"1.35V,1.5V",64,1250,3300 72 | SODIMMs,MT8KTF25664HZ-1G4,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,1,1,1,1,15E,2GB,2Gb,64,8,8,"1.35V,1.5V",64,1500,3300 73 | SODIMMs,MT8KTF12864HZ-1G4,1,0,1,"14 (12,13,15,16)","10 (11,12)",3,1,1,1,1,15E,1GB,1Gb,64,8,8,"1.35V,1.5V",64,1500,3300 74 | SODIMMs,MT16KTF1G64HZ-1G9,2,0,1,"16 (12,13,14,15)","10 (11,12)",3,2,2,2,2,107,8GB,4Gb,64,8,8,"1.35V,1.5V",64,1071,3300 75 | SODIMMs,MT16KTF1G64HZ-1G6,2,0,1,"16 (12,13,14,15)","10 (11,12)",3,2,2,2,2,125,8GB,4Gb,64,8,8,"1.35V,1.5V",64,1250,3300 76 | RDIMMs,MT18JSF1G72PZ-1G9,1,0,1,"16 (12,13,14,15)","11 (10,12)",3,2,1,1,1,107,8GB,4Gb,72,4,4,1.5V,72,1071,3300 77 | RDIMMs,MT18JSF1G72PZ-1G6,1,0,1,"16 (12,13,14,15)","11 (10,12)",3,2,1,1,1,125,8GB,4Gb,72,4,4,1.5V,72,1250,3300 78 | RDIMMs,MT18JSF51272PZ-1G4,1,0,1,"15 (12,13,14,16)","11 (10,12)",3,2,1,1,1,15E,4GB,2Gb,72,4,4,1.5V,72,1500,3300 79 | RDIMMs,MT18KSF1G72PZ-1G4,1,0,1,"16 (12,13,14,15)","11 (10,12)",3,2,1,1,1,15E,8GB,4Gb,72,4,4,"1.35V,1.5V",72,1500,3300 80 | RDIMMs,MT18KSF1G72PZ-1G6,1,0,1,"16 (12,13,14,15)","11 (10,12)",3,2,1,1,1,125,8GB,4Gb,72,4,4,"1.35V,1.5V",72,1250,3300 81 | RDIMMs,MT9JSF51272PZ-1G6,1,0,1,"16 (12,13,14,15)","10 (11,12)",3,2,1,1,1,125,4GB,4Gb,72,8,8,1.5V,72,1250,3300 82 | RDIMMs,MT9JSF51272PZ-1G9,1,0,1,"16 (12,13,14,15)","10 (11,12)",3,2,1,1,1,107,4GB,4Gb,72,8,8,1.5V,72,1071,3300 83 | RDIMMs,MT9KSF25672PZ-1G4,1,0,1,"15 (12,13,14,16)","10 (11,12)",3,2,1,1,1,15E,2GB,2Gb,72,8,8,"1.35V,1.5V",72,1500,3300 84 | RDIMMs,MT9KSF51272PZ-1G6,1,0,1,"16 (12,13,14,15)","10 (11,12)",3,2,1,1,1,125,4GB,4Gb,72,8,8,"1.35V,1.5V",72,1250,3300 85 | RDIMMs,MT36KSF2G72PZ-1G4,2,1,1,"16 (12,13,14,15)","11 (10,12)",3,2,2,2,1,15E,16GB,4Gb,72,4,4,"1.35V,1.5V",72,1500,3300 86 | RDIMMs,MT36KSF2G72PZ-1G6,2,1,1,"16 (12,13,14,15)","11 (10,12)",3,2,2,2,1,125,16GB,4Gb,72,4,4,"1.35V,1.5V",72,1250,3300 87 | RDIMMs,MT18JSF1G72PDZ-1G6,2,1,1,"16 (12,13,14,15)","10 (11,12)",3,2,2,2,1,125,8GB,4Gb,72,8,8,1.5V,72,1250,3300 88 | RDIMMs,MT18JSF1G72PDZ-1G9,2,1,1,"16 (12,13,14,15)","10 (11,12)",3,2,2,2,1,107,8GB,4Gb,72,8,8,1.5V,72,1071,3300 89 | RDIMMs,MT18KSF1G72PDZ-1G4,2,1,1,"16 (12,13,14,15)","10 (11,12)",3,2,2,2,1,15E,8GB,4Gb,72,8,8,"1.35V,1.5V",72,1500,3300 90 | RDIMMs,MT18KSF1G72PDZ-1G6,2,1,1,"16 (12,13,14,15)","10 (11,12)",3,2,2,2,1,125,8GB,4Gb,72,8,8,"1.35V,1.5V",72,1250,3300 91 | RDIMMs,MT36JSF1G72PZ-1G4,2,1,1,"15 (12,13,14,16)","11 (10,12)",3,2,2,2,1,15E,8GB,2Gb,72,4,4,1.5V,72,1500,3300 92 | RDIMMs,MT36JSF2G72PZ-1G6,2,1,1,"16 (12,13,14,15)","11 (10,12)",3,2,2,2,1,125,16GB,4Gb,72,4,4,1.5V,72,1250,3300 93 | RDIMMs,MT36JSF2G72PZ-1G9,2,1,1,"16 (12,13,14,15)","11 (10,12)",3,2,2,2,1,107,16GB,4Gb,72,4,4,1.5V,72,1071,3300 94 | -------------------------------------------------------------------------------- /ddr/memports.csv: -------------------------------------------------------------------------------- 1 | Port name,Device type,IO standard HP 1.5,IO standard HR 1.5,IO standard HP 1.35,IO standard HR 1.35,IO direction,Signal Group,Calibration read string,Calibration write string,Port width,MB odelay addr,MB idelay addr,Slew rate,Ouput Impedance,Drive Strength,Ibuf low pwr 2 | ddr3_dq,All,SSTL15_DCI,SSTL15,SSTL135_DCI,SSTL135,IO,Data,mcal_DQIn,mcal_DQOut,DQ_WIDTH,4100,4200,FAST,RDRV_40_40,0,FALSE 3 | ddr3_dqs_p,All,DIFF_SSTL15_DCI,DIFF_SSTL15,DIFF_SSTL135_DCI,DIFF_SSTL135,IO,Strobe,mcal_nc,mcal_DQSOut,DQS_WIDTH,8100,8200,FAST,RDRV_40_40,0,FALSE 4 | ddr3_dqs_n,All,DIFF_SSTL15_DCI,DIFF_SSTL15,DIFF_SSTL135_DCI,DIFF_SSTL135,IO,Strobe,mcal_nc,8'bx,DQS_WIDTH,,,FAST,RDRV_40_40,0,FALSE 5 | ddr3_dm,All,SSTL15_DCI,SSTL15,SSTL135_DCI,SSTL135,O,Mask,mcal_DMIn_n,mcal_DMOut_n,DM_WIDTH,4400,4800,FAST,RDRV_40_40,0 6 | ddr3_addr,All,SSTL15_DCI,SSTL15,SSTL135_DCI,SSTL135,O,Address,mcal_nc,mcal_ADR,ROW_WIDTH,10010,,FAST,RDRV_40_40,0 7 | ddr3_ba,All,SSTL15_DCI,SSTL15,SSTL135_DCI,SSTL135,O,BankAddress,mcal_nc,mcal_BA,BANK_WIDTH,10080,,FAST,RDRV_40_40,0 8 | ddr3_ras_n,All,SSTL15_DCI,SSTL15,SSTL135_DCI,SSTL135,O,Control,mcal_nc,mcal_RAS_n,,10020,,FAST,RDRV_40_40,0 9 | ddr3_cas_n,All,SSTL15_DCI,SSTL15,SSTL135_DCI,SSTL135,O,Control,mcal_nc,mcal_CAS_n,,10021,,FAST,RDRV_40_40,0 10 | ddr3_we_n,All,SSTL15_DCI,SSTL15,SSTL135_DCI,SSTL135,O,Control,mcal_nc,mcal_WE_n,,10022,,FAST,RDRV_40_40,0 11 | ddr3_parity,RDIMMs,SSTL15_DCI,SSTL15,SSTL135_DCI,SSTL135,O,Control,mcal_nc,mcal_PAR,,11000,,FAST,RDRV_40_40,0 12 | ddr3_ck_p,All,DIFF_SSTL15_DCI,DIFF_SSTL15,DIFF_SSTL135_DCI,DIFF_SSTL135,O,Clock,mcal_nc,8'b01010101,,,,FAST,RDRV_40_40,0 13 | ddr3_ck_n,All,DIFF_SSTL15_DCI,DIFF_SSTL15,DIFF_SSTL135_DCI,DIFF_SSTL135,O,Clock,mcal_nc,8'bx,,,,FAST,RDRV_40_40,0 14 | ddr3_cke,All,SSTL15_DCI,SSTL15,SSTL135_DCI,SSTL135,O,Control,mcal_nc,mcal_CKE,CKE_WIDTH,10200,,FAST,RDRV_40_40,0 15 | ddr3_cs_n,All,SSTL15_DCI,SSTL15,SSTL135_DCI,SSTL135,O,Control,mcal_nc,mcal_CS_n,CS_WIDTH*nCS_PER_RANK,10400,,FAST,RDRV_40_40,0 16 | ddr3_odt,All,SSTL15_DCI,SSTL15,SSTL135_DCI,SSTL135,O,Control,mcal_nc,mcal_ODT,ODT_WIDTH,10800,,FAST,RDRV_40_40,0 17 | ddr3_reset_n,All,SSTL15,SSTL15,SSTL135,SSTL135,O,Control,mcal_nc,8'bx,,,,SLOW,RDRV_48_48,0 18 | -------------------------------------------------------------------------------- /divider.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This IP is the synthetizable divider implementation. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | `timescale 1ns / 1ps 22 | 23 | module divder_unsigned #(parameter WIDTH = 8)(A,B,Res); 24 | //input and output ports. 25 | input [WIDTH-1:0] A; 26 | input [WIDTH-1:0] B; 27 | output [WIDTH-1:0] Res; 28 | //internal variables 29 | reg [WIDTH-1:0] Res = 0; 30 | reg [WIDTH-1:0] a1,b1; 31 | reg [WIDTH:0] p1; 32 | integer i; 33 | 34 | always@ (A or B) 35 | begin 36 | //initialize the variables. 37 | a1 = A; 38 | b1 = B; 39 | p1= 0; 40 | for(i=0;i < WIDTH;i=i+1) begin //start the for loop 41 | p1 = {p1[WIDTH-2:0],a1[WIDTH-1]}; 42 | a1[WIDTH-1:1] = a1[WIDTH-2:0]; 43 | p1 = p1-b1; 44 | if(p1[WIDTH-1] == 1) begin 45 | a1[0] = 0; 46 | p1 = p1 + b1; end 47 | else 48 | a1[0] = 1; 49 | end 50 | Res = a1; 51 | end 52 | 53 | endmodule 54 | 55 | -------------------------------------------------------------------------------- /encryption_cores/keccak.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This IP is the synthetizable keccak 224-256-384-512 one hash ped clk and one hash every 24 clk implementation. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | `timescale 1ns / 1ps 22 | 23 | `define PLEN 200 24 | 25 | /*** Helper macros to unroll the permutation. ***/ 26 | `define get_set_word(x, a) \ 27 | x[(((a) + 1) * 64) - 1 : (a) * 64] 28 | 29 | `define SHA3KECCAK_STAGE(out_cnt, cnt, stage, clk) \ 30 | clk \ 31 | begin \ 32 | b_a_a = 0; \ 33 | `get_set_word(b_a_a, 0) = `get_set_word(a_a1[cnt], 0) ^ `get_set_word(a_a1[cnt], 5) ^ `get_set_word(a_a1[cnt], 10) ^ `get_set_word(a_a1[cnt], 15) ^ `get_set_word(a_a1[cnt], 20); \ 34 | `get_set_word(b_a_a, 1) = `get_set_word(a_a1[cnt], 1) ^ `get_set_word(a_a1[cnt], 6) ^ `get_set_word(a_a1[cnt], 11) ^ `get_set_word(a_a1[cnt], 16) ^ `get_set_word(a_a1[cnt], 21); \ 35 | `get_set_word(b_a_a, 2) = `get_set_word(a_a1[cnt], 2) ^ `get_set_word(a_a1[cnt], 7) ^ `get_set_word(a_a1[cnt], 12) ^ `get_set_word(a_a1[cnt], 17) ^ `get_set_word(a_a1[cnt], 22); \ 36 | `get_set_word(b_a_a, 3) = `get_set_word(a_a1[cnt], 3) ^ `get_set_word(a_a1[cnt], 8) ^ `get_set_word(a_a1[cnt], 13) ^ `get_set_word(a_a1[cnt], 18) ^ `get_set_word(a_a1[cnt], 23); \ 37 | `get_set_word(b_a_a, 4) = `get_set_word(a_a1[cnt], 4) ^ `get_set_word(a_a1[cnt], 9) ^ `get_set_word(a_a1[cnt], 14) ^ `get_set_word(a_a1[cnt], 19) ^ `get_set_word(a_a1[cnt], 24); \ 38 | \ 39 | a_a2[cnt] = {(`PLEN * 8){1'b0}}; \ 40 | `get_set_word(a_a2[cnt], 0+0) = `get_set_word(a_a1[cnt], 0+0) ^ `get_set_word(b_a_a, (0+4) % 5) ^ rol64(`get_set_word(b_a_a, 0+1), 1); \ 41 | `get_set_word(a_a2[cnt], 5+0) = `get_set_word(a_a1[cnt], 5+0) ^ `get_set_word(b_a_a, (0+4) % 5) ^ rol64(`get_set_word(b_a_a, 0+1), 1); \ 42 | `get_set_word(a_a2[cnt], 10+0) = `get_set_word(a_a1[cnt], 10+0) ^ `get_set_word(b_a_a, (0+4) % 5) ^ rol64(`get_set_word(b_a_a, 0+1), 1); \ 43 | `get_set_word(a_a2[cnt], 15+0) = `get_set_word(a_a1[cnt], 15+0) ^ `get_set_word(b_a_a, (0+4) % 5) ^ rol64(`get_set_word(b_a_a, 0+1), 1); \ 44 | `get_set_word(a_a2[cnt], 20+0) = `get_set_word(a_a1[cnt], 20+0) ^ `get_set_word(b_a_a, (0+4) % 5) ^ rol64(`get_set_word(b_a_a, 0+1), 1); \ 45 | \ 46 | `get_set_word(a_a2[cnt], 0+1) = `get_set_word(a_a1[cnt], 0+1) ^ `get_set_word(b_a_a, (1+4) % 5) ^ rol64(`get_set_word(b_a_a, 1+1), 1); \ 47 | `get_set_word(a_a2[cnt], 5+1) = `get_set_word(a_a1[cnt], 5+1) ^ `get_set_word(b_a_a, (1+4) % 5) ^ rol64(`get_set_word(b_a_a, 1+1), 1); \ 48 | `get_set_word(a_a2[cnt], 10+1) = `get_set_word(a_a1[cnt], 10+1) ^ `get_set_word(b_a_a, (1+4) % 5) ^ rol64(`get_set_word(b_a_a, 1+1), 1); \ 49 | `get_set_word(a_a2[cnt], 15+1) = `get_set_word(a_a1[cnt], 15+1) ^ `get_set_word(b_a_a, (1+4) % 5) ^ rol64(`get_set_word(b_a_a, 1+1), 1); \ 50 | `get_set_word(a_a2[cnt], 20+1) = `get_set_word(a_a1[cnt], 20+1) ^ `get_set_word(b_a_a, (1+4) % 5) ^ rol64(`get_set_word(b_a_a, 1+1), 1); \ 51 | \ 52 | `get_set_word(a_a2[cnt], 0+2) = `get_set_word(a_a1[cnt], 0+2) ^ `get_set_word(b_a_a, (2+4) % 5) ^ rol64(`get_set_word(b_a_a, 2+1), 1); \ 53 | `get_set_word(a_a2[cnt], 5+2) = `get_set_word(a_a1[cnt], 5+2) ^ `get_set_word(b_a_a, (2+4) % 5) ^ rol64(`get_set_word(b_a_a, 2+1), 1); \ 54 | `get_set_word(a_a2[cnt], 10+2) = `get_set_word(a_a1[cnt], 10+2) ^ `get_set_word(b_a_a, (2+4) % 5) ^ rol64(`get_set_word(b_a_a, 2+1), 1); \ 55 | `get_set_word(a_a2[cnt], 15+2) = `get_set_word(a_a1[cnt], 15+2) ^ `get_set_word(b_a_a, (2+4) % 5) ^ rol64(`get_set_word(b_a_a, 2+1), 1); \ 56 | `get_set_word(a_a2[cnt], 20+2) = `get_set_word(a_a1[cnt], 20+2) ^ `get_set_word(b_a_a, (2+4) % 5) ^ rol64(`get_set_word(b_a_a, 2+1), 1); \ 57 | \ 58 | `get_set_word(a_a2[cnt], 0+3) = `get_set_word(a_a1[cnt], 0+3) ^ `get_set_word(b_a_a, (3+4) % 5) ^ rol64(`get_set_word(b_a_a, 3+1), 1); \ 59 | `get_set_word(a_a2[cnt], 5+3) = `get_set_word(a_a1[cnt], 5+3) ^ `get_set_word(b_a_a, (3+4) % 5) ^ rol64(`get_set_word(b_a_a, 3+1), 1); \ 60 | `get_set_word(a_a2[cnt], 10+3) = `get_set_word(a_a1[cnt], 10+3) ^ `get_set_word(b_a_a, (3+4) % 5) ^ rol64(`get_set_word(b_a_a, 3+1), 1); \ 61 | `get_set_word(a_a2[cnt], 15+3) = `get_set_word(a_a1[cnt], 15+3) ^ `get_set_word(b_a_a, (3+4) % 5) ^ rol64(`get_set_word(b_a_a, 3+1), 1); \ 62 | `get_set_word(a_a2[cnt], 20+3) = `get_set_word(a_a1[cnt], 20+3) ^ `get_set_word(b_a_a, (3+4) % 5) ^ rol64(`get_set_word(b_a_a, 3+1), 1); \ 63 | \ 64 | `get_set_word(a_a2[cnt], 0+4) = `get_set_word(a_a1[cnt], 0+4) ^ `get_set_word(b_a_a, (4+4) % 5) ^ rol64(`get_set_word(b_a_a, (4+1) % 5), 1); \ 65 | `get_set_word(a_a2[cnt], 5+4) = `get_set_word(a_a1[cnt], 5+4) ^ `get_set_word(b_a_a, (4+4) % 5) ^ rol64(`get_set_word(b_a_a, (4+1) % 5), 1); \ 66 | `get_set_word(a_a2[cnt], 10+4) = `get_set_word(a_a1[cnt], 10+4) ^ `get_set_word(b_a_a, (4+4) % 5) ^ rol64(`get_set_word(b_a_a, (4+1) % 5), 1); \ 67 | `get_set_word(a_a2[cnt], 15+4) = `get_set_word(a_a1[cnt], 15+4) ^ `get_set_word(b_a_a, (4+4) % 5) ^ rol64(`get_set_word(b_a_a, (4+1) % 5), 1); \ 68 | `get_set_word(a_a2[cnt], 20+4) = `get_set_word(a_a1[cnt], 20+4) ^ `get_set_word(b_a_a, (4+4) % 5) ^ rol64(`get_set_word(b_a_a, (4+1) % 5), 1); \ 69 | \ 70 | a_a3[cnt] = a_a2[cnt]; \ 71 | t = `get_set_word(a_a2[cnt], 1); \ 72 | b = `get_set_word(a_a2[cnt], pi0); \ 73 | `get_set_word(a_a3[cnt], pi0) = rol64(t, rho0); \ 74 | t = b; \ 75 | \ 76 | b = `get_set_word(a_a2[cnt], pi1); \ 77 | `get_set_word(a_a3[cnt], pi1) = rol64(t, rho1); \ 78 | t = b; \ 79 | \ 80 | b = `get_set_word(a_a2[cnt], pi2); \ 81 | `get_set_word(a_a3[cnt], pi2) = rol64(t, rho2); \ 82 | t = b; \ 83 | \ 84 | b = `get_set_word(a_a2[cnt], pi3); \ 85 | `get_set_word(a_a3[cnt], pi3) = rol64(t, rho3); \ 86 | t = b; \ 87 | \ 88 | b = `get_set_word(a_a2[cnt], pi4); \ 89 | `get_set_word(a_a3[cnt], pi4) = rol64(t, rho4); \ 90 | t = b; \ 91 | \ 92 | b = `get_set_word(a_a2[cnt], pi5); \ 93 | `get_set_word(a_a3[cnt], pi5) = rol64(t, rho5); \ 94 | t = b; \ 95 | \ 96 | b = `get_set_word(a_a2[cnt], pi6); \ 97 | `get_set_word(a_a3[cnt], pi6) = rol64(t, rho6); \ 98 | t = b; \ 99 | \ 100 | b = `get_set_word(a_a2[cnt], pi7); \ 101 | `get_set_word(a_a3[cnt], pi7) = rol64(t, rho7); \ 102 | t = b; \ 103 | \ 104 | b = `get_set_word(a_a2[cnt], pi8); \ 105 | `get_set_word(a_a3[cnt], pi8) = rol64(t, rho8); \ 106 | t = b; \ 107 | \ 108 | b = `get_set_word(a_a2[cnt], pi9); \ 109 | `get_set_word(a_a3[cnt], pi9) = rol64(t, rho9); \ 110 | t = b; \ 111 | \ 112 | b = `get_set_word(a_a2[cnt], pi10); \ 113 | `get_set_word(a_a3[cnt], pi10) = rol64(t, rho10); \ 114 | t = b; \ 115 | \ 116 | b = `get_set_word(a_a2[cnt], pi11); \ 117 | `get_set_word(a_a3[cnt], pi11) = rol64(t, rho11); \ 118 | t = b; \ 119 | \ 120 | b = `get_set_word(a_a2[cnt], pi12); \ 121 | `get_set_word(a_a3[cnt], pi12) = rol64(t, rho12); \ 122 | t = b; \ 123 | \ 124 | b = `get_set_word(a_a2[cnt], pi13); \ 125 | `get_set_word(a_a3[cnt], pi13) = rol64(t, rho13); \ 126 | t = b; \ 127 | \ 128 | b = `get_set_word(a_a2[cnt], pi14); \ 129 | `get_set_word(a_a3[cnt], pi14) = rol64(t, rho14); \ 130 | t = b; \ 131 | \ 132 | b = `get_set_word(a_a2[cnt], pi15); \ 133 | `get_set_word(a_a3[cnt], pi15) = rol64(t, rho15); \ 134 | t = b; \ 135 | \ 136 | b = `get_set_word(a_a2[cnt], pi16); \ 137 | `get_set_word(a_a3[cnt], pi16) = rol64(t, rho16); \ 138 | t = b; \ 139 | \ 140 | b = `get_set_word(a_a2[cnt], pi17); \ 141 | `get_set_word(a_a3[cnt], pi17) = rol64(t, rho17); \ 142 | t = b; \ 143 | \ 144 | b = `get_set_word(a_a2[cnt], pi18); \ 145 | `get_set_word(a_a3[cnt], pi18) = rol64(t, rho18); \ 146 | t = b; \ 147 | \ 148 | b = `get_set_word(a_a2[cnt], pi19); \ 149 | `get_set_word(a_a3[cnt], pi19) = rol64(t, rho19); \ 150 | t = b; \ 151 | \ 152 | b = `get_set_word(a_a2[cnt], pi20); \ 153 | `get_set_word(a_a3[cnt], pi20) = rol64(t, rho20); \ 154 | t = b; \ 155 | \ 156 | b = `get_set_word(a_a2[cnt], pi21); \ 157 | `get_set_word(a_a3[cnt], pi21) = rol64(t, rho21); \ 158 | t = b; \ 159 | \ 160 | b = `get_set_word(a_a2[cnt], pi22); \ 161 | `get_set_word(a_a3[cnt], pi22) = rol64(t, rho22); \ 162 | t = b; \ 163 | \ 164 | b = `get_set_word(a_a2[cnt], pi23); \ 165 | `get_set_word(a_a3[cnt], pi23) = rol64(t, rho23); \ 166 | \ 167 | a_a1[out_cnt] <= {(`PLEN * 8){1'b0}}; \ 168 | b_a_a = 0; \ 169 | `get_set_word(b_a_a, 0) = `get_set_word(a_a3[cnt], 0+0); \ 170 | `get_set_word(b_a_a, 1) = `get_set_word(a_a3[cnt], 0+1); \ 171 | `get_set_word(b_a_a, 2) = `get_set_word(a_a3[cnt], 0+2); \ 172 | `get_set_word(b_a_a, 3) = `get_set_word(a_a3[cnt], 0+3); \ 173 | `get_set_word(b_a_a, 4) = `get_set_word(a_a3[cnt], 0+4); \ 174 | `get_set_word(a_a1[out_cnt], 0+0) <= `get_set_word(b_a_a, 0) ^ (~`get_set_word(b_a_a, (0+1) % 5) & `get_set_word(b_a_a, (0+2) % 5)) ^ select_RC(stage); \ 175 | `get_set_word(a_a1[out_cnt], 0+1) <= `get_set_word(b_a_a, 1) ^ (~`get_set_word(b_a_a, (1+1) % 5) & `get_set_word(b_a_a, (1+2) % 5)); \ 176 | `get_set_word(a_a1[out_cnt], 0+2) <= `get_set_word(b_a_a, 2) ^ (~`get_set_word(b_a_a, (2+1) % 5) & `get_set_word(b_a_a, (2+2) % 5)); \ 177 | `get_set_word(a_a1[out_cnt], 0+3) <= `get_set_word(b_a_a, 3) ^ (~`get_set_word(b_a_a, (3+1) % 5) & `get_set_word(b_a_a, (3+2) % 5)); \ 178 | `get_set_word(a_a1[out_cnt], 0+4) <= `get_set_word(b_a_a, 4) ^ (~`get_set_word(b_a_a, (4+1) % 5) & `get_set_word(b_a_a, (4+2) % 5)); \ 179 | \ 180 | `get_set_word(b_a_a, 0) = `get_set_word(a_a3[cnt], 5+0); \ 181 | `get_set_word(b_a_a, 1) = `get_set_word(a_a3[cnt], 5+1); \ 182 | `get_set_word(b_a_a, 2) = `get_set_word(a_a3[cnt], 5+2); \ 183 | `get_set_word(b_a_a, 3) = `get_set_word(a_a3[cnt], 5+3); \ 184 | `get_set_word(b_a_a, 4) = `get_set_word(a_a3[cnt], 5+4); \ 185 | `get_set_word(a_a1[out_cnt], 5+0) <= `get_set_word(b_a_a, 0) ^ (~`get_set_word(b_a_a, (0+1) % 5) & `get_set_word(b_a_a, (0+2) % 5)); \ 186 | `get_set_word(a_a1[out_cnt], 5+1) <= `get_set_word(b_a_a, 1) ^ (~`get_set_word(b_a_a, (1+1) % 5) & `get_set_word(b_a_a, (1+2) % 5)); \ 187 | `get_set_word(a_a1[out_cnt], 5+2) <= `get_set_word(b_a_a, 2) ^ (~`get_set_word(b_a_a, (2+1) % 5) & `get_set_word(b_a_a, (2+2) % 5)); \ 188 | `get_set_word(a_a1[out_cnt], 5+3) <= `get_set_word(b_a_a, 3) ^ (~`get_set_word(b_a_a, (3+1) % 5) & `get_set_word(b_a_a, (3+2) % 5)); \ 189 | `get_set_word(a_a1[out_cnt], 5+4) <= `get_set_word(b_a_a, 4) ^ (~`get_set_word(b_a_a, (4+1) % 5) & `get_set_word(b_a_a, (4+2) % 5)); \ 190 | \ 191 | `get_set_word(b_a_a, 0) = `get_set_word(a_a3[cnt], 10+0); \ 192 | `get_set_word(b_a_a, 1) = `get_set_word(a_a3[cnt], 10+1); \ 193 | `get_set_word(b_a_a, 2) = `get_set_word(a_a3[cnt], 10+2); \ 194 | `get_set_word(b_a_a, 3) = `get_set_word(a_a3[cnt], 10+3); \ 195 | `get_set_word(b_a_a, 4) = `get_set_word(a_a3[cnt], 10+4); \ 196 | `get_set_word(a_a1[out_cnt], 10+0) <= `get_set_word(b_a_a, 0) ^ (~`get_set_word(b_a_a, (0+1) % 5) & `get_set_word(b_a_a, (0+2) % 5)); \ 197 | `get_set_word(a_a1[out_cnt], 10+1) <= `get_set_word(b_a_a, 1) ^ (~`get_set_word(b_a_a, (1+1) % 5) & `get_set_word(b_a_a, (1+2) % 5)); \ 198 | `get_set_word(a_a1[out_cnt], 10+2) <= `get_set_word(b_a_a, 2) ^ (~`get_set_word(b_a_a, (2+1) % 5) & `get_set_word(b_a_a, (2+2) % 5)); \ 199 | `get_set_word(a_a1[out_cnt], 10+3) <= `get_set_word(b_a_a, 3) ^ (~`get_set_word(b_a_a, (3+1) % 5) & `get_set_word(b_a_a, (3+2) % 5)); \ 200 | `get_set_word(a_a1[out_cnt], 10+4) <= `get_set_word(b_a_a, 4) ^ (~`get_set_word(b_a_a, (4+1) % 5) & `get_set_word(b_a_a, (4+2) % 5)); \ 201 | \ 202 | `get_set_word(b_a_a, 0) = `get_set_word(a_a3[cnt], 15+0); \ 203 | `get_set_word(b_a_a, 1) = `get_set_word(a_a3[cnt], 15+1); \ 204 | `get_set_word(b_a_a, 2) = `get_set_word(a_a3[cnt], 15+2); \ 205 | `get_set_word(b_a_a, 3) = `get_set_word(a_a3[cnt], 15+3); \ 206 | `get_set_word(b_a_a, 4) = `get_set_word(a_a3[cnt], 15+4); \ 207 | `get_set_word(a_a1[out_cnt], 15+0) <= `get_set_word(b_a_a, 0) ^ (~`get_set_word(b_a_a, (0+1) % 5) & `get_set_word(b_a_a, (0+2) % 5)); \ 208 | `get_set_word(a_a1[out_cnt], 15+1) <= `get_set_word(b_a_a, 1) ^ (~`get_set_word(b_a_a, (1+1) % 5) & `get_set_word(b_a_a, (1+2) % 5)); \ 209 | `get_set_word(a_a1[out_cnt], 15+2) <= `get_set_word(b_a_a, 2) ^ (~`get_set_word(b_a_a, (2+1) % 5) & `get_set_word(b_a_a, (2+2) % 5)); \ 210 | `get_set_word(a_a1[out_cnt], 15+3) <= `get_set_word(b_a_a, 3) ^ (~`get_set_word(b_a_a, (3+1) % 5) & `get_set_word(b_a_a, (3+2) % 5)); \ 211 | `get_set_word(a_a1[out_cnt], 15+4) <= `get_set_word(b_a_a, 4) ^ (~`get_set_word(b_a_a, (4+1) % 5) & `get_set_word(b_a_a, (4+2) % 5)); \ 212 | \ 213 | `get_set_word(b_a_a, 0) = `get_set_word(a_a3[cnt], 20+0); \ 214 | `get_set_word(b_a_a, 1) = `get_set_word(a_a3[cnt], 20+1); \ 215 | `get_set_word(b_a_a, 2) = `get_set_word(a_a3[cnt], 20+2); \ 216 | `get_set_word(b_a_a, 3) = `get_set_word(a_a3[cnt], 20+3); \ 217 | `get_set_word(b_a_a, 4) = `get_set_word(a_a3[cnt], 20+4); \ 218 | `get_set_word(a_a1[out_cnt], 20+0) <= `get_set_word(b_a_a, 0) ^ (~`get_set_word(b_a_a, (0+1) % 5) & `get_set_word(b_a_a, (0+2) % 5)); \ 219 | `get_set_word(a_a1[out_cnt], 20+1) <= `get_set_word(b_a_a, 1) ^ (~`get_set_word(b_a_a, (1+1) % 5) & `get_set_word(b_a_a, (1+2) % 5)); \ 220 | `get_set_word(a_a1[out_cnt], 20+2) <= `get_set_word(b_a_a, 2) ^ (~`get_set_word(b_a_a, (2+1) % 5) & `get_set_word(b_a_a, (2+2) % 5)); \ 221 | `get_set_word(a_a1[out_cnt], 20+3) <= `get_set_word(b_a_a, 3) ^ (~`get_set_word(b_a_a, (3+1) % 5) & `get_set_word(b_a_a, (3+2) % 5)); \ 222 | `get_set_word(a_a1[out_cnt], 20+4) <= `get_set_word(b_a_a, 4) ^ (~`get_set_word(b_a_a, (4+1) % 5) & `get_set_word(b_a_a, (4+2) % 5)); \ 223 | end 224 | 225 | 226 | module keccak_512 # ( 227 | parameter PIPELINED = 1, 228 | parameter SINGLECYCLE = 0, 229 | parameter OUT_WIDTH = 512)/* Supports all four modes of output. */ 230 | ( 231 | input rst, 232 | input clk, 233 | input [((`PLEN - (OUT_WIDTH / 4)) * 8) - 1:0]in,/* Input width is automatically calculated. */ 234 | input [7:0]in_len,/* Number of bytes on input, the rest of bytes will be cleared. */ 235 | input [7:0]delimiter,/* This delimiter can be custom, default is 0'h01. */ 236 | output [OUT_WIDTH - 1:0]out, 237 | input load,//Used only when PIPELINED == 0 238 | output ready//Used only when PIPELINED == 0 239 | ); 240 | 241 | /*** Constants. ***/ 242 | localparam rho0 = 1; 243 | localparam rho1 = 3; 244 | localparam rho2 = 6; 245 | localparam rho3 = 10; 246 | localparam rho4 = 15; 247 | localparam rho5 = 21; 248 | localparam rho6 = 28; 249 | localparam rho7 = 36; 250 | localparam rho8 = 45; 251 | localparam rho9 = 55; 252 | localparam rho10 = 2; 253 | localparam rho11 = 14; 254 | localparam rho12 = 27; 255 | localparam rho13 = 41; 256 | localparam rho14 = 56; 257 | localparam rho15 = 8; 258 | localparam rho16 = 25; 259 | localparam rho17 = 43; 260 | localparam rho18 = 62; 261 | localparam rho19 = 18; 262 | localparam rho20 = 39; 263 | localparam rho21 = 61; 264 | localparam rho22 = 20; 265 | localparam rho23 = 44; 266 | 267 | localparam pi0 = 10; 268 | localparam pi1 = 7; 269 | localparam pi2 = 11; 270 | localparam pi3 = 17; 271 | localparam pi4 = 18; 272 | localparam pi5 = 3; 273 | localparam pi6 = 5; 274 | localparam pi7 = 16; 275 | localparam pi8 = 8; 276 | localparam pi9 = 21; 277 | localparam pi10 = 24; 278 | localparam pi11 = 4; 279 | localparam pi12 = 15; 280 | localparam pi13 = 23; 281 | localparam pi14 = 19; 282 | localparam pi15 = 13; 283 | localparam pi16 = 12; 284 | localparam pi17 = 2; 285 | localparam pi18 = 20; 286 | localparam pi19 = 14; 287 | localparam pi20 = 22; 288 | localparam pi21 = 9; 289 | localparam pi22 = 6; 290 | localparam pi23 = 1; 291 | 292 | localparam RC0 = 64'h0000000000000001; 293 | localparam RC1 = 64'h0000000000008082; 294 | localparam RC2 = 64'h800000000000808a; 295 | localparam RC3 = 64'h8000000080008000; 296 | localparam RC4 = 64'h000000000000808b; 297 | localparam RC5 = 64'h0000000080000001; 298 | localparam RC6 = 64'h8000000080008081; 299 | localparam RC7 = 64'h8000000000008009; 300 | localparam RC8 = 64'h000000000000008a; 301 | localparam RC9 = 64'h0000000000000088; 302 | localparam RC10 = 64'h0000000080008009; 303 | localparam RC11 = 64'h000000008000000a; 304 | localparam RC12 = 64'h000000008000808b; 305 | localparam RC13 = 64'h800000000000008b; 306 | localparam RC14 = 64'h8000000000008089; 307 | localparam RC15 = 64'h8000000000008003; 308 | localparam RC16 = 64'h8000000000008002; 309 | localparam RC17 = 64'h8000000000000080; 310 | localparam RC18 = 64'h000000000000800a; 311 | localparam RC19 = 64'h800000008000000a; 312 | localparam RC20 = 64'h8000000080008081; 313 | localparam RC21 = 64'h8000000000008080; 314 | localparam RC22 = 64'h0000000080000001; 315 | localparam RC23 = 64'h8000000080008008; 316 | 317 | wire clk_int = rst ? 1'b0 : clk; 318 | 319 | 320 | reg [(`PLEN * 8) - 1:0]a_a1[0:24]; 321 | reg [(`PLEN * 8) - 1:0]a_a2[0:24]; 322 | reg [(`PLEN * 8) - 1:0]a_a3[0:24]; 323 | 324 | reg [320 - 1 : 0]b_a_a; 325 | reg [320 - 1 : 0]b_a_tmp; 326 | 327 | wire [(`PLEN * 8) - 1 : 0]delimiter1_int = (delimiter << (in_len * 8)); 328 | wire [(`PLEN * 8) - 1 : 0]delimiter2_int = (8'h80 << ((`PLEN - (OUT_WIDTH / 4)) - 1) * 8); 329 | wire [(`PLEN * 8) - 1 : 0]delimiters_int = delimiter1_int | delimiter2_int; 330 | //wire [(`PLEN * 8) - 1 : 0]input_mask = (({{(`PLEN * 8)-2{1'b0}}, 1'b1} << (in_len << 3)) - 1); 331 | 332 | //`define rol64(x, s) (((x) << s) | ((x) >> (64 - s))) 333 | function [63:0]rol64; 334 | input [63:0]x; 335 | input [5:0]s; 336 | begin 337 | case(s) 338 | 0: rol64 = {x}; 339 | 1: rol64 = {x[62:0], x[63]}; 340 | 2: rol64 = {x[61:0], x[63:62]}; 341 | 3: rol64 = {x[60:0], x[63:61]}; 342 | 4: rol64 = {x[59:0], x[63:60]}; 343 | 5: rol64 = {x[58:0], x[63:59]}; 344 | 6: rol64 = {x[57:0], x[63:58]}; 345 | 7: rol64 = {x[56:0], x[63:57]}; 346 | 8: rol64 = {x[55:0], x[63:56]}; 347 | 9: rol64 = {x[54:0], x[63:55]}; 348 | 10: rol64 = {x[53:0], x[63:54]}; 349 | 11: rol64 = {x[52:0], x[63:53]}; 350 | 12: rol64 = {x[51:0], x[63:52]}; 351 | 13: rol64 = {x[50:0], x[63:51]}; 352 | 14: rol64 = {x[49:0], x[63:50]}; 353 | 15: rol64 = {x[48:0], x[63:49]}; 354 | 16: rol64 = {x[47:0], x[63:48]}; 355 | 17: rol64 = {x[46:0], x[63:47]}; 356 | 18: rol64 = {x[45:0], x[63:46]}; 357 | 19: rol64 = {x[44:0], x[63:45]}; 358 | 20: rol64 = {x[43:0], x[63:44]}; 359 | 21: rol64 = {x[42:0], x[63:43]}; 360 | 22: rol64 = {x[41:0], x[63:42]}; 361 | 23: rol64 = {x[40:0], x[63:41]}; 362 | 24: rol64 = {x[39:0], x[63:40]}; 363 | 25: rol64 = {x[38:0], x[63:39]}; 364 | 26: rol64 = {x[37:0], x[63:38]}; 365 | 27: rol64 = {x[36:0], x[63:37]}; 366 | 28: rol64 = {x[35:0], x[63:36]}; 367 | 29: rol64 = {x[34:0], x[63:35]}; 368 | 30: rol64 = {x[33:0], x[63:34]}; 369 | 31: rol64 = {x[32:0], x[63:33]}; 370 | 32: rol64 = {x[31:0], x[63:32]}; 371 | 33: rol64 = {x[30:0], x[63:31]}; 372 | 34: rol64 = {x[29:0], x[63:30]}; 373 | 35: rol64 = {x[28:0], x[63:29]}; 374 | 36: rol64 = {x[27:0], x[63:28]}; 375 | 37: rol64 = {x[26:0], x[63:27]}; 376 | 38: rol64 = {x[25:0], x[63:26]}; 377 | 39: rol64 = {x[24:0], x[63:25]}; 378 | 40: rol64 = {x[23:0], x[63:24]}; 379 | 41: rol64 = {x[22:0], x[63:23]}; 380 | 42: rol64 = {x[21:0], x[63:22]}; 381 | 43: rol64 = {x[20:0], x[63:21]}; 382 | 44: rol64 = {x[19:0], x[63:20]}; 383 | 45: rol64 = {x[18:0], x[63:19]}; 384 | 46: rol64 = {x[17:0], x[63:18]}; 385 | 47: rol64 = {x[16:0], x[63:17]}; 386 | 48: rol64 = {x[15:0], x[63:16]}; 387 | 49: rol64 = {x[14:0], x[63:15]}; 388 | 50: rol64 = {x[13:0], x[63:14]}; 389 | 51: rol64 = {x[12:0], x[63:13]}; 390 | 52: rol64 = {x[11:0], x[63:12]}; 391 | 53: rol64 = {x[10:0], x[63:11]}; 392 | 54: rol64 = {x[09:0], x[63:10]}; 393 | 55: rol64 = {x[08:0], x[63:09]}; 394 | 56: rol64 = {x[07:0], x[63:08]}; 395 | 57: rol64 = {x[06:0], x[63:07]}; 396 | 58: rol64 = {x[05:0], x[63:06]}; 397 | 59: rol64 = {x[04:0], x[63:05]}; 398 | 60: rol64 = {x[03:0], x[63:04]}; 399 | 61: rol64 = {x[02:0], x[63:03]}; 400 | 62: rol64 = {x[01:0], x[63:02]}; 401 | 63: rol64 = {x[00], x[63:01]}; 402 | endcase 403 | end 404 | endfunction 405 | 406 | function [63:0]select_RC; 407 | input [4:0]s; 408 | begin 409 | case(s) 410 | 0: select_RC = RC0; 411 | 1: select_RC = RC1; 412 | 2: select_RC = RC2; 413 | 3: select_RC = RC3; 414 | 4: select_RC = RC4; 415 | 5: select_RC = RC5; 416 | 6: select_RC = RC6; 417 | 7: select_RC = RC7; 418 | 8: select_RC = RC8; 419 | 9: select_RC = RC9; 420 | 10: select_RC = RC10; 421 | 11: select_RC = RC11; 422 | 12: select_RC = RC12; 423 | 13: select_RC = RC13; 424 | 14: select_RC = RC14; 425 | 15: select_RC = RC15; 426 | 16: select_RC = RC16; 427 | 17: select_RC = RC17; 428 | 18: select_RC = RC18; 429 | 19: select_RC = RC19; 430 | 20: select_RC = RC20; 431 | 21: select_RC = RC21; 432 | 22: select_RC = RC22; 433 | 23: select_RC = RC23; 434 | default: select_RC = 0; 435 | endcase 436 | end 437 | endfunction 438 | 439 | reg [63:0]t; 440 | reg [63:0]b; 441 | genvar cnt; 442 | reg [4:0]stage_cnt; 443 | 444 | /*always @ (*) 445 | begin 446 | in_int = 0; 447 | in_int <= in; 448 | end*/ 449 | 450 | always @ (*) 451 | begin 452 | if(PIPELINED == 0 & SINGLECYCLE == 0) 453 | begin 454 | if(load) 455 | a_a1[0] <= in ^ delimiters_int; 456 | else 457 | a_a1[0] <= a_a1[1]; 458 | end 459 | else 460 | a_a1[0] <= in ^ delimiters_int; 461 | end 462 | 463 | always @ (posedge clk) 464 | begin 465 | if(PIPELINED == 0 & SINGLECYCLE == 0) 466 | begin 467 | if(rst | load) 468 | stage_cnt <= 0; 469 | else 470 | begin 471 | if(stage_cnt != 24) 472 | begin 473 | `SHA3KECCAK_STAGE(1, 0, stage_cnt, ) 474 | stage_cnt <= stage_cnt + 1; 475 | end 476 | end 477 | end 478 | end 479 | 480 | generate 481 | for(cnt = 0; cnt < 24; cnt = cnt + 1) 482 | begin: L0 483 | if(SINGLECYCLE == 0) 484 | begin 485 | if(PIPELINED == 1) 486 | begin 487 | `SHA3KECCAK_STAGE(cnt + 1, cnt, cnt, always @ (posedge clk)) 488 | end 489 | end 490 | else 491 | begin 492 | `SHA3KECCAK_STAGE(cnt + 1, cnt, cnt, always @ (a_a1[cnt])) 493 | end 494 | end 495 | endgenerate 496 | 497 | /*generate 498 | for(cnt = 0; cnt < OUT_WIDTH; cnt = cnt + 8) 499 | begin: REORDER_OUT 500 | assign out[cnt + 7: cnt] = a_a1[24][OUT_WIDTH - cnt - 1:OUT_WIDTH - (cnt + 8)]; 501 | end 502 | endgenerate*/ 503 | 504 | assign out = SINGLECYCLE == 0 ? ((PIPELINED == 0) ? (stage_cnt == 24 ? a_a1[0] : 0) : a_a1[24]) : a_a1[24]; 505 | assign ready = stage_cnt == 24; 506 | 507 | endmodule 508 | -------------------------------------------------------------------------------- /fft.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 08/15/2017 08:09:27 PM 7 | // Design Name: 8 | // Module Name: fft 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | module load32( 22 | output [31:0]out, 23 | input [31:0]in 24 | ); 25 | assign out = in; 26 | endmodule 27 | 28 | function real loadReal; 29 | input real in; 30 | begin 31 | loadReal = in; 32 | end 33 | endfunction 34 | 35 | module fft # ( 36 | parameter WIDTH = 8)( 37 | input rst, 38 | input clk 39 | ); 40 | 41 | real sintable[(2**WIDTH) / 2:0]; 42 | real costable[(2**WIDTH) / 2:0]; 43 | reg [31:0]bitReverse[2**WIDTH:0]; 44 | 45 | reg[WIDTH-1:0]k; 46 | reg [WIDTH-1:0]r; 47 | function [9:0] reverseBitInit; 48 | input [9:0] i; 49 | begin 50 | for (k=0; k> 1; 55 | end 56 | end 57 | endfunction 58 | 59 | localparam real PI = 3.141592653589793; 60 | genvar count_init; 61 | generate 62 | for (count_init = 0; count_init < WIDTH; count_init = count_init + 1) 63 | begin: FFT_INIT 64 | //load32(bitReverse[count_init], reverseBitInit(count_init)); 65 | //real j = loadReal(2.0 * PI * count_init / (2**WIDTH)); 66 | //real costable = loadReal(cos(j)); 67 | //real sintable = loadReal(sin(j)); 68 | end 69 | endgenerate 70 | endmodule 71 | -------------------------------------------------------------------------------- /flipflop.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This IP is the synthetizable flip-flops implementation. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | `timescale 1ns / 1ps 22 | 23 | //JK flip flop module 24 | module flip_flop_jkrse(J,K,Clk,R,S,CE,Qout); 25 | input J,K; //inputs 26 | input Clk; //Clock 27 | input R; //synchronous reset (R) 28 | input S; //synchronous set (S) 29 | input CE; //clock enable (CE) 30 | output Qout; //data output (Q) 31 | 32 | //Internal variable 33 | reg Qout; 34 | 35 | always@ (posedge(Clk)) //Everything is synchronous to positive edge of clock 36 | begin 37 | if(R == 1) //reset has highest priority. 38 | Qout = 0; 39 | else 40 | if(S == 1) //set has next priority 41 | Qout = 1; 42 | else 43 | if(CE == 1) //J,K values are considered only when CE is ON. 44 | if(J == 0 && K == 0) 45 | Qout = Qout; //no change 46 | else if(J == 0 && K == 1) 47 | Qout = 0; //reset 48 | else if(J == 1 && K == 0) 49 | Qout = 1; //set 50 | else 51 | Qout = ~Qout; //toggle 52 | else 53 | Qout = Qout; //no change 54 | end 55 | 56 | endmodule 57 | -------------------------------------------------------------------------------- /i2c.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 01/18/2017 03:51:34 PM 7 | // Design Name: 8 | // Module Name: i2c_master 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | `define I2C_DEBUG 23 | 24 | module i2c_master( 25 | input clk,/* Peripheral clock/not necessary to be core clock, the core clock can be different (input) */ 26 | input rst,/* Asynchronus reset, is mandatory to provide this signal, active on posedge (input) */ 27 | input [7:0]dataIn,/* In data */ 28 | output reg [7:0]dataOut,/* Out data */ 29 | input wr,/* Send data, asynchronus with 'clk' , active on posedge or negedge(input) */ 30 | input rd,/* Read data, , asynchronus with 'clk' , active on posedge or negedge (input) */ 31 | output buffempty,/* '1' if transmit buffer is empty (output) */ 32 | input prescaller,/* The prescaller divider is = (1 << prescaller) value between 0 and 7 for dividers by:1,2,4,8,16,32,64,126 and 256 (input)*/ 33 | input dirsend,/* 0 = receiver, 1 = transmitter. */ 34 | output reg scl, 35 | output sda, 36 | output reg senderr,/* If you try to send a character if send buffer is full this bit is set to '1', this can be ignored and if is '1' does not affect the interface (output) */ 37 | input res_senderr,/* To reset 'senderr' signal write '1' wait half core clock and and after '0' to this bit, is asynchronous with 'clk' (input)*/ 38 | output chartransferred,/* Is set to '1' if a character is received, if you read the receive buffe this bit will go '0', if you ignore it and continue to send data this bit will remain '1' until you read the read register (output) */ 39 | output reg ack, 40 | input resendstart, 41 | output reg arbitrationlost 42 | ); 43 | 44 | parameter PRESCALLER_SIZE = 8; 45 | 46 | reg dirsendint; 47 | 48 | reg charreceivedp; 49 | reg charreceivedn; 50 | 51 | reg inbufffullp; 52 | reg inbufffulln; 53 | 54 | reg [7:0]input_buffer; 55 | reg [7:0]output_buffer; 56 | 57 | assign buffempty = ~(inbufffullp ^ inbufffulln); 58 | reg [2:0]prescallerbuff; 59 | 60 | /* 61 | * You need to put the data on the bus and wait a half of core clock to assert the wr signal(see simulation). 62 | */ 63 | always @ (posedge wr) 64 | begin 65 | if(wr && inbufffullp == inbufffulln && buffempty) 66 | begin 67 | input_buffer <= dataIn; 68 | end 69 | end 70 | 71 | always @ (posedge wr or posedge res_senderr or posedge rst) 72 | begin 73 | if(rst) 74 | begin 75 | inbufffullp <= 1'b0; 76 | senderr <= 1'b0; 77 | prescallerbuff <= 3'b000; 78 | end 79 | else 80 | if(res_senderr) 81 | senderr <= 1'b0; 82 | else 83 | if(wr && inbufffullp == inbufffulln && buffempty) 84 | begin 85 | inbufffullp <= ~inbufffullp; 86 | prescallerbuff = prescaller; 87 | end 88 | else 89 | if(!buffempty) 90 | senderr <= 1'b1; 91 | end 92 | 93 | /* 94 | * You need to assert rd signal, wait a half core clock and after read the data(see simulation). 95 | */ 96 | always @ (posedge rd or posedge rst) 97 | begin 98 | if(rst) 99 | charreceivedn <= 1'b0; 100 | else 101 | if(charreceivedp != charreceivedn) 102 | charreceivedn <= ~charreceivedn; 103 | end 104 | 105 | reg resendstartp; 106 | reg resendstartn; 107 | wire resendstartw; 108 | /* 109 | * You need to assert rd signal, wait a half core clock and after read the data(see simulation). 110 | */ 111 | always @ (posedge resendstart or posedge rst) 112 | begin 113 | if(rst) 114 | resendstartn <= 1'b0; 115 | else 116 | if(resendstartp == resendstartn) 117 | resendstartn <= ~resendstartn; 118 | end 119 | //assign sendstopw = sendstopp ^ sendstopn; 120 | 121 | /***********************************************/ 122 | /************ !Asynchronus send ****************/ 123 | /***********************************************/ 124 | reg [7:0]shift_reg_out; 125 | reg [7:0]shift_reg_in; 126 | reg [5:0]sckint; 127 | //reg sckintn; 128 | parameter dirint_send = 1'b0; 129 | parameter dirint_rec = 1'b1; 130 | 131 | reg lsbfirstint; 132 | reg [1:0]modeint; 133 | 134 | parameter state_idle = 2'b00; 135 | parameter state_busy = 2'b01; 136 | reg [1:0]state; 137 | 138 | parameter statebusy_startphase1 = 4'b0000; 139 | parameter statebusy_startphase2 = 4'b0001; 140 | parameter statebusy_startphase3 = 4'b0010; 141 | parameter statebusy_startphase4 = 4'b0011; 142 | parameter statebusy_start = 4'b0100; 143 | parameter statebusy_send = 4'b0101; 144 | parameter statebusy_stopphase1 = 4'b0110; 145 | parameter statebusy_stopphase2 = 4'b0111; 146 | 147 | parameter statebusy_restartphase1 = 4'b1000; 148 | parameter statebusy_restartphase2 = 4'b1001; 149 | parameter statebusy_restartphase3 = 4'b1010; 150 | 151 | reg [3:0]statebusy; 152 | 153 | reg sda_out; 154 | 155 | reg _dirsendint; 156 | 157 | always @ (posedge clk or posedge rst) 158 | begin 159 | if(rst) 160 | begin 161 | /* 162 | * Reset all bits modifyed by this function. 163 | */ 164 | inbufffulln <= 1'b0; 165 | resendstartp <= 1'b0; 166 | _dirsendint <= 1'b1; 167 | dirsendint <= 1'b1; 168 | state <= state_idle; 169 | statebusy <= statebusy_startphase1; 170 | shift_reg_out <= {8{1'b0}}; 171 | shift_reg_in <= {8{1'b0}}; 172 | sckint <= {6{1'b0}}; 173 | output_buffer <= {8{1'b0}}; 174 | charreceivedp <= 1'b0; 175 | lsbfirstint <= 1'b0; 176 | arbitrationlost <= 1'b0; 177 | modeint <= 2'b00; 178 | ack <= 1'b1; 179 | sda_out <= 1'b1; 180 | scl <= 1'b1; 181 | end 182 | else 183 | begin 184 | case(state) 185 | state_idle: 186 | begin 187 | /* 188 | * Wait here for a new byte to be pushed on send buff. 189 | */ 190 | if(inbufffullp != inbufffulln) 191 | begin 192 | inbufffulln <= ~inbufffulln; 193 | shift_reg_out <= input_buffer; 194 | shift_reg_in <= {8{1'b0}}; 195 | _dirsendint <= 1'b1; 196 | state <= state_busy; 197 | arbitrationlost <= 1'b0; 198 | statebusy <= statebusy_startphase1; 199 | dirsendint <= dirsend; 200 | end 201 | end 202 | state_busy: 203 | begin 204 | case(statebusy) 205 | /* 206 | * From here begin to create 'repeat start' condition. 207 | */ 208 | statebusy_restartphase1:/* Begin resend start sequency */ 209 | begin 210 | scl <= 1'b0; 211 | _dirsendint <= 1'b1; 212 | statebusy <= statebusy_restartphase2; 213 | end 214 | statebusy_restartphase2: 215 | begin 216 | sda_out <= 1'b1; 217 | statebusy <= statebusy_restartphase3; 218 | end 219 | statebusy_restartphase3: 220 | begin 221 | scl <= 1'b1; 222 | sckint[5:0] <= 6'b000000; 223 | statebusy <= statebusy_startphase1; 224 | end 225 | /* 226 | * From here begin to create 'start' condition. 227 | */ 228 | statebusy_startphase1: 229 | begin 230 | scl <= 1'b1; 231 | sda_out <= 1'b0; 232 | statebusy <= statebusy_startphase2; 233 | end 234 | statebusy_startphase2: 235 | begin 236 | scl <= 1'b0; 237 | statebusy <= statebusy_startphase3; 238 | end 239 | /* 240 | * Put first bit to sda. 241 | */ 242 | statebusy_startphase3: 243 | begin 244 | sda_out <= shift_reg_out[7]; 245 | statebusy <= statebusy_startphase4; 246 | _dirsendint <= dirsendint; 247 | end 248 | statebusy_startphase4: 249 | begin 250 | statebusy <= statebusy_send; 251 | scl <= 1'b1; 252 | end 253 | /* 254 | * From here begin to create bit read/write conditions. 255 | */ 256 | statebusy_send:/* Send/Receive data */ 257 | begin 258 | /* 259 | * Bit all, cycle all. 260 | */ 261 | sckint <= sckint + 1; 262 | /* 263 | * Bit before first bit, cycle 2. 264 | * Set to transmit. 265 | */ 266 | if(sckint[5:0] == 6'b111110 && dirsendint) 267 | _dirsendint <= 1'b1; 268 | /* 269 | * Bit 1, cycle 1. 270 | * Set to transmit. 271 | */ 272 | if(sckint[5:0] == 6'b000101) 273 | scl <= 1'b0; 274 | /* 275 | * Bit 9(stop), cycle 0. 276 | * If no char on buffer a STOP will be send, from here begin the STOP. 277 | */ 278 | if(sckint[5:0] == 6'b100100) 279 | begin 280 | sckint <= {6{1'b0}}; 281 | if(inbufffullp == inbufffulln) 282 | begin 283 | scl <= 1'b1; 284 | end 285 | statebusy <= statebusy_stopphase1; 286 | _dirsendint <= 1'b1; 287 | sda_out <= 1'b1; 288 | end 289 | else 290 | /* 291 | * Bit all except 9(stop), cycle 0. 292 | * On ACK time will verify if need to send another character without STOP. 293 | */ 294 | if(sckint[1:0] == 2'b00) 295 | begin 296 | /* 297 | * Bit all except 8(ack) and 9(stop), cycle 0. 298 | * Here will take the data from SDA pin. 299 | */ 300 | if(sckint[5:2] != 4'b1000 && sckint[5:2] != 4'b1001) 301 | begin 302 | shift_reg_in <= (shift_reg_in << 1) | sda; 303 | /* 304 | * Check if the input is the same like output, if different signify thas it lost arbitration. 305 | */ 306 | if(sda != sda_out) 307 | begin 308 | /* 309 | * Entirely release the buss and go to Idle state. 310 | */ 311 | arbitrationlost <= 1'b1; 312 | /* 313 | * Next cycle will enter in idle state. 314 | */ 315 | state <= state_idle; 316 | statebusy <= statebusy_send; 317 | end 318 | end 319 | else 320 | begin 321 | /* 322 | * Bit 8(ack), cycle 0. 323 | * Here is the time to get the ack from the sda pin. 324 | */ 325 | if(sckint[5:2] == 4'b1000) 326 | begin 327 | /* 328 | * Take the ack bit. 329 | */ 330 | ack <= sda; 331 | /* 332 | * Check if the send buffer is full. 333 | */ 334 | if(inbufffulln != inbufffullp) 335 | begin 336 | /* 337 | * If send buff is full, continue to send. 338 | */ 339 | inbufffulln <= ~inbufffulln; 340 | shift_reg_out <= input_buffer; 341 | shift_reg_in <= {8{1'b0}}; 342 | /* 343 | * Delay 2 cycles before sending new character. 344 | */ 345 | sckint <= 6'b111101; 346 | /* 347 | * Check if need to resend a start sequency. 348 | */ 349 | if(resendstartp != resendstartn) 350 | begin 351 | /* 352 | * Resend start sequency. 353 | */ 354 | resendstartp <= ~resendstartp; 355 | /* 356 | * Next cycle wil begin the restart condition. 357 | */ 358 | //state <= state_busy; 359 | statebusy <= statebusy_restartphase1; 360 | end 361 | else 362 | /* 363 | * Continue to send data. 364 | */ 365 | begin 366 | //state <= state_busy; 367 | statebusy <= statebusy_send; 368 | end 369 | end 370 | /* 371 | * Put to dataOut the shift register. 372 | */ 373 | dataOut <= shift_reg_in; 374 | if(charreceivedp == charreceivedn) 375 | charreceivedp <= ~charreceivedp; 376 | dirsendint <= dirsend; 377 | end 378 | end 379 | end 380 | else 381 | /* 382 | * Bit all, cycle 1. 383 | */ 384 | if(sckint[1:0] == 2'b01) 385 | begin 386 | /* 387 | * Transition from '1' to '0' of SCL pin. 388 | * Shift left the shift_reg_out register after the bit 7 is send and before checking the state of sda is the same to bit 7. 389 | */ 390 | shift_reg_out <= (shift_reg_out << 1) | 1'b0; 391 | scl <= 1'b0; 392 | end 393 | else 394 | /* 395 | * Bit all, cycle 3. 396 | */ 397 | if(sckint[1:0] == 2'b11) 398 | begin 399 | /* 400 | * Transition from '0' to '1' of SCL pin. 401 | */ 402 | scl <= 1'b1; 403 | end 404 | else 405 | begin 406 | /* 407 | * Bit 7(last data bit), cycle 2. 408 | */ 409 | if(sckint[5:2] == 4'b0111) 410 | /* 411 | * After sending/receiving last bit put the sda to tristate to check the ack. 412 | */ 413 | _dirsendint <= 1'b0; 414 | else 415 | /* 416 | * Bit 8, cycle 2. 417 | */ 418 | if(sckint[5:2] == 4'b1000) 419 | /* 420 | * After checking ack put sda to open-collector to send the stop sequency if need to be send. 421 | */ 422 | _dirsendint <= 1'b1; 423 | /* 424 | * Bit all except 8(ack), cycle 2. 425 | * Put data on sda. 426 | */ 427 | sda_out <= shift_reg_out[7]; 428 | end 429 | end 430 | /* 431 | * End the 'stop' condition and go to Idle state. 432 | */ 433 | statebusy_stopphase1: 434 | begin 435 | /* 436 | * End sequence for stop signal. 437 | */ 438 | sda_out <= 1'b1; 439 | /* 440 | * Next cycle will enter in idle state. 441 | */ 442 | state <= state_idle; 443 | statebusy <= statebusy_startphase1; 444 | end 445 | endcase 446 | end 447 | endcase 448 | end 449 | end 450 | 451 | `ifdef I2C_DEBUG 452 | assign sda = sda_out; 453 | `else 454 | assign sda = sda_out ? 1'bz : (_dirsendint ? 1'b0 : 1'bz); 455 | `endif 456 | assign chartransferred = (charreceivedp ^ charreceivedn); 457 | 458 | 459 | endmodule 460 | -------------------------------------------------------------------------------- /i2c_simulation.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 01/30/2017 06:53:38 PM 7 | // Design Name: 8 | // Module Name: simulate 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | 23 | module simulate( 24 | 25 | ); 26 | 27 | wire rst; 28 | reg _rst = 0; 29 | //wire [7:0]data; 30 | reg [7:0]_datasend; 31 | wire [7:0]_datarec; 32 | wire wr; 33 | reg _wr = 0; 34 | wire rd; 35 | reg _rd = 0; 36 | wire buffempty; 37 | reg dirsend = 0; 38 | wire scl; 39 | wire sda; 40 | wire senderr; 41 | reg res_senderr = 0; 42 | wire chartransferred; 43 | wire ack; 44 | reg sendstart = 0; 45 | wire arbitrationlost; 46 | 47 | 48 | wire busy; 49 | reg [2:0]clk = 3'b000; 50 | 51 | reg clk_in = 0; 52 | parameter tck = 2; ///< clock tick 53 | 54 | always #(tck/2) clk_in <= ~clk_in; // clocking device 55 | 56 | i2c_master i2c0 ( 57 | .clk(clk[2]), 58 | .rst(rst), 59 | .dataIn(_datasend), 60 | .dataOut(_datarec), 61 | .wr(wr), 62 | .rd(rd), 63 | .buffempty(buffempty), 64 | .prescaller(3'h0), 65 | .dirsend(dirsend), 66 | .scl(scl), 67 | .sda(sda), 68 | .senderr(senderr), 69 | .res_senderr(res_senderr), 70 | .chartransferred(chartransferred), 71 | .ack(ack), 72 | .resendstart(sendstart), 73 | .arbitrationlost(arbitrationlost) 74 | ); 75 | 76 | initial begin 77 | _rst <= 1; 78 | #2; 79 | _rst <= 0; 80 | #2; 81 | sendstart = 1'b0; 82 | /* Set unit to transmitter. */ 83 | dirsend = 1'b1; 84 | /* Put one char to the buffer. */ 85 | _datasend <= 8'h55; 86 | /* Wait half core clock for propagation*/ 87 | #1; 88 | _wr <= 1'b1; 89 | #1; 90 | _wr <= 1'b0; 91 | /* 92 | * Wait buffer to become empty, after this you can send another char to maintain buffer full 93 | * This don't mather because the buffer is allready transferred to shift register, the buffer is empty. 94 | */ 95 | wait(buffempty == 1); 96 | /* 97 | * This start is not aplyed to first char, will be applyed to second char because the buffer has already transferred to shift register. 98 | * After sending first char the unit will resend the start sequency. 99 | */ 100 | sendstart = 1'b1; 101 | #1; 102 | sendstart = 1'b0; 103 | /* 104 | * Put second char to buffer. 105 | */ 106 | _datasend <= 8'hAA; 107 | /* Wait half core clock for propagation*/ 108 | #1; 109 | _wr <= 1'b1; 110 | #1; 111 | _wr <= 1'b0; 112 | /* 113 | * We put second char to buffer, now the buffer is full, we wait to become empty to put another char to buffer. 114 | */ 115 | wait(buffempty == 1); 116 | /* Wait half core clock */ 117 | #1; 118 | /* 119 | * Assert 'rd'. 120 | * This read is made for simulatio, w don't use the read char because is already put on _datarec. 121 | */ 122 | _rd = 1'b1; 123 | /* 124 | * Wait half core clock for propagation. 125 | */ 126 | #1; 127 | _rd = 1'b0; 128 | /* 129 | * Wait buffer to become empty, after this you can send another char to maintain buffer full. 130 | */ 131 | wait(buffempty == 1); 132 | /* 133 | * Wait the second char to be transferred, now because the buffer is empty, the unit will automatically send stop sequency. 134 | */ 135 | wait(chartransferred == 1); 136 | /* 137 | * Put the device to reception mode, the mode will be applied only at beginning of next send/receive byte. 138 | */ 139 | dirsend = 1'b0; 140 | /* 141 | * This is a dummy byte only used for debug where even in receive mode will transmit. 142 | * The unit is made in same wy that in debug mode will transmit even if is in receive mode. 143 | * In implementation you need to comment the "`define I2C_DEBUG" on module. 144 | */ 145 | _datasend <= 8'h55; 146 | #1; 147 | /* 148 | * In receive mode, to receive a byte you can emulate a send sequency because at base will work like send sequency, 149 | * you need to maintain send buffer full in order to receive bytes without sending stop sequency, 150 | * when send buffer is empty the stop sequency is send automatically. 151 | */ 152 | _wr <= 1'b1; 153 | #1; 154 | _wr <= 1'b0; 155 | #1; 156 | /* Assert 'rd' */ 157 | _rd = 1'b1; 158 | /* Wait half core clock for propagation */ 159 | #1; 160 | _rd = 1'b0; 161 | /* Wait half core clock for propagation*/ 162 | wait(chartransferred == 1);/* Wait the byte to be received, because the send buffer is empty the unit wil automatically send the stop sequency */ 163 | /* Put 'data' to tri state */ 164 | _datasend = 8'bz; 165 | /* Wait half core clock */ 166 | #1; 167 | /* Assert 'rd' */ 168 | _rd = 1'b1; 169 | /* Wait half core clock for propagation */ 170 | #1; 171 | /* Read data into '_datarec' register */ 172 | _rd = 1'b0; 173 | #500; 174 | $finish; 175 | end 176 | 177 | assign rst = _rst; 178 | assign wr = _wr; 179 | assign rd = _rd; 180 | assign data = _datasend; 181 | 182 | always @ (posedge clk_in) 183 | begin 184 | clk <= clk + 1; 185 | end 186 | endmodule 187 | 188 | -------------------------------------------------------------------------------- /memory.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This IPs is the ROM and RAM memory for the Atmel XMEGA CPU implementation. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | `timescale 1ns / 1ps 22 | 23 | module rom #( 24 | parameter bus_addr_pgm_width = 11, 25 | parameter rom_path = "NONE" 26 | ) ( 27 | input [bus_addr_pgm_width-1:0] pmem_a, 28 | output [15:0] pmem_d 29 | ); 30 | 31 | localparam LENGTH=2**bus_addr_pgm_width; 32 | reg [15:0] mem [LENGTH-1:0]; 33 | initial $readmemh(rom_path, mem); 34 | assign pmem_d = mem[pmem_a]; 35 | 36 | endmodule 37 | 38 | 39 | module ram #( 40 | parameter bus_addr_data_width = 13, /* < in bytes */ 41 | parameter ram_path = "NONE" 42 | ) ( 43 | input clk, 44 | input dmem_we, 45 | input dmem_re, 46 | input [bus_addr_data_width-1:0] dmem_a, 47 | input [7:0] dmem_w, 48 | output [7:0] dmem_r 49 | ); 50 | 51 | reg [7:0] mem [2**bus_addr_data_width-1:0]; 52 | 53 | initial begin 54 | if (ram_path == "true") 55 | $readmemh(ram_path, mem); 56 | end 57 | 58 | always@(posedge clk) begin 59 | if(dmem_we) 60 | mem[dmem_a] <= dmem_w; 61 | end 62 | assign dmem_r = dmem_re ? mem[dmem_a] : 8'bz; 63 | 64 | endmodule 65 | -------------------------------------------------------------------------------- /multiplyer.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: Iulian Gheorghiu 5 | // 6 | // Create Date: 08/15/2017 06:39:44 PM 7 | // Design Name: 8 | // Module Name: 8 bit custom multiplyer. 9 | // Project Name: 8 bit custom multiplyer IP. 10 | // Target Devices: All 11 | // Tool Versions: 12 | // Description: This is a 8 bit custom multiplyer IP library. 13 | // 14 | // Dependencies: None 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | 23 | module multiplyer # (parameter WIDTH_IN = 8)( 24 | input [WIDTH_IN - 1:0]a, 25 | input [WIDTH_IN - 1:0]b, 26 | output [(WIDTH_IN * 2) - 1:0]p 27 | ); 28 | 29 | wire [7:0]X0 = b[0] ? a[7:0] : 8'h00; 30 | wire [7:0]X1 = b[1] ? a[7:0] : 8'h00; 31 | wire [8:0]AD1 = X1 + {1'b0, X0[7:1]}; 32 | wire [7:0]X2 = b[2] ? a[7:0] : 8'h00; 33 | wire [8:0]AD2 = X2 + AD1[8:1]; 34 | wire [7:0]X3 = b[3] ? a[7:0] : 8'h00; 35 | wire [8:0]AD3 = X3 + AD2[8:1]; 36 | wire [7:0]X4 = b[4] ? a[7:0] : 8'h00; 37 | wire [8:0]AD4 = X4 + AD3[8:1]; 38 | wire [7:0]X5 = b[5] ? a[7:0] : 8'h00; 39 | wire [8:0]AD5 = X5 + AD4[8:1]; 40 | wire [7:0]X6 = b[6] ? a[7:0] : 8'h00; 41 | wire [8:0]AD6 = X6 + AD5[8:1]; 42 | wire [7:0]X7 = b[7] ? a[7:0] : 8'h00; 43 | wire [8:0]AD7 = X7 + AD6[8:1]; 44 | assign p = {AD7, AD6[0], AD5[0], AD4[0], AD3[0], AD2[0], AD1[0], X0[0]}; 45 | 46 | 47 | endmodule 48 | -------------------------------------------------------------------------------- /pmods.vh: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* PMOD OLED RGB */ 3 | /********************************************************************************/ 4 | `define PMOD_OLED_RGB_CONNECT(con) \ 5 | output con``_1, \ 6 | output con``_2, \ 7 | output con``_4, \ 8 | output con``_7, \ 9 | output con``_8, \ 10 | output con``_9, \ 11 | output con``_10 12 | 13 | `define PMOD_OLED_RGB_ATTACH(con, mod) \ 14 | wire mod``_cs; \ 15 | assign con``_1 = mod``_cs; \ 16 | wire mod``_sdout; \ 17 | assign con``_2 = mod``_sdout; \ 18 | wire mod``_sck; \ 19 | assign con``_4 = mod``_sck; \ 20 | reg mod``_dc; \ 21 | assign con``_7 = mod``_dc; \ 22 | reg mod``_res; \ 23 | assign con``_8 = mod``_res; \ 24 | reg mod``_vccen; \ 25 | assign con``_9 = mod``_vccen; \ 26 | reg mod``_pmoden; \ 27 | assign con``_10 = mod``_pmoden 28 | 29 | `define PMOD_OLED_RGB_INST_FROM_TOP(con, mod, reset, clock, freq, busy) \ 30 | SSD1331 # ( \ 31 | .clk_freq(freq) \ 32 | ) mod``pmod_oled_rgb_inst( \ 33 | .rst(reset), \ 34 | .clk(clock), \ 35 | .mod_1(con``_1), \ 36 | .mod_2(con``_2), \ 37 | .mod_4(con``_4), \ 38 | .mod_7(con``_7), \ 39 | .mod_8(con``_8), \ 40 | .mod_9(con``_9), \ 41 | .mod_10(con``_10), \ 42 | .init_busy(busy) \ 43 | ) 44 | 45 | /********************************************************************************/ 46 | /* PMOD MIC3 */ 47 | /********************************************************************************/ 48 | `define PMOD_MIC3_CONNECT(con) \ 49 | output con``_7, \ 50 | input con``_9, \ 51 | output con``_10 52 | 53 | `define PMOD_MIC3_ATTACH(con, mod) \ 54 | wire mod``_cs; \ 55 | assign con``_7 = mod``_cs; \ 56 | wire mod``_sdin = con``_9; \ 57 | wire mod``_sck; \ 58 | assign con``_10 = mod``_sck; \ 59 | 60 | /********************************************************************************/ 61 | /* PMOD NAV SPI */ 62 | /********************************************************************************/ 63 | `define PMOD_NAV_SPI_CONNECT(con) \ 64 | output con``_1, \ 65 | input con``_2, \ 66 | output con``_3, \ 67 | output con``_4, \ 68 | input con``_7, \ 69 | input con``_8, \ 70 | output con``_9, \ 71 | output con``_10 72 | 73 | `define PMOD_NAV_SPI_ATTACH(con, mod) \ 74 | wire mod``_cs_av; \ 75 | assign con``_1 = mod``_cs; \ 76 | wire mod``_sdin = con``_2; \ 77 | wire mod``_sdo; \ 78 | assign con``_3 = mod``_sdo; \ 79 | wire mod``_spc; \ 80 | assign con``_4 = mod``_spc; \ 81 | wire mod``_int = con``_7; \ 82 | wire mod``_drdy_m = con``_8; \ 83 | wire mod``_cs_m; \ 84 | assign con``_9 = mod``_cs_m; \ 85 | wire mod``_cs_alt; \ 86 | assign con``_10 = mod``_cs_alt 87 | 88 | /********************************************************************************/ 89 | /* PMOD NAV I2C */ 90 | /********************************************************************************/ 91 | `define PMOD_NAV_I2C_CONNECT(con) \ 92 | output con``_1, \ 93 | inout con``_2, \ 94 | output con``_3, \ 95 | output con``_4, \ 96 | input con``_7, \ 97 | input con``_8, \ 98 | output con``_9, \ 99 | output con``_10 100 | 101 | `define PMOD_NAV_I2C_ATTACH(con, mod, addr) \ 102 | assign con``_1 = 1'b1; \ 103 | wire mod``_sda_out; \ 104 | assign con``_2 = mod``_sda_out; \ 105 | wire mod``_sda_in = con``_2; \ 106 | assign con``_3 = addr; \ 107 | wire mod``_scl; \ 108 | assign con``_4 = mod``_scl; \ 109 | wire mod``_int = con``_7; \ 110 | wire mod``_drdy_m = con``_8; \ 111 | wire mod``_cs_m; \ 112 | assign con``_9 = mod``_cs_m; \ 113 | wire mod``_cs_alt; \ 114 | assign con``_10 = mod``_cs_alt 115 | 116 | /********************************************************************************/ 117 | /* PMOD RTCC */ 118 | /********************************************************************************/ 119 | `define PMOD_RTCC_CONNECT(con) \ 120 | output con``_3, \ 121 | inout con``_4 122 | 123 | `define PMOD_RTCC_ATTACH(con, mod, addr) \ 124 | wire mod``_scl; \ 125 | assign con``_3 = mod``_scl; \ 126 | wire mod``_sda_out; \ 127 | assign con``_4 = mod``_sda_out; \ 128 | wire mod``_sda_in = con``_4 129 | 130 | -------------------------------------------------------------------------------- /serdes.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This IP is the custom DDR SER/DES implementation. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | `timescale 1ns / 1ps 21 | 22 | module ddr_oserdes #( 23 | parameter DATA_RATE = "SDR",//"SDR" or "DDR" 24 | parameter DATA_WIDTH = 8 25 | )( 26 | input rst, 27 | input clk, 28 | input write, 29 | output s_out, 30 | input [DATA_WIDTH - 1:0]data_send, 31 | output ck_en_out, 32 | output busy_sig 33 | ); 34 | 35 | localparam DATA_WIDTH_int = DATA_RATE == "SDR" ? DATA_WIDTH : DATA_WIDTH / 2; 36 | 37 | /* 38 | * Custom Deserealizer. 39 | */ 40 | 41 | reg old_state_write; 42 | wire write_pulse = old_state_write != write; 43 | reg [DATA_WIDTH_int - 1:0]sending; 44 | reg [DATA_WIDTH_int - 1:0]shift_reg_p; 45 | reg [DATA_WIDTH_int - 1:0]shift_reg_n; 46 | 47 | integer cnt; 48 | 49 | always @ (posedge rst or posedge clk) 50 | begin 51 | if(rst) 52 | begin 53 | old_state_write <= 0; 54 | shift_reg_p <= 0; 55 | shift_reg_n <= 0; 56 | sending <= 0; 57 | end 58 | else if(sending[0]) 59 | begin 60 | sending <= {1'b0, sending[DATA_WIDTH_int - 1:1]}; 61 | {shift_reg_p} <= {1'b0, shift_reg_p[DATA_WIDTH_int - 1:1]}; 62 | if(DATA_RATE == "DDR") 63 | {shift_reg_n} <= {1'b0, shift_reg_n[DATA_WIDTH_int - 1:1]}; 64 | end 65 | if(write_pulse & ~sending[1] & ~rst) 66 | begin 67 | if(DATA_RATE == "DDR") 68 | begin/* Reorder bits to DDR shift registers. */ 69 | for(cnt = 0; cnt < DATA_WIDTH; cnt = cnt + 2) 70 | shift_reg_p[cnt >> 1] <= data_send[cnt]; 71 | for(cnt = 0; cnt < DATA_WIDTH; cnt = cnt + 2) 72 | shift_reg_n[cnt >> 1] <= data_send[cnt + 1]; 73 | end 74 | else 75 | begin 76 | shift_reg_p <= data_send; 77 | end 78 | sending <= {DATA_WIDTH_int{1'b1}}; 79 | old_state_write <= write; 80 | end 81 | end 82 | 83 | assign busy_sig = sending[1]; 84 | assign s_out = sending[0] ? ((DATA_RATE == "DDR") ? (clk ? shift_reg_p[0] : shift_reg_n[0]) : shift_reg_p[0]) : 1'bz; 85 | assign ck_en_out = sending[0]; 86 | 87 | endmodule 88 | 89 | module ddr_iserdes #( 90 | parameter DATA_RATE = "SDR", 91 | parameter DATA_WIDTH = 8 92 | )( 93 | input rst, 94 | input clk, 95 | input rec_en, 96 | input s_in, 97 | output reg [DATA_WIDTH - 1:0]data_rec, 98 | output reg ready 99 | ); 100 | 101 | localparam DATA_WIDTH_int = DATA_RATE == "SDR" ? DATA_WIDTH : DATA_WIDTH / 2; 102 | 103 | /* 104 | * Custom Serializer. 105 | */ 106 | 107 | reg [DATA_WIDTH_int - 1:0]receiving; 108 | reg [DATA_WIDTH_int - 1:0]shift_reg_p; 109 | reg [DATA_WIDTH_int - 1:0]shift_reg_n; 110 | reg first_bit; 111 | 112 | always @ (posedge rst or negedge rec_en or posedge clk) 113 | begin 114 | if(rst | ~rec_en) 115 | begin 116 | shift_reg_p <= 0; 117 | if(DATA_RATE == "SDR") 118 | receiving <= 0; 119 | end 120 | else if(rec_en) 121 | begin 122 | shift_reg_p <= {s_in, shift_reg_p[DATA_WIDTH_int - 1:1]}; 123 | if(DATA_RATE == "SDR") 124 | receiving <= {~receiving[0], receiving[DATA_WIDTH_int - 1:1]}; 125 | end 126 | end 127 | 128 | always @ (posedge rst or negedge rec_en or negedge clk) 129 | begin 130 | if(DATA_RATE == "DDR") 131 | begin 132 | if(rst | ~rec_en) 133 | begin 134 | shift_reg_n <= 0; 135 | if(DATA_RATE == "DDR") 136 | receiving <= 0; 137 | end 138 | else if(rec_en) 139 | begin 140 | shift_reg_n <= {s_in, shift_reg_n[DATA_WIDTH_int - 1:1]}; 141 | if(DATA_RATE == "DDR") 142 | receiving <= {~receiving[0], receiving[DATA_WIDTH_int - 1:1]}; 143 | end 144 | end 145 | end 146 | 147 | integer cnt; 148 | 149 | always @ (*) 150 | begin 151 | for(cnt = 0; cnt < DATA_WIDTH_int; cnt = cnt + 1) 152 | begin 153 | if(DATA_RATE == "DDR") 154 | begin/* Resorder bits from DDR dual edge shift registers. */ 155 | data_rec[cnt * 2] <= shift_reg_p[cnt]; 156 | data_rec[(cnt * 2) + 1] <= shift_reg_n[cnt]; 157 | end 158 | else 159 | data_rec <= shift_reg_p; 160 | end 161 | end 162 | 163 | always @ (posedge clk) ready = receiving[0]; 164 | 165 | endmodule 166 | -------------------------------------------------------------------------------- /spi_master.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | //////////////////////////////////////////////////////////////////////////////// 3 | //// //// 4 | //// Project Name: ASYNCHRONOUS SPI MASTER (Verilog) //// 5 | //// //// 6 | //// Module Name: spi_master //// 7 | //// //// 8 | //// //// 9 | //// Author(s): //// 10 | //// Iulian Gheorghiu //// 11 | //// //// 12 | //// Create Date: 01/17/2017 11:21:57 AM //// 13 | //// Refer to simulate.v for more information //// 14 | //// Revision 0.01 - File Created //// 15 | //// //// 16 | //////////////////////////////////////////////////////////////////////////////// 17 | 18 | module spi_master( 19 | clk,/* Peripheral clock/not necessary to be core clock, the core clock can be different (input) */ 20 | rst,/* Asynchronus reset, is mandatory to provide this signal, active on posedge (input) */ 21 | data_in,/* In/Out data(bidirectional) */ 22 | data_out,/* In/Out data(bidirectional) */ 23 | wr,/* Send data, asynchronus with 'clk' , active on posedge or negedge(input) */ 24 | rd,/* Read data, , asynchronus with 'clk' , active on posedge or negedge (input) */ 25 | buffempty,/* '1' if transmit buffer is empty (output) */ 26 | prescaller,/* The prescaller divider is = (1 << prescaller) value between 0 and 7 for dividers by:1,2,4,8,16,32,64,128 and 256 (input)*/ 27 | sck,/* SPI 'sck' signal (output) */ 28 | mosi,/* SPI 'mosi' signal (output) */ 29 | miso,/* SPI 'miso' signal (input) */ 30 | ss,/* SPI 'ss' signal (if send buffer is maintained full the ss signal will not go high between between transmit chars)(output) */ 31 | lsbfirst,/* If '0' msb is send first, if '1' lsb is send first (input) */ 32 | mode,/* All four modes is supported (input) */ 33 | senderr,/* If you try to send a character if send buffer is full this bit is set to '1', this can be ignored and if is '1' does not affect the interface (output) */ 34 | res_senderr,/* To reset 'senderr' signal write '1' wait minimum half core clock and and after '0' to this bit, is asynchronous with 'clk' (input)*/ 35 | charreceived/* Is set to '1' if a character is received, if you read the receive buffe this bit will go '0', if you ignore it and continue to send data this bit will remain '1' until you read the read register (output) */ 36 | ); 37 | 38 | parameter WORD_LEN = 8; 39 | parameter PRESCALLER_SIZE = 8; 40 | 41 | input clk; 42 | input rst; 43 | input [WORD_LEN - 1:0]data_in; 44 | output [WORD_LEN - 1:0]data_out; 45 | input wr; 46 | input rd; 47 | output buffempty; 48 | input [2:0]prescaller; 49 | output sck; 50 | output mosi; 51 | reg _mosi; 52 | input miso; 53 | output reg ss; 54 | input lsbfirst; 55 | input [1:0]mode; 56 | output reg senderr; 57 | input res_senderr; 58 | output charreceived; 59 | 60 | reg charreceivedp; 61 | reg charreceivedn; 62 | 63 | reg inbufffullp = 1'b0; 64 | reg inbufffulln = 1'b0; 65 | 66 | reg [WORD_LEN - 1:0]input_buffer; 67 | reg [WORD_LEN - 1:0]output_buffer; 68 | 69 | assign buffempty = ~(inbufffullp ^ inbufffulln); 70 | reg [2:0]prescallerbuff; 71 | /***********************************************/ 72 | /************* Asynchronus send ****************/ 73 | /***********************************************/ 74 | /* 75 | * You need to put the data on the bus and wait a half of core clock to assert the wr signal(see simulation). 76 | */ 77 | `ifdef WRITE_ON_NEG_EDGE == 1 78 | always @ (negedge wr) 79 | `else 80 | always @ (posedge wr) 81 | `endif 82 | begin 83 | if(wr && inbufffullp == inbufffulln && buffempty) 84 | begin 85 | input_buffer <= data_in; 86 | end 87 | end 88 | 89 | `ifdef WRITE_ON_NEG_EDGE == 1 90 | always @ (negedge wr or posedge res_senderr or posedge rst) 91 | `else 92 | always @ (posedge wr or posedge res_senderr or posedge rst) 93 | `endif 94 | begin 95 | if(rst) 96 | begin 97 | inbufffullp <= 1'b0; 98 | senderr <= 1'b0; 99 | prescallerbuff <= 3'b000; 100 | end 101 | else 102 | if(res_senderr) 103 | senderr <= 1'b0; 104 | else 105 | if(wr && inbufffullp == inbufffulln && buffempty) 106 | begin 107 | inbufffullp <= ~inbufffullp; 108 | prescallerbuff <= prescaller; 109 | end 110 | else 111 | if(!buffempty) 112 | senderr <= 1'b1; 113 | end 114 | /***********************************************/ 115 | /************ !Asynchronus send ****************/ 116 | /***********************************************/ 117 | parameter state_idle = 1'b0; 118 | parameter state_busy = 1'b1; 119 | reg state; 120 | 121 | 122 | reg [PRESCALLER_SIZE - 1:0]prescaller_cnt; 123 | reg [WORD_LEN - 1:0]shift_reg_out; 124 | reg [WORD_LEN - 1:0]shift_reg_in; 125 | reg [4:0]sckint; 126 | //reg sckintn; 127 | reg [2:0]prescallerint; 128 | reg [7:0]prescdemux; 129 | 130 | 131 | always @ (*) 132 | begin 133 | if(prescallerint < PRESCALLER_SIZE) 134 | begin 135 | case(prescallerint) 136 | 3'b000: prescdemux <= 8'b00000001; 137 | 3'b001: prescdemux <= 8'b00000011; 138 | 3'b010: prescdemux <= 8'b00000111; 139 | 3'b011: prescdemux <= 8'b00001111; 140 | 3'b100: prescdemux <= 8'b00011111; 141 | 3'b101: prescdemux <= 8'b00111111; 142 | 3'b110: prescdemux <= 8'b01111111; 143 | 3'b111: prescdemux <= 8'b11111111; 144 | endcase 145 | end 146 | else 147 | prescdemux <= 8'b00000001; 148 | end 149 | 150 | reg lsbfirstint; 151 | reg [1:0]modeint; 152 | 153 | always @ (posedge clk or posedge rst) 154 | begin 155 | if(rst) 156 | begin 157 | inbufffulln <= 1'b0; 158 | ss <= 1'b1; 159 | state <= state_idle; 160 | prescaller_cnt <= {PRESCALLER_SIZE{1'b0}}; 161 | prescallerint <= {PRESCALLER_SIZE{3'b0}}; 162 | shift_reg_out <= {WORD_LEN{1'b0}}; 163 | shift_reg_in <= {WORD_LEN{1'b0}}; 164 | sckint <= {5{1'b0}}; 165 | _mosi <= 1'b1; 166 | output_buffer <= {WORD_LEN{1'b0}}; 167 | charreceivedp <= 1'b0; 168 | lsbfirstint <= 1'b0; 169 | modeint <= 2'b00; 170 | end 171 | else 172 | begin 173 | case(state) 174 | state_idle: 175 | begin 176 | if(inbufffullp != inbufffulln) 177 | begin 178 | inbufffulln <= ~inbufffulln; 179 | ss <= 1'b0; 180 | prescaller_cnt <= {PRESCALLER_SIZE{1'b0}}; 181 | prescallerint <= prescallerbuff; 182 | lsbfirstint <= lsbfirst; 183 | modeint <= mode; 184 | shift_reg_out <= input_buffer; 185 | state <= state_busy; 186 | if(!mode[0]) 187 | begin 188 | if(!lsbfirst) 189 | _mosi <= input_buffer[WORD_LEN - 1]; 190 | else 191 | _mosi <= input_buffer[0]; 192 | end 193 | end 194 | end 195 | state_busy: 196 | begin 197 | if(prescaller_cnt != prescdemux) 198 | begin 199 | prescaller_cnt <= prescaller_cnt + 1; 200 | end 201 | else 202 | begin 203 | prescaller_cnt <= {PRESCALLER_SIZE{1'b0}}; 204 | sckint <= sckint + 1; 205 | if(sckint[0] == modeint[0]) 206 | begin 207 | if(!lsbfirstint) 208 | begin 209 | shift_reg_in <= {miso, shift_reg_in[7:1]}; 210 | shift_reg_out <= {shift_reg_out[6:0], 1'b1}; 211 | end 212 | else 213 | begin 214 | shift_reg_in <= {shift_reg_in[6:0], miso}; 215 | shift_reg_out <= {1'b1, shift_reg_out[7:1]}; 216 | end 217 | end 218 | else 219 | begin 220 | if(sckint[4:1] == WORD_LEN - 1) 221 | begin 222 | sckint <= {5{1'b0}}; 223 | if(inbufffullp == inbufffulln) 224 | begin 225 | ss <= 1'b1; 226 | end 227 | output_buffer <= shift_reg_in; 228 | if(charreceivedp == charreceivedn) 229 | charreceivedp <= ~charreceivedp; 230 | state <= state_idle; 231 | end 232 | else 233 | begin 234 | if(!lsbfirstint) 235 | _mosi <= shift_reg_out[WORD_LEN - 1]; 236 | else 237 | _mosi <= shift_reg_out[0]; 238 | end 239 | end 240 | end 241 | end 242 | endcase 243 | end 244 | end 245 | /* 246 | * You need to assert rd signal, wait a half core clock and after read the data(see simulation). 247 | */ 248 | `ifdef READ_ON_NEG_EDGE == 1 249 | always @ (negedge rd or posedge rst) 250 | `else 251 | always @ (posedge rd or posedge rst) 252 | `endif 253 | begin 254 | if(rst) 255 | charreceivedn <= 1'b0; 256 | else 257 | if(charreceivedp != charreceivedn) 258 | charreceivedn <= ~charreceivedn; 259 | end 260 | 261 | assign data_out = (rd) ? output_buffer : {WORD_LEN{1'bz}}; 262 | 263 | assign sck = (modeint[1])? ~sckint : sckint; 264 | assign mosi = (ss) ? 1'b1:_mosi; 265 | assign charreceived = (charreceivedp ^ charreceivedn); 266 | 267 | endmodule 268 | -------------------------------------------------------------------------------- /string.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This IP is the synthetizable big endian <-> little endian of strings implementation. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | `timescale 1ns / 1ps 22 | 23 | module string #(parameter LEN = 32)( 24 | input [LEN-1:0]in, 25 | output reg [LEN-1:0]out 26 | ); 27 | 28 | genvar cnt; 29 | generate 30 | for(cnt = LEN; cnt > 0; cnt = cnt - 8) 31 | begin 32 | always @(in) 33 | begin 34 | if(in[cnt-1:cnt-8]) 35 | out = {in[cnt-1:cnt-8], out[LEN - 1: 8]}; 36 | end 37 | end 38 | for(cnt = LEN; cnt > 0; cnt = cnt - 8) 39 | begin 40 | always @(in) 41 | begin 42 | if(!in[cnt-1:cnt-8]) 43 | out = {8'h00, out[LEN - 1: 8]}; 44 | end 45 | end 46 | endgenerate 47 | 48 | endmodule 49 | -------------------------------------------------------------------------------- /uart_implementation.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 03/11/2017 07:10:16 PM 7 | // Design Name: 8 | // Module Name: main 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | 23 | module main( 24 | input CLK100MHZ, 25 | input btnc, 26 | input uart_tx_in, 27 | output uart_rx_out, 28 | input [7:0]sw, 29 | output reg [7:0]led, 30 | output [7:0]ja 31 | ); 32 | reg txen; 33 | reg rxen; 34 | 35 | wire [8:0]data_rec; 36 | wire [8:0]data_send; 37 | reg wr; 38 | reg rd; 39 | wire buffempty; 40 | wire charreceived; 41 | wire receiveoverrun; 42 | wire frameerror; 43 | wire parityerror; 44 | 45 | wire [15:0]prescaller_cnt; 46 | 47 | parameter PRESCALLER = (450000000/1000000/16) - 1; 48 | 49 | wire uart_clk; 50 | 51 | wire clk_pll_0; 52 | wire clk_pll_1; 53 | wire clk_pll_2; 54 | wire clk_pll_3; 55 | wire clk_pll_4; 56 | wire clk_pll_5; 57 | assign uart_clk = (PRESCALLER) ? ((prescaller_cnt < (PRESCALLER >> 1)) ? 1'b1:1'b0):clk_pll_0; // If prescaller != 0 generate a ~50% clk wavwform. 58 | wire PLL1_FEEDBACK; 59 | PLLE2_BASE #( 60 | .BANDWIDTH("OPTIMIZED"), // OPTIMIZED, HIGH, LOW 61 | .CLKFBOUT_MULT(9), // Multiply value for all CLKOUT, (2-64) 62 | .CLKFBOUT_PHASE(0.0), // Phase offset in degrees of CLKFB, (-360.000-360.000). 63 | .CLKIN1_PERIOD(10.0), // Input clock period in ns to ps resolution (i.e. 33.333 is 30 MHz). 64 | // CLKOUT0_DIVIDE - CLKOUT5_DIVIDE: Divide amount for each CLKOUT (1-128) 65 | .CLKOUT0_DIVIDE(2), 66 | .CLKOUT1_DIVIDE(4), 67 | .CLKOUT2_DIVIDE(1), 68 | .CLKOUT3_DIVIDE(1), 69 | .CLKOUT4_DIVIDE(1), 70 | .CLKOUT5_DIVIDE(1), 71 | // CLKOUT0_DUTY_CYCLE - CLKOUT5_DUTY_CYCLE: Duty cycle for each CLKOUT (0.001-0.999). 72 | .CLKOUT0_DUTY_CYCLE(0.5), 73 | .CLKOUT1_DUTY_CYCLE(0.5), 74 | .CLKOUT2_DUTY_CYCLE(0.5), 75 | .CLKOUT3_DUTY_CYCLE(0.5), 76 | .CLKOUT4_DUTY_CYCLE(0.5), 77 | .CLKOUT5_DUTY_CYCLE(0.5), 78 | // CLKOUT0_PHASE - CLKOUT5_PHASE: Phase offset for each CLKOUT (-360.000-360.000). 79 | .CLKOUT0_PHASE(0.0), 80 | .CLKOUT1_PHASE(0.0), 81 | .CLKOUT2_PHASE(0.0), 82 | .CLKOUT3_PHASE(0.0), 83 | .CLKOUT4_PHASE(0.0), 84 | .CLKOUT5_PHASE(0.0), 85 | .DIVCLK_DIVIDE(1), // Master division value, (1-56) 86 | .REF_JITTER1(0.0), // Reference input jitter in UI, (0.000-0.999). 87 | .STARTUP_WAIT("FALSE") // Delay DONE until PLL Locks, ("TRUE"/"FALSE") 88 | ) 89 | PLLE2_BASE_inst ( 90 | // Clock Outputs: 1-bit (each) output: User configurable clock outputs 91 | .CLKOUT0(clk_pll_0), // 1-bit output: CLKOUT0 92 | .CLKOUT1(clk_pll_1), // 1-bit output: CLKOUT1 93 | .CLKOUT2(clk_pll_2), // 1-bit output: CLKOUT2 94 | .CLKOUT3(clk_pll_3), // 1-bit output: CLKOUT3 95 | .CLKOUT4(clk_pll_4), // 1-bit output: CLKOUT4 96 | .CLKOUT5(clk_pll_5), // 1-bit output: CLKOUT5 97 | // Feedback Clocks: 1-bit (each) output: Clock feedback ports 98 | .CLKFBOUT(PLL1_FEEDBACK), // 1-bit output: Feedback clock 99 | //.LOCKED(LOCKED), // 1-bit output: LOCK 100 | .CLKIN1(CLK100MHZ), // 1-bit input: Input clock 101 | // Control Ports: 1-bit (each) input: PLL control ports 102 | .PWRDWN(btnc), // 1-bit input: Power-down 103 | .RST(btnc), // 1-bit input: Reset 104 | // Feedback Clocks: 1-bit (each) input: Clock feedback ports 105 | .CLKFBIN(PLL1_FEEDBACK) // 1-bit input: Feedback clock 106 | ); 107 | 108 | 109 | `define CNT_ASYNC(rst, clk, lath, load, value) \ 110 | always @ (posedge clk) \ 111 | begin \ 112 | if(load) lath <= value; \ 113 | else lath <= ~lath; \ 114 | end 115 | 116 | wire prescaler_load; 117 | 118 | cnt_async_dn_rst_ld # ( 119 | .SIZE(16)) 120 | prescaller( 121 | .rst(btnc), 122 | .clk(clk_pll_0), 123 | .load(prescaler_load), 124 | .value(PRESCALLER), 125 | .cnt(prescaller_cnt) 126 | ); 127 | 128 | assign prescaler_load = (prescaller_cnt == 0); 129 | 130 | uart_tx uart_tx0( 131 | .clk(uart_clk),/* Peripheral clock (uart_clk/8) = brate if u2x = 1 or (uart_clk/16) = brate if u2x = 0 (input) */ 132 | .rst(btnc),/* Asynchronus reset, is mandatory to provide this signal, active on posedge (input) */ 133 | .txen(txen), 134 | .data(data_send),/* In/ data(input) */ 135 | .wr(wr),/* Send data, asynchronus with 'clk' , active on posedge or negedge(input) */ 136 | .buffempty(buffempty),/* '1' if transmit buffer is empty (output) */ 137 | .wordlen(4'd8),/* 0 = 5bit, 1 = 6bit, 2 = 7bit, 3 = 8bit, 4 = 9bit, 5-6-7 = reserved */ 138 | .tx(uart_rx_out),/* Tx pin */ 139 | .u2x(1'b0),/* Double speed */ 140 | .parity(2'd1),/* Parity type: 0 = none, 1 = even, 2 = odd (Not implemented yet) */ 141 | .stopbits(1'b0),/* Number of stop bits: 0 = one stop bit, 1 = Two stop bits */ 142 | .mode(1'b0)/*0 = Asysnhronous, 1 = Synchronous*/ 143 | ); 144 | 145 | uart_rx uart_rx0( 146 | .clk(uart_clk),/* Peripheral clock (uart_clk/8) = brate if u2x = 1 or (uart_clk/16) = brate if u2x = 0 (input) */ 147 | .rst(btnc),/* Asynchronus reset, is mandatory to provide this signal, active on posedge (input) */ 148 | .rxen(rxen), 149 | .data(data_rec),/* Out data(output) */ 150 | .rd(rd),/* Read data, , asynchronus with 'clk' , active on posedge or negedge (input) */ 151 | .charreceived(charreceived),/* Is set to '1' if a character is received, if you read the receive buffe this bit will go '0', if you ignore it and continue to send data this bit will remain '1' until you read the read register (output) */ 152 | .wordlen(4'd8),/* 0 = 5bit, 1 = 6bit, 2 = 7bit, 3 = 8bit, 4 = 9bit, 5-6-7 = reserved */ 153 | .rx(uart_tx_in),/* Rx pin */ 154 | .u2x(1'b0),/* Double speed */ 155 | .parity(2'd1),/* Parity type: 0 = none, 1 = even, 2 = odd (Not implemented yet) */ 156 | .stopbits(1'b0),/* Number of stop bits: 0 = one stop bit, 1 = Two stop bits */ 157 | .mode(1'b0),/*0 = Asysnhronous, 1 = Synchronous*/ 158 | .frameerror(frameerror),/* If stop bit is not detected a frame error will report, this is actualized every received byte. */ 159 | .parityerror(parityerror),/* Parity error bit report (Not implemented yet) */ 160 | .receiveoverrun(receiveoverrun)/* If receive buffer is full and another char is received a receiveoverrun will report, this bit is resetted on read. */ 161 | ); 162 | 163 | 164 | always @ (posedge uart_clk) 165 | begin 166 | if(btnc) 167 | led[0] <= 1'b0; 168 | else 169 | if(frameerror) 170 | led[0] <= 1'b1; 171 | end 172 | 173 | always @ (posedge uart_clk) 174 | begin 175 | if(btnc) 176 | led[1] <= 1'b0; 177 | else 178 | if(receiveoverrun) 179 | led[1] <= 1'b1; 180 | end 181 | 182 | always @ (posedge uart_clk) 183 | begin 184 | if(btnc) 185 | led[2] <= 1'b0; 186 | else 187 | //if(parityerror) 188 | led[2] <= parityerror; 189 | end 190 | 191 | reg [2:0]cnt = 0; 192 | reg [1:0]start_cnt = 0; 193 | 194 | initial begin 195 | end 196 | 197 | reg [25:0]sequence_count; 198 | reg [8:0]temp_chars; 199 | 200 | `define ORDER_TO_TYME(order) \ 201 | 26'h2000000 + (order * 26'h0000010) 202 | 203 | parameter rom_char_end = `ORDER_TO_TYME(94); 204 | 205 | `define SEND_CHAR(char_nr, char) \ 206 | char_nr:\ 207 | begin\ 208 | temp_chars <= char;\ 209 | sequence_count <= sequence_count + 26'h00000001;\ 210 | end\ 211 | char_nr + 1:\ 212 | begin\ 213 | wr <= 1'b1;\ 214 | sequence_count <= sequence_count + 26'h00000001;\ 215 | end\ 216 | char_nr + 2:\ 217 | begin\ 218 | wr <= 1'b0;\ 219 | sequence_count <= sequence_count + 26'h00000001;\ 220 | end\ 221 | char_nr + 3:\ 222 | begin\ 223 | if(buffempty)\ 224 | sequence_count <= char_nr + 26'h00000010;\ 225 | end 226 | 227 | always @ (posedge clk_pll_1 or posedge btnc) 228 | begin 229 | if(btnc) 230 | begin 231 | wr <= 1'b0; 232 | start_cnt <= 2'h0; 233 | cnt <= 3'h2; 234 | //led <= 8'h00; 235 | sequence_count <= 32'h0; 236 | txen <= 1'b0; 237 | rxen <= 1'b0; 238 | end 239 | else 240 | begin 241 | case(start_cnt) 242 | 2'h0: 243 | begin 244 | txen <= 1'b0; 245 | rxen <= 1'b0; 246 | start_cnt <= 2'h1; 247 | end 248 | 2'h1: 249 | begin 250 | txen <= 1'b1; 251 | rxen <= 1'b1; 252 | start_cnt <= 2'h2; 253 | end 254 | endcase 255 | 256 | if(sequence_count >= rom_char_end) 257 | begin 258 | if(charreceived && cnt == 3'h02) 259 | begin 260 | cnt <= 3'h00; 261 | end 262 | else 263 | begin 264 | case(cnt) 265 | 3'h00: 266 | begin 267 | //led <= data_rec; 268 | wr <= 1'b1; 269 | rd <= 1'b1; 270 | cnt <= 3'h01; 271 | end 272 | 3'h01: 273 | begin 274 | wr <= 1'b0; 275 | rd <= 1'b0; 276 | cnt <= 3'h02; 277 | end 278 | endcase 279 | end 280 | end 281 | else 282 | begin 283 | if(sequence_count < `ORDER_TO_TYME(0)) 284 | begin 285 | sequence_count <= sequence_count + 11'h001; 286 | end 287 | else 288 | begin 289 | case (sequence_count) 290 | `SEND_CHAR(`ORDER_TO_TYME(0), "G") 291 | `SEND_CHAR(`ORDER_TO_TYME(1), "o") 292 | `SEND_CHAR(`ORDER_TO_TYME(2), "o") 293 | `SEND_CHAR(`ORDER_TO_TYME(3), "d") 294 | `SEND_CHAR(`ORDER_TO_TYME(4), " ") 295 | `SEND_CHAR(`ORDER_TO_TYME(5), "m") 296 | `SEND_CHAR(`ORDER_TO_TYME(6), "o") 297 | `SEND_CHAR(`ORDER_TO_TYME(7), "r") 298 | `SEND_CHAR(`ORDER_TO_TYME(8), "n") 299 | `SEND_CHAR(`ORDER_TO_TYME(9), "i") 300 | `SEND_CHAR(`ORDER_TO_TYME(10), "n") 301 | `SEND_CHAR(`ORDER_TO_TYME(11), "g") 302 | `SEND_CHAR(`ORDER_TO_TYME(12), "\r") 303 | `SEND_CHAR(`ORDER_TO_TYME(13), "T") 304 | `SEND_CHAR(`ORDER_TO_TYME(14), "h") 305 | `SEND_CHAR(`ORDER_TO_TYME(15), "i") 306 | `SEND_CHAR(`ORDER_TO_TYME(16), "s") 307 | `SEND_CHAR(`ORDER_TO_TYME(17), " ") 308 | `SEND_CHAR(`ORDER_TO_TYME(18), "i") 309 | `SEND_CHAR(`ORDER_TO_TYME(19), "s") 310 | `SEND_CHAR(`ORDER_TO_TYME(20), " ") 311 | `SEND_CHAR(`ORDER_TO_TYME(21), "a") 312 | `SEND_CHAR(`ORDER_TO_TYME(22), "n") 313 | `SEND_CHAR(`ORDER_TO_TYME(23), " ") 314 | `SEND_CHAR(`ORDER_TO_TYME(24), "e") 315 | `SEND_CHAR(`ORDER_TO_TYME(25), "x") 316 | `SEND_CHAR(`ORDER_TO_TYME(26), "a") 317 | `SEND_CHAR(`ORDER_TO_TYME(27), "m") 318 | `SEND_CHAR(`ORDER_TO_TYME(28), "p") 319 | `SEND_CHAR(`ORDER_TO_TYME(29), "l") 320 | `SEND_CHAR(`ORDER_TO_TYME(30), "e") 321 | `SEND_CHAR(`ORDER_TO_TYME(31), " ") 322 | `SEND_CHAR(`ORDER_TO_TYME(32), "o") 323 | `SEND_CHAR(`ORDER_TO_TYME(33), "f") 324 | `SEND_CHAR(`ORDER_TO_TYME(34), " ") 325 | `SEND_CHAR(`ORDER_TO_TYME(35), "a") 326 | `SEND_CHAR(`ORDER_TO_TYME(36), " ") 327 | `SEND_CHAR(`ORDER_TO_TYME(37), "u") 328 | `SEND_CHAR(`ORDER_TO_TYME(38), "a") 329 | `SEND_CHAR(`ORDER_TO_TYME(39), "r") 330 | `SEND_CHAR(`ORDER_TO_TYME(40), "t") 331 | `SEND_CHAR(`ORDER_TO_TYME(41), " ") 332 | `SEND_CHAR(`ORDER_TO_TYME(42), "h") 333 | `SEND_CHAR(`ORDER_TO_TYME(43), "a") 334 | `SEND_CHAR(`ORDER_TO_TYME(44), "r") 335 | `SEND_CHAR(`ORDER_TO_TYME(45), "d") 336 | `SEND_CHAR(`ORDER_TO_TYME(46), "w") 337 | `SEND_CHAR(`ORDER_TO_TYME(47), "a") 338 | `SEND_CHAR(`ORDER_TO_TYME(48), "r") 339 | `SEND_CHAR(`ORDER_TO_TYME(49), "e") 340 | `SEND_CHAR(`ORDER_TO_TYME(50), " ") 341 | `SEND_CHAR(`ORDER_TO_TYME(51), "m") 342 | `SEND_CHAR(`ORDER_TO_TYME(52), "o") 343 | `SEND_CHAR(`ORDER_TO_TYME(53), "d") 344 | `SEND_CHAR(`ORDER_TO_TYME(54), "u") 345 | `SEND_CHAR(`ORDER_TO_TYME(55), "l") 346 | `SEND_CHAR(`ORDER_TO_TYME(56), "e") 347 | `SEND_CHAR(`ORDER_TO_TYME(57), " ") 348 | `SEND_CHAR(`ORDER_TO_TYME(58), "t") 349 | `SEND_CHAR(`ORDER_TO_TYME(59), "h") 350 | `SEND_CHAR(`ORDER_TO_TYME(60), "a") 351 | `SEND_CHAR(`ORDER_TO_TYME(61), "t") 352 | `SEND_CHAR(`ORDER_TO_TYME(62), " ") 353 | `SEND_CHAR(`ORDER_TO_TYME(63), "e") 354 | `SEND_CHAR(`ORDER_TO_TYME(64), "c") 355 | `SEND_CHAR(`ORDER_TO_TYME(65), "h") 356 | `SEND_CHAR(`ORDER_TO_TYME(66), "o") 357 | `SEND_CHAR(`ORDER_TO_TYME(67), " ") 358 | `SEND_CHAR(`ORDER_TO_TYME(68), "t") 359 | `SEND_CHAR(`ORDER_TO_TYME(69), "h") 360 | `SEND_CHAR(`ORDER_TO_TYME(70), "e") 361 | `SEND_CHAR(`ORDER_TO_TYME(71), " ") 362 | `SEND_CHAR(`ORDER_TO_TYME(72), "r") 363 | `SEND_CHAR(`ORDER_TO_TYME(73), "e") 364 | `SEND_CHAR(`ORDER_TO_TYME(74), "c") 365 | `SEND_CHAR(`ORDER_TO_TYME(75), "e") 366 | `SEND_CHAR(`ORDER_TO_TYME(76), "i") 367 | `SEND_CHAR(`ORDER_TO_TYME(77), "v") 368 | `SEND_CHAR(`ORDER_TO_TYME(78), "e") 369 | `SEND_CHAR(`ORDER_TO_TYME(79), "d") 370 | `SEND_CHAR(`ORDER_TO_TYME(80), " ") 371 | `SEND_CHAR(`ORDER_TO_TYME(81), "c") 372 | `SEND_CHAR(`ORDER_TO_TYME(82), "h") 373 | `SEND_CHAR(`ORDER_TO_TYME(83), "a") 374 | `SEND_CHAR(`ORDER_TO_TYME(84), "r") 375 | `SEND_CHAR(`ORDER_TO_TYME(85), "s") 376 | `SEND_CHAR(`ORDER_TO_TYME(86), " ") 377 | `SEND_CHAR(`ORDER_TO_TYME(87), "b") 378 | `SEND_CHAR(`ORDER_TO_TYME(88), "a") 379 | `SEND_CHAR(`ORDER_TO_TYME(89), "c") 380 | `SEND_CHAR(`ORDER_TO_TYME(90), "k") 381 | `SEND_CHAR(`ORDER_TO_TYME(91), ".") 382 | `SEND_CHAR(`ORDER_TO_TYME(92), "\r") 383 | `SEND_CHAR(`ORDER_TO_TYME(93), "\r") 384 | endcase 385 | end 386 | end 387 | end 388 | end 389 | 390 | assign data_send = (sequence_count >= rom_char_end) ? data_rec : temp_chars; 391 | 392 | endmodule -------------------------------------------------------------------------------- /uart_rx.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 03/21/2017 02:54:54 PM 7 | // Design Name: 8 | // Module Name: uart_rx 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | 23 | module uart_rx( 24 | input clk,/* Peripheral clock/will be provided from a prescaller, no need to be 50% waveform (input) */ 25 | input rst,/* Asynchronus reset, is mandatory to provide this signal, active on posedge (input) */ 26 | input rxen, 27 | output reg[8:0]data,/* Out data(output) */ 28 | input rd,/* Read data, , asynchronus with 'clk' , active on posedge or negedge (input) */ 29 | output charreceived,/* Is set to '1' if a character is received, if you read the receive buffe this bit will go '0', if you ignore it and continue to send data this bit will remain '1' until you read the read register (output) */ 30 | input [3:0]wordlen,/* In bits */ 31 | input rx,/* Rx pin */ 32 | inout sck,/* Synchronous clk pin (Not implemented yet) */ 33 | input u2x,/* Double speed */ 34 | input [1:0]parity,/* Parity type: 0 = none, 1 = even, 2 = odd (Not implemented yet) */ 35 | input stopbits,/* Number of stop bits: 0 = one stop bit, 1 = Two stop bits */ 36 | input mode,/*0 = Asysnhronous, 1 = Synchronous*/ 37 | output reg frameerror,/* If stop bit is not detected a frame error will report, this is actualized every received byte. */ 38 | output reg parityerror,/* Parity error bit report (Not implemented yet) */ 39 | output receiveoverrun/* If receive buffer is full and another char is received a receiveoverrun will report, this bit is resetted on read. */ 40 | ); 41 | 42 | parameter [6:0]MAX_WORD_LEN = 9; 43 | 44 | parameter state_idle = 1'b0; 45 | parameter state_busy = 1'b1; 46 | 47 | reg receiveoverrunp; 48 | reg receiveoverrunn; 49 | wire receiveoverrunpn; 50 | 51 | reg [2:0]rxbitcntstate; 52 | 53 | reg charreceivedp; 54 | reg charreceivedn; 55 | 56 | reg state_rx; 57 | reg [(MAX_WORD_LEN - 1) + 4:0]shift_reg_in; 58 | //reg [MAX_WORD_LEN - 1:0]temp_output_buffer; 59 | reg [7:0]sckint_rx; 60 | //reg [3:0]bitcount_rx; 61 | reg [3:0]total_word_len_rx; 62 | 63 | wire _chk_int; 64 | wire chk_int; 65 | reg [(MAX_WORD_LEN - 1) + 4:0]parity_mask; 66 | wire [(MAX_WORD_LEN - 1) + 4:0]valid_data; 67 | wire parity_bit; 68 | 69 | always @ (*) 70 | begin 71 | case(wordlen) 72 | 4'h05: parity_mask <= 12'b000000111110; 73 | 4'h06: parity_mask <= 12'b000001111110; 74 | 4'h07: parity_mask <= 12'b000011111110; 75 | 4'h09: parity_mask <= 12'b001111111110; 76 | default: parity_mask <= 12'b000111111110; 77 | endcase 78 | end 79 | /*assign parity_mask = (wordlen == 4'h08) ? 12'b000111111110: 80 | (wordlen == 4'h05) ? 12'b000000111110: 81 | (wordlen == 4'h06) ? 12'b000001111110: 82 | (wordlen == 4'h07) ? 12'b000011111110: 83 | (wordlen == 4'h09) ? 12'b001111111110: 84 | 12'b000111111110;*/ 85 | 86 | assign valid_data = shift_reg_in & parity_mask; 87 | assign _chk_int = ^valid_data; 88 | assign chk_int = (parity == 2'b10) ? ~_chk_int:_chk_int; 89 | assign parity_bit = (shift_reg_in & (1 << wordlen + 1)) ? 1:0; 90 | 91 | reg last_state_rxp; 92 | reg last_state_rxn; 93 | wire rx_start_detected; 94 | 95 | always @ (negedge rx or posedge rst) 96 | begin 97 | if(rst) 98 | last_state_rxn <= 0; 99 | else 100 | begin 101 | if(last_state_rxn == last_state_rxp) 102 | begin 103 | last_state_rxn <= ~last_state_rxp; 104 | end 105 | end 106 | end 107 | assign rx_start_detected = (last_state_rxn ^ last_state_rxp); 108 | 109 | /*Rx logic*/ 110 | always @ (posedge clk or posedge rst) 111 | begin 112 | if(rst || !rxen) 113 | begin 114 | last_state_rxp <= 0; 115 | state_rx <= state_idle; 116 | data <= 0; 117 | shift_reg_in <= 0; 118 | sckint_rx <= 0; 119 | charreceivedp <= 0; 120 | frameerror <= 0; 121 | parityerror <= 0; 122 | receiveoverrunn <= 0; 123 | rxbitcntstate <= 0; 124 | total_word_len_rx <= 0; 125 | end 126 | else 127 | begin 128 | if(state_rx == state_idle) 129 | begin 130 | // Wait for a transition from hi to low that indicate a start condition. 131 | if(rx_start_detected) 132 | begin 133 | shift_reg_in <= 0; 134 | sckint_rx <= 0; 135 | rxbitcntstate <= 7; 136 | // Calculate the total number of bits to receive including end. 137 | total_word_len_rx <= parity ? 1 : 0 + 1 + stopbits + wordlen; 138 | state_rx <= state_busy; 139 | end 140 | end 141 | else 142 | begin 143 | case(sckint_rx[3:0]) 144 | 7,8,9: 145 | begin 146 | rxbitcntstate <= rxbitcntstate + (rx ? 3'd7 : 3'd1); 147 | sckint_rx <= sckint_rx + 1; 148 | end 149 | 10: 150 | begin 151 | if(sckint_rx[7:4] == total_word_len_rx)// If is stop bit check-it and out the received data. 152 | begin 153 | // Verify stop bit to be valid, else report a frame error. 154 | frameerror <= ~rxbitcntstate[2]; 155 | // Verify the parity bit 156 | if(parity) 157 | parityerror <= parity_bit ^ chk_int; 158 | else 159 | parityerror <= 0; 160 | // Put data from shift register to output data register. 161 | data <= valid_data[8:1]; 162 | // Check if the previous received data has been read from output register, if not report a overrun situation.. 163 | if(charreceivedn == charreceivedp) 164 | charreceivedp <= ~charreceivedp; 165 | else 166 | begin 167 | if(receiveoverrunn == receiveoverrunp) 168 | receiveoverrunn <= ~receiveoverrunn; 169 | end 170 | state_rx <= state_idle; 171 | sckint_rx <= 0; 172 | last_state_rxp <= last_state_rxn; 173 | end 174 | else 175 | begin 176 | shift_reg_in[sckint_rx[7:4]] <= rxbitcntstate[2]; 177 | sckint_rx <= sckint_rx + 1; 178 | end 179 | end 180 | 15: 181 | begin 182 | rxbitcntstate <= 7; 183 | sckint_rx <= sckint_rx + 1; 184 | end 185 | default: 186 | begin 187 | sckint_rx <= sckint_rx + 1; 188 | end 189 | endcase 190 | end 191 | end 192 | end 193 | /* 194 | * You need to assert rd signal, wait a half core clock and after read the data(see simulation). 195 | */ 196 | wire rdrst; 197 | `ifdef READ_ON_NEG_EDGE == 1 198 | assign rdrst = ~rd | rst; 199 | `else 200 | assign rdrst = rd | rst; 201 | `endif 202 | always @ (posedge rdrst) 203 | begin 204 | if(rst || !rxen) 205 | begin 206 | charreceivedn <= 1'b0; 207 | receiveoverrunp <= 1'b0; 208 | end 209 | else 210 | begin 211 | if(charreceivedp != charreceivedn) 212 | charreceivedn <= ~charreceivedn; 213 | if(receiveoverrunn != receiveoverrunp) 214 | receiveoverrunp <= ~receiveoverrunp; 215 | end 216 | end 217 | 218 | assign receiveoverrun = (receiveoverrunp ^ receiveoverrunn); 219 | 220 | //assign data_out = (rd) ? output_buffer : {MAX_WORD_LEN{1'bz}}; 221 | 222 | assign charreceived = (charreceivedp ^ charreceivedn); 223 | 224 | 225 | 226 | endmodule 227 | -------------------------------------------------------------------------------- /uart_simulation.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 02/14/2017 05:30:05 PM 7 | // Design Name: 8 | // Module Name: simulation 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | 23 | module simulation( 24 | ); 25 | 26 | reg clk_in = 0; 27 | reg clk_out = 0; 28 | 29 | wire [8:0]data_rec; 30 | reg [8:0]data_send; 31 | 32 | reg [2:0]clk = 3'b000;/* Peripheral clock/not necessary to be core clock, the core clock can be different (input) */ 33 | wire rst;/* Asynchronus reset, is mandatory to provide this signal, active on posedge (input) */ 34 | reg _rst = 0; 35 | wire txen; 36 | reg _txen = 0; 37 | wire rxen; 38 | reg _rxen = 0; 39 | wire wr;/* Send data, asynchronus with 'clk' , active on posedge or negedge(input) */ 40 | reg _wr = 0; 41 | wire rd;/* Read data, , asynchronus with 'clk' , active on posedge or negedge (input) */ 42 | reg _rd = 0; 43 | wire buffempty;/* '1' if transmit buffer is empty (output) */ 44 | wire charreceived;/* Is set to '1' if a character is received, if you read the receive buffe this bit will go '0', if you ignore it and continue to send data this bit will remain '1' until you read the read register (output) */ 45 | reg [3:0]wordlen;/*0=6bit, 1=7bit, 2=8bit, 3=9bit*/ 46 | wire rx; 47 | wire tx; 48 | reg u2x = 0; 49 | wire [1:0]parity; 50 | reg [1:0]_parity = 0; 51 | reg stopbits = 0; 52 | reg mode = 0; 53 | wire receiveoverrun; 54 | 55 | //uart uart0( 56 | // .clk(clk[2]),/* Peripheral clock/not necessary to be core clock, the core clock can be different (input) */ 57 | // .rst(rst),/* Asynchronus reset, is mandatory to provide this signal, active on posedge (input) */ 58 | // .txen(txen), 59 | // .rxen(rxen), 60 | // .data_in(data_send),/* In/ data(input) */ 61 | // .data_out(data_rec),/* Out data(output) */ 62 | // .wr(wr),/* Send data, asynchronus with 'clk' , active on posedge or negedge(input) */ 63 | // .rd(rd),/* Read data, , asynchronus with 'clk' , active on posedge or negedge (input) */ 64 | // .buffempty(buffempty),/* '1' if transmit buffer is empty (output) */ 65 | // .prescaller(2),/* The prescaller divider is = (1 << prescaller) value between 0 and 7 for dividers by:1,2,4,8,16,32,64,128 and 256 (input)*/ 66 | // .charreceived(charreceived),/* Is set to '1' if a character is received, if you read the receive buffe this bit will go '0', if you ignore it and continue to send data this bit will remain '1' until you read the read register (output) */ 67 | // .wordlen(wordlen), 68 | // .rx(rx), 69 | // .tx(tx), 70 | // .u2x(u2x), 71 | // .parity(parity), 72 | // .stopbits(stopbits), 73 | // .mode(mode), 74 | // .receiveoverrun(receiveoverrun) 75 | //); 76 | 77 | uart_tx uart_tx0( 78 | .clk(clk[2]),/* Peripheral clock/not necessary to be core clock, the core clock can be different (input) */ 79 | .rst(rst),/* Asynchronus reset, is mandatory to provide this signal, active on posedge (input) */ 80 | .txen(txen), 81 | .data(data_send),/* In/ data(input) */ 82 | .wr(wr),/* Send data, asynchronus with 'clk' , active on posedge or negedge(input) */ 83 | .buffempty(buffempty),/* '1' if transmit buffer is empty (output) */ 84 | .wordlen(wordlen),/* 0 = 8bit, 1 = 5bit, 2 = 6bit, 3 = 7bit, 4 = 9bit, 5-6-7 = 8bit */ 85 | .tx(tx),/* Tx pin */ 86 | .u2x(u2x),/* Double speed */ 87 | .parity(parity),/* Parity type: 0 = none, 1 = even, 2 = odd (Not implemented yet) */ 88 | .stopbits(stopbits),/* Number of stop bits: 0 = one stop bit, 1 = Two stop bits */ 89 | .mode(1'b0)/*0 = Asysnhronous, 1 = Synchronous*/ 90 | ); 91 | 92 | uart_rx uart_rx0( 93 | .clk(clk[2]),/* Peripheral clock/not necessary to be core clock, the core clock can be different (input) */ 94 | .rst(rst),/* Asynchronus reset, is mandatory to provide this signal, active on posedge (input) */ 95 | .rxen(rxen), 96 | .data(data_rec),/* Out data(output) */ 97 | .rd(rd),/* Read data, , asynchronus with 'clk' , active on posedge or negedge (input) */ 98 | .charreceived(charreceived),/* Is set to '1' if a character is received, if you read the receive buffe this bit will go '0', if you ignore it and continue to send data this bit will remain '1' until you read the read register (output) */ 99 | .wordlen(wordlen),/* 0 = 8bit, 1 = 5bit, 2 = 6bit, 3 = 7bit, 4 = 9bit, 5-6-7 = 8bit */ 100 | .rx(rx),/* Rx pin */ 101 | .u2x(u2x),/* Double speed */ 102 | .parity(parity),/* Parity type: 0 = none, 1 = even, 2 = odd (Not implemented yet) */ 103 | .stopbits(stopbits),/* Number of stop bits: 0 = one stop bit, 1 = Two stop bits */ 104 | .mode(1'b0),/*0 = Asysnhronous, 1 = Synchronous*/ 105 | .frameerror(frameerror),/* If stop bit is not detected a frame error will report, this is actualized every received byte. */ 106 | .parityerror(parityerror),/* Parity error bit report (Not implemented yet) */ 107 | .receiveoverrun(receiveoverrun)/* If receive buffer is full and another char is received a receiveoverrun will report, this bit is resetted on read. */ 108 | ); 109 | 110 | parameter tck = 2; ///< clock tick 111 | 112 | always #(tck/2) clk_in <= ~clk_in; // clocking device 113 | 114 | initial begin 115 | #1; 116 | _rst <= 1; 117 | #2; 118 | _rst <= 0; 119 | wordlen = 8; 120 | stopbits = 0; 121 | _parity = 2'b00; 122 | mode = 0; 123 | u2x = 1'b0; 124 | #1; 125 | _txen = 1'b1; 126 | _rxen = 1'b1; 127 | #1; 128 | data_send = 8'h55; 129 | #1; 130 | _wr = 1'b1; 131 | #1; 132 | _wr = 1'b0; 133 | #1; 134 | wait(charreceived == 1); 135 | #1; 136 | _rd = 1'b1; 137 | #1; 138 | _rd = 1'b0; 139 | wait(buffempty == 1); 140 | data_send = 8'hAA; 141 | #1; 142 | _wr = 1'b1; 143 | #1; 144 | _wr = 1'b0; 145 | #1; 146 | data_send = 8'h00; 147 | wait(charreceived == 1); 148 | //wait(receiveoverrun == 1); 149 | #1; 150 | _rd = 1'b1; 151 | #1; 152 | _rd = 1'b0; 153 | #100; 154 | $finish; 155 | end 156 | 157 | assign rx = tx; 158 | 159 | assign parity = _parity; 160 | assign rst = _rst; 161 | assign txen = _txen; 162 | assign rxen = _rxen; 163 | assign wr = _wr; 164 | assign rd = _rd; 165 | 166 | always @ (posedge clk_in) 167 | begin 168 | clk <= clk + 1; 169 | end 170 | 171 | endmodule 172 | -------------------------------------------------------------------------------- /uart_tx.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 03/21/2017 02:54:54 PM 7 | // Design Name: 8 | // Module Name: uart_tx 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | 23 | module uart_tx( 24 | input clk,/* Peripheral clock/will be provided from a prescaller, no need to be 50% waveform (input) */ 25 | input rst,/* Asynchronus reset, is mandatory to provide this signal, active on posedge (input) */ 26 | input txen, 27 | input [8:0]data,/* In data(input) */ 28 | input wr,/* Send data, asynchronus with 'clk' , active on posedge or negedge(input) */ 29 | output buffempty,/* '1' if transmit buffer is empty (output) */ 30 | input [3:0]wordlen,/* In bits */ 31 | output reg tx,/* Tx pin */ 32 | inout sck,/* Synchronous clk pin (Not implemented yet) */ 33 | input u2x,/* Double speed */ 34 | input [1:0]parity,/* Parity type: 0 = none, 1 = even, 2 = odd (Not implemented yet) */ 35 | input stopbits,/* Number of stop bits: 0 = one stop bit, 1 = Two stop bits */ 36 | input mode/*0 = Asysnhronous, 1 = Synchronous*/ 37 | ); 38 | 39 | parameter MAX_WORD_LEN = 9; 40 | parameter state_idle = 1'b0; 41 | parameter state_busy = 1'b1; 42 | 43 | reg state_tx; 44 | reg [(MAX_WORD_LEN - 1) + 4:0]shift_reg_out; 45 | reg [MAX_WORD_LEN - 1:0]input_buffer; 46 | 47 | reg inbufffullp; 48 | reg inbufffulln; 49 | 50 | reg [3:0]sckint_tx; 51 | reg [3:0]bitcount_tx; 52 | reg [3:0]total_word_len_tx; 53 | 54 | wire _chk_int; 55 | wire chk_int; 56 | reg [(MAX_WORD_LEN - 1) + 4:0]parity_mask; 57 | wire [(MAX_WORD_LEN - 1) + 4:0]parity_rest; 58 | 59 | always @ (*) 60 | begin 61 | case(wordlen) 62 | 4'h05: parity_mask <= 12'b000000111110; 63 | 4'h06: parity_mask <= 12'b000001111110; 64 | 4'h07: parity_mask <= 12'b000011111110; 65 | 4'h09: parity_mask <= 12'b001111111110; 66 | default: parity_mask <= 12'b000111111110; 67 | endcase 68 | end 69 | /*assign parity_mask = (wordlen == 4'h08) ? 12'b000111111110: 70 | (wordlen == 4'h05) ? 12'b000000111110: 71 | (wordlen == 4'h06) ? 12'b000001111110: 72 | (wordlen == 4'h07) ? 12'b000011111110: 73 | (wordlen == 4'h09) ? 12'b001111111110: 74 | 12'b000111111110;*/ 75 | 76 | assign parity_rest = shift_reg_out & parity_mask; 77 | assign _chk_int = ^parity_rest; 78 | assign chk_int = (parity == 2'b10) ? ~_chk_int:_chk_int; 79 | 80 | assign buffempty = ~(inbufffullp ^ inbufffulln); 81 | 82 | /***********************************************/ 83 | /************* Asynchronus send ****************/ 84 | /***********************************************/ 85 | /* 86 | * You need to put the data on the bus and wait a half of core clock to assert the wr signal(see simulation). 87 | */ 88 | always @ (posedge wr/* or posedge rst*/) 89 | begin 90 | if(wr && inbufffullp == inbufffulln && buffempty && txen) 91 | begin 92 | input_buffer <= data; 93 | end 94 | end 95 | 96 | always @ (negedge wr or posedge rst) 97 | begin 98 | if(rst || !txen) 99 | inbufffullp <= 1'b0; 100 | else 101 | if(inbufffullp == inbufffulln && buffempty && txen) 102 | begin 103 | inbufffullp <= ~inbufffullp; 104 | end 105 | end 106 | 107 | wire [4:0]input_buffer_tmp_5b = input_buffer[4:0]; 108 | wire [5:0]input_buffer_tmp_6b = input_buffer[5:0]; 109 | wire [6:0]input_buffer_tmp_7b = input_buffer[6:0]; 110 | wire [7:0]input_buffer_tmp_8b = input_buffer[7:0]; 111 | wire [8:0]input_buffer_tmp_9b = input_buffer[8:0]; 112 | 113 | /*Tx logic*/ 114 | always @ (posedge clk or posedge rst) 115 | begin 116 | if(rst || !txen) 117 | begin 118 | inbufffulln <= 1'b0; 119 | state_tx <= state_idle; 120 | shift_reg_out <= {MAX_WORD_LEN{1'b0}}; 121 | sckint_tx <= {5{1'b0}}; 122 | bitcount_tx <= {4{1'b0}}; 123 | total_word_len_tx <= {4{1'b0}}; 124 | tx <= 1'b1; 125 | end 126 | else 127 | begin 128 | case(state_tx) 129 | state_idle: 130 | begin 131 | if(inbufffullp != inbufffulln) 132 | begin 133 | inbufffulln <= inbufffullp; 134 | sckint_tx <= 5'h01; 135 | case({parity, stopbits, wordlen}) 136 | {2'b00, 4'h05}: shift_reg_out <= {1'b1, input_buffer[4:0], 1'h0}; 137 | {2'b00, 4'h06}: shift_reg_out <= {1'b1, input_buffer[5:0], 1'h0}; 138 | {2'b00, 4'h07}: shift_reg_out <= {1'b1, input_buffer[6:0], 1'h0}; 139 | {2'b00, 4'h08}: shift_reg_out <= {1'b1, input_buffer[7:0], 1'h0}; 140 | {2'b00, 4'h09}: shift_reg_out <= {1'b1, input_buffer[8:0], 1'h0}; 141 | {2'b01, 4'h05}: shift_reg_out <= {2'b11, input_buffer[4:0], 1'h0}; 142 | {2'b01, 4'h06}: shift_reg_out <= {2'b11, input_buffer[5:0], 1'h0}; 143 | {2'b01, 4'h07}: shift_reg_out <= {2'b11, input_buffer[6:0], 1'h0}; 144 | {2'b01, 4'h08}: shift_reg_out <= {2'b11, input_buffer[7:0], 1'h0}; 145 | {2'b01, 4'h09}: shift_reg_out <= {2'b11, input_buffer[8:0], 1'h0}; 146 | {2'b10, 4'h05}: shift_reg_out <= {1'b1, chk_int, input_buffer[4:0], 1'h0}; 147 | {2'b10, 4'h06}: shift_reg_out <= {1'b1, chk_int, input_buffer[5:0], 1'h0}; 148 | {2'b10, 4'h07}: shift_reg_out <= {1'b1, chk_int, input_buffer[6:0], 1'h0}; 149 | {2'b10, 4'h08}: shift_reg_out <= {1'b1, chk_int, input_buffer[7:0], 1'h0}; 150 | {2'b10, 4'h09}: shift_reg_out <= {1'b1, chk_int, input_buffer[8:0], 1'h0}; 151 | {2'b11, 4'h05}:shift_reg_out <= {2'b11, chk_int, input_buffer[4:0], 1'h0}; 152 | {2'b11, 4'h06}:shift_reg_out <= {2'b11, chk_int, input_buffer[5:0], 1'h0}; 153 | {2'b11, 4'h07}:shift_reg_out <= {2'b11, chk_int, input_buffer[6:0], 1'h0}; 154 | {2'b11, 4'h08}:shift_reg_out <= {2'b11, chk_int, input_buffer[7:0], 1'h0}; 155 | {2'b11, 4'h09}:shift_reg_out <= {2'b11, chk_int, input_buffer[8:0], 1'h0}; 156 | default: shift_reg_out <= {1'b1, input_buffer[7:0], 1'h0}; 157 | endcase 158 | bitcount_tx <= 4'b0000; 159 | total_word_len_tx <= parity ? 1 : 0 + 1 + stopbits + wordlen + 1; 160 | state_tx <= state_busy; 161 | /*Put start, first bit from shift_reg_out*/ 162 | tx <= 1'b0; 163 | end 164 | end 165 | state_busy: 166 | begin 167 | case(sckint_tx) 168 | 4'h0D: 169 | begin 170 | sckint_tx <= sckint_tx + 1; 171 | bitcount_tx <= bitcount_tx + 4'b0001; 172 | end 173 | 4'h0E: 174 | begin 175 | if(bitcount_tx == total_word_len_tx) 176 | state_tx <= state_idle; 177 | sckint_tx <= sckint_tx + 1; 178 | end 179 | 4'h0F: 180 | begin 181 | sckint_tx <= sckint_tx + 1; 182 | tx <= shift_reg_out[bitcount_tx]; 183 | end 184 | default: 185 | begin 186 | sckint_tx <= sckint_tx + 1; 187 | end 188 | endcase 189 | end 190 | endcase 191 | end 192 | end 193 | 194 | endmodule 195 | -------------------------------------------------------------------------------- /util.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | ////////////////////////////////////////////////////////////////////////////////// 3 | // Company: 4 | // Engineer: 5 | // 6 | // Create Date: 08/10/2017 04:58:07 PM 7 | // Design Name: 8 | // Module Name: util 9 | // Project Name: 10 | // Target Devices: 11 | // Tool Versions: 12 | // Description: 13 | // 14 | // Dependencies: 15 | // 16 | // Revision: 17 | // Revision 0.01 - File Created 18 | // Additional Comments: 19 | // 20 | ////////////////////////////////////////////////////////////////////////////////// 21 | 22 | 23 | module reg_write_generator( 24 | input rst, 25 | input clk, 26 | input wtite, 27 | output pulse 28 | ); 29 | 30 | reg write_to_reg_p = 0; 31 | reg write_to_reg_n = 0; 32 | 33 | always @ (posedge clk) 34 | begin 35 | if(rst) 36 | write_to_reg_p <= 0; 37 | else 38 | begin 39 | if(wtite && write_to_reg_p ^ ~write_to_reg_n) 40 | write_to_reg_p <= ~write_to_reg_n; 41 | end 42 | end 43 | 44 | always @ (negedge clk) 45 | begin 46 | if(rst) 47 | write_to_reg_n <= 0; 48 | else 49 | begin 50 | if(write_to_reg_p ^ write_to_reg_n) 51 | write_to_reg_n <= write_to_reg_p; 52 | end 53 | end 54 | 55 | assign pulse = write_to_reg_p ^ write_to_reg_n; 56 | 57 | endmodule 58 | 59 | -------------------------------------------------------------------------------- /xmega_core/core1ROM.mem: -------------------------------------------------------------------------------- 1 | c009 2 | d001 3 | 9508 4 | 0000 5 | 9508 6 | 940e 7 | 0003 8 | dff9 9 | 0000 10 | 0000 11 | 12 | c000 13 | 2400 14 | 27cc 15 | 27dd 16 | 2788 17 | 2799 18 | efaf 19 | e0b0 20 | 21 | 9701 22 | 09a0 23 | 40b0 24 | f00a 25 | cffb 26 | 27 | b100 28 | ef1f 29 | 2701 30 | b900 31 | 2788 32 | 2799 33 | efaf 34 | e0b0 35 | 36 | 9701 37 | 09a0 38 | 40b0 39 | f00a 40 | cffb 41 | 42 | b100 43 | 830a 44 | 811a 45 | ef0f 46 | 2710 47 | 2710 48 | 931f 49 | 900f 50 | 2600 51 | 9200 52 | 0008 53 | 9010 54 | 0008 55 | 2610 56 | b810 57 | 0e10 58 | 1a10 59 | e3e9 60 | e0f0 61 | 9409 62 | 9508 63 | 9731 64 | 9631 65 | 54e0 66 | 40f0 67 | 5ce0 68 | 4fff 69 | 95e1 70 | 95e1 71 | 95e0 72 | 95e0 73 | 95e6 74 | 0fee 75 | 95e7 76 | 1fee 77 | 13ee 78 | 0000 79 | 13ee 80 | 940c 81 | 004d 82 | 0000 83 | 9302 84 | 9111 85 | e3a5 86 | e0b0 87 | e202 88 | 930e 89 | 9503 90 | 930e 91 | 9503 92 | 930e 93 | 911d 94 | 911d 95 | 911d 96 | e3e8 97 | e0f0 98 | 9509 99 | 940c 100 | 0005 101 | 102 | -------------------------------------------------------------------------------- /xmega_core/core1ROMsym.mem: -------------------------------------------------------------------------------- 1 | c009 2 | d001 3 | 9508 4 | 0000 5 | 9508 6 | 940e 7 | 0003 8 | dff9 9 | 0000 10 | 0000 11 | 12 | c000 13 | 2400 14 | 27cc 15 | 27dd 16 | ef8f 17 | 2799 18 | e0a0 19 | e0b0 20 | 21 | 9701 22 | 09a0 23 | 40b0 24 | f00a 25 | cffb 26 | 27 | b100 28 | ef1f 29 | 2701 30 | b900 31 | ef8f 32 | 2799 33 | e0a0 34 | e0b0 35 | 36 | 9701 37 | 09a0 38 | 40b0 39 | f00a 40 | cffb 41 | 42 | b100 43 | 830a 44 | 811a 45 | ef0f 46 | 2710 47 | 2710 48 | 931f 49 | 900f 50 | 2600 51 | 9200 52 | 0008 53 | 9010 54 | 0008 55 | 2610 56 | b810 57 | 0e10 58 | 1a10 59 | e3e9 60 | e0f0 61 | 9409 62 | 9508 63 | 9731 64 | 9631 65 | 54e0 66 | 40f0 67 | 5ce0 68 | 4fff 69 | 95e1 70 | 95e1 71 | 95e0 72 | 95e0 73 | 95e6 74 | 0fee 75 | 95e7 76 | 1fee 77 | 13ee 78 | 0000 79 | 13ee 80 | 940c 81 | 004d 82 | 0000 83 | 9302 84 | 9111 85 | e3a5 86 | e0b0 87 | e202 88 | 930e 89 | 9503 90 | 930e 91 | 9503 92 | 930e 93 | 911d 94 | 911d 95 | 911d 96 | e3e8 97 | e0f0 98 | 9509 99 | 940c 100 | 0005 101 | -------------------------------------------------------------------------------- /xmega_core/io/io_i2c.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This IP is the Atmel I2C adaptor implementation. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | `timescale 1ns / 1ps 22 | 23 | module i2c( 24 | 25 | ); 26 | endmodule 27 | -------------------------------------------------------------------------------- /xmega_core/io/io_spi.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This IP is the Atmel SPI adaptor implementation. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | `timescale 1ns / 1ps 22 | 23 | module spi( 24 | 25 | ); 26 | endmodule 27 | -------------------------------------------------------------------------------- /xmega_core/io/io_uart.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This IP is the Atmel UART adaptor implementation. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | `timescale 1ns / 1ps 22 | 23 | module uart( 24 | 25 | ); 26 | endmodule 27 | -------------------------------------------------------------------------------- /xmega_core/io/pio.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This IP is the Atmel PIO adaptor implementation. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | `timescale 1ns / 1ps 22 | 23 | module pio( 24 | 25 | ); 26 | endmodule 27 | -------------------------------------------------------------------------------- /xmega_core/mega_alu.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This IP is the ALU for Atmel XMEGA CPU implementation. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | `timescale 1ns / 1ps 22 | 23 | `include "mega_alu_h.v" 24 | `include "mega_core_h.v" 25 | `include "mega_core_cfg_h.v" 26 | 27 | module mega_alu( 28 | input [15:0]inst, 29 | input [4:0]in_addr_1, 30 | input [4:0]in_addr_2, 31 | input [15:0]in_1, 32 | input [15:0]in_2, 33 | output reg [15:0]out, 34 | //output c_out, 35 | input ALU_FLAG_C_IN, //Zero Flag 36 | input ALU_FLAG_Z_IN, //Zero Flag 37 | input ALU_FLAG_N_IN, //Negative Flag 38 | input ALU_FLAG_V_IN, //Two's complement overflow indicator 39 | input ALU_FLAG_S_IN, //N?V for signed tests 40 | input ALU_FLAG_H_IN, //Half Carry Flag 41 | input ALU_FLAG_T_IN, //Transfer bit used by BLD and BST instructions 42 | input ALU_FLAG_I_IN, //Global Interrupt Enable/Disable Flag 43 | output reg ALU_FLAG_C_OUT, //Carry Flag 44 | output reg ALU_FLAG_Z_OUT, //Zero Flag 45 | output reg ALU_FLAG_N_OUT, //Negative Flag 46 | output reg ALU_FLAG_V_OUT, //Two's complement overflow indicator 47 | output reg ALU_FLAG_S_OUT, //N?V for signed tests 48 | output reg ALU_FLAG_H_OUT, //Half Carry Flag 49 | output reg ALU_FLAG_T_OUT, //Transfer bit used by BLD and BST instructions 50 | output reg ALU_FLAG_I_OUT //Global Interrupt Enable/Disable Flag 51 | ); 52 | 53 | initial 54 | begin 55 | ALU_FLAG_C_OUT = 0; 56 | ALU_FLAG_Z_OUT = 0; 57 | ALU_FLAG_N_OUT = 0; 58 | ALU_FLAG_V_OUT = 0; 59 | ALU_FLAG_S_OUT = 0; 60 | ALU_FLAG_H_OUT = 0; 61 | ALU_FLAG_T_OUT = 0; 62 | ALU_FLAG_I_OUT = 0; 63 | end 64 | 65 | reg in_addr_1_and_2_equal; 66 | 67 | always @ (in_addr_1 or in_addr_2) 68 | begin 69 | in_addr_1_and_2_equal = (in_addr_1 == in_addr_2) ? 1'b1 : 1'b0; 70 | end 71 | 72 | reg [15:0]in_2_int; 73 | reg cin_int; 74 | 75 | always @ (*) 76 | begin 77 | in_2_int <= in_1; 78 | cin_int <= ALU_FLAG_C_IN; 79 | 80 | casex(inst) 81 | `INSTRUCTION_ADD, 82 | `INSTRUCTION_ADC: 83 | begin 84 | if(!in_addr_1_and_2_equal) 85 | in_2_int <= in_2; 86 | end 87 | `ifndef CORE_TYPE_REDUCED 88 | `ifndef CORE_TYPE_MINIMAL 89 | `INSTRUCTION_ADIW, 90 | `INSTRUCTION_SBIW, 91 | `endif 92 | `endif 93 | `INSTRUCTION_SUB, 94 | `INSTRUCTION_SBC, 95 | `INSTRUCTION_SUBI, 96 | `INSTRUCTION_SBCI, 97 | `INSTRUCTION_INC, 98 | `INSTRUCTION_DEC, 99 | `INSTRUCTION_LPM_R_P : in_2_int <= in_2; 100 | endcase 101 | 102 | casex(inst) 103 | `INSTRUCTION_ADD, 104 | `INSTRUCTION_LSR, 105 | `INSTRUCTION_NEG, 106 | `INSTRUCTION_SUB, 107 | `INSTRUCTION_SUBI, 108 | `INSTRUCTION_INC, 109 | `INSTRUCTION_DEC: cin_int <= 1'b0; 110 | endcase 111 | 112 | end 113 | 114 | wire [17:0] add_result_int_w_c_tmp = {in_1, 1'b1} + {in_2_int, cin_int}; 115 | wire [16:0] add_result_int_w_c = add_result_int_w_c_tmp[17:1]; 116 | wire [17:0] sub_result_int_w_c_tmp = {in_1, 1'b0} - {in_2_int, cin_int}; 117 | wire [16:0] sub_result_int_w_c = sub_result_int_w_c_tmp[17:1]; 118 | 119 | `ifndef CORE_TYPE_REDUCED 120 | `ifndef CORE_TYPE_MINIMAL 121 | `ifndef CORE_TYPE_CLASSIC_8K 122 | `ifndef CORE_TYPE_CLASSIC_128K 123 | /* 124 | * Multiply Unit. 125 | */ 126 | 127 | reg [7:0]in_1_mul; 128 | reg [7:0]in_2_mul; 129 | wire [15:0]mul_result_int = in_1_mul * in_2_mul; 130 | reg mul_b15; 131 | 132 | always @ (*) 133 | begin 134 | casex(inst) 135 | `INSTRUCTION_MUL: 136 | begin 137 | in_1_mul <= in_1; 138 | in_2_mul <= in_2; 139 | end 140 | `INSTRUCTION_MULS: 141 | begin 142 | in_1_mul <= in_1[6:0]; 143 | in_2_mul <= in_2[6:0]; 144 | mul_b15 <= (in_1[7] ^ in_2[7]); 145 | end 146 | `INSTRUCTION_MULSU: 147 | begin 148 | in_1_mul <= in_1[6:0]; 149 | in_2_mul <= in_2[7:0]; 150 | mul_b15 <= in_1[7]; 151 | end 152 | `INSTRUCTION_FMUL: 153 | begin 154 | in_1_mul <= in_1[7:1]; 155 | in_2_mul <= in_2[7:1]; 156 | end 157 | `INSTRUCTION_FMULS: 158 | begin 159 | in_1_mul <= in_1[6:1]; 160 | in_2_mul <= in_2[6:1]; 161 | mul_b15 <= (in_1[7] ^ in_2[7]); 162 | end 163 | `INSTRUCTION_FMULSU: 164 | begin 165 | in_1_mul <= in_1[6:1]; 166 | in_2_mul <= in_2[7:1]; 167 | mul_b15 <= in_1[7]; 168 | end 169 | default: 170 | begin 171 | in_1_mul <= 0; 172 | in_2_mul <= 0; 173 | mul_b15 <= 0; 174 | end 175 | endcase 176 | end 177 | 178 | `endif 179 | `endif 180 | `endif 181 | `endif 182 | wire carry_8bit = in_1 < in_2; 183 | wire carry_8bit_plus_carry = in_1 < (in_2 + ALU_FLAG_C_IN); 184 | 185 | always @ (*) 186 | begin 187 | {ALU_FLAG_C_OUT, out} <= 17'h00000; 188 | casex(inst) 189 | `INSTRUCTION_ADD: 190 | begin 191 | if(in_addr_1_and_2_equal) 192 | {ALU_FLAG_C_OUT, out} <= {in_1[7], 7'h00, in_1[6:0], cin_int};//LSL 193 | else 194 | {ALU_FLAG_C_OUT, out} <= {add_result_int_w_c[8], 8'h00, add_result_int_w_c[7:0]}; 195 | end 196 | `INSTRUCTION_ADC: 197 | begin 198 | if(in_addr_1_and_2_equal) 199 | {ALU_FLAG_C_OUT, out} <= {in_1[7], 7'h00, in_1[6:0], cin_int};//ROL 200 | else 201 | {ALU_FLAG_C_OUT, out} <= {add_result_int_w_c[8], 8'h00, add_result_int_w_c[7:0]}; 202 | end 203 | `INSTRUCTION_INC, 204 | `INSTRUCTION_DEC: {ALU_FLAG_C_OUT, out} <= {add_result_int_w_c[8], 8'h00, add_result_int_w_c[7:0]}; 205 | `INSTRUCTION_SUB, 206 | `INSTRUCTION_SBC, 207 | `INSTRUCTION_SUBI, 208 | `INSTRUCTION_SBCI: {ALU_FLAG_C_OUT, out} <= {sub_result_int_w_c[8], 8'h00, sub_result_int_w_c[7:0]}; 209 | `INSTRUCTION_LSR, 210 | `INSTRUCTION_ROR: {ALU_FLAG_C_OUT, out} <= {in_1[0], 7'h00, cin_int, in_1[7:1]}; 211 | `INSTRUCTION_AND: {ALU_FLAG_C_OUT, out} <= {9'h00, (in_1[7:0] & in_2[7:0])}; 212 | `INSTRUCTION_OR: {ALU_FLAG_C_OUT, out} <= {9'h00, (in_1[7:0] | in_2[7:0])}; 213 | `INSTRUCTION_EOR: {ALU_FLAG_C_OUT, out} <= {9'h00, (in_1[7:0] ^ in_2[7:0])}; 214 | `INSTRUCTION_MOV: {ALU_FLAG_C_OUT, out} <= {9'h00, in_1[7:0]}; 215 | `INSTRUCTION_MOVW: {ALU_FLAG_C_OUT, out} <= {1'h00, in_1}; 216 | `INSTRUCTION_COM: {ALU_FLAG_C_OUT, out} <= {1'b1, 8'h00, (8'h00 - in_1[7:0])}; 217 | `INSTRUCTION_NEG: {ALU_FLAG_C_OUT, out} <= {|in_1[7:0], 8'h00, ~in_1[7:0]}; 218 | `ifndef CORE_TYPE_REDUCED 219 | `ifndef CORE_TYPE_MINIMAL 220 | `INSTRUCTION_ADIW: {ALU_FLAG_C_OUT, out} <= add_result_int_w_c; 221 | `INSTRUCTION_SBIW: {ALU_FLAG_C_OUT, out} <= sub_result_int_w_c; 222 | `endif 223 | `endif 224 | `ifndef CORE_TYPE_REDUCED 225 | `ifndef CORE_TYPE_MINIMAL 226 | `ifndef CORE_TYPE_CLASSIC_8K 227 | `ifndef CORE_TYPE_CLASSIC_128K 228 | `INSTRUCTION_MUL, 229 | `INSTRUCTION_FMUL: {ALU_FLAG_C_OUT, out} <= {mul_result_int[15], mul_result_int}; 230 | `INSTRUCTION_MULS, 231 | `INSTRUCTION_MULSU, 232 | `INSTRUCTION_FMULS, 233 | `INSTRUCTION_FMULSU: {ALU_FLAG_C_OUT, out} <= {mul_b15, mul_result_int}; 234 | `endif 235 | `endif 236 | `endif 237 | `endif 238 | `INSTRUCTION_ASR: {ALU_FLAG_C_OUT, out} <= {in_1[0], 7'h00, in_1[7], in_1[7:1]}; 239 | `INSTRUCTION_CP, 240 | `INSTRUCTION_CPI: {ALU_FLAG_C_OUT, out} <= {carry_8bit, 16'h0000}; 241 | `INSTRUCTION_CPC: {ALU_FLAG_C_OUT, out} <= {carry_8bit_plus_carry, 16'h0000}; 242 | `INSTRUCTION_SWAP: {ALU_FLAG_C_OUT, out} <= {1'b0, in_1[3:0], in_1[7:4]}; 243 | `INSTRUCTION_SEx_CLx: {ALU_FLAG_C_OUT, out} <= inst[6:4] ? {ALU_FLAG_C_IN, {16{1'b0}}} : {inst[7], {16{1'b0}}}; 244 | `ifndef CORE_TYPE_REDUCED 245 | `INSTRUCTION_LPM_R_P: {ALU_FLAG_C_OUT, out} <= add_result_int_w_c; 246 | `endif 247 | endcase 248 | end 249 | 250 | /* 251 | * ALU FLAG effect for each instruction. 252 | */ 253 | always @ (inst or out or in_1 or in_2) 254 | begin 255 | ALU_FLAG_Z_OUT <= ALU_FLAG_Z_IN; 256 | ALU_FLAG_N_OUT <= ALU_FLAG_N_IN; 257 | ALU_FLAG_V_OUT <= ALU_FLAG_V_IN; 258 | ALU_FLAG_S_OUT <= ALU_FLAG_S_IN; 259 | ALU_FLAG_H_OUT <= ALU_FLAG_H_IN; 260 | ALU_FLAG_T_OUT <= ALU_FLAG_T_IN; 261 | ALU_FLAG_I_OUT <= ALU_FLAG_I_IN; 262 | casex(inst) 263 | `INSTRUCTION_ADD: 264 | begin 265 | if(in_addr_1_and_2_equal) 266 | begin 267 | ALU_FLAG_H_OUT <= in_1[3]; 268 | ALU_FLAG_V_OUT <= ALU_FLAG_N_OUT & ALU_FLAG_C_OUT; 269 | end 270 | else 271 | begin 272 | ALU_FLAG_H_OUT <= (in_1[3] & in_2[3])|(in_2[3] & ~out[3])|(~out[3] & in_1[3]); 273 | ALU_FLAG_V_OUT <= (in_1[7] & in_2[7] & ~out[7])|(~in_1[7] & ~in_2[7] & out[7]); 274 | end 275 | ALU_FLAG_S_OUT <= ALU_FLAG_N_OUT & ALU_FLAG_V_OUT; 276 | ALU_FLAG_N_OUT <= out[7]; 277 | ALU_FLAG_Z_OUT <= &(~out[7:0]); 278 | end 279 | `INSTRUCTION_ADC: 280 | begin 281 | if(in_addr_1_and_2_equal) 282 | begin 283 | ALU_FLAG_H_OUT <= in_1[3]; 284 | ALU_FLAG_V_OUT <= ALU_FLAG_N_OUT & ALU_FLAG_C_OUT; 285 | ALU_FLAG_Z_OUT <= &(~out[7:0]); 286 | end 287 | else 288 | begin 289 | ALU_FLAG_H_OUT <= (in_1[3] & in_2[3])|(in_2[3] & ~out[3])|(~out[3] & in_1[3]); 290 | ALU_FLAG_V_OUT <= (in_1[7] & in_2[7] & ~out[7])|(~in_1[7] & ~in_2[7] & out[7]); 291 | ALU_FLAG_Z_OUT <= &(~{out[7:0], ALU_FLAG_Z_IN}); 292 | end 293 | ALU_FLAG_S_OUT <= ALU_FLAG_N_OUT & ALU_FLAG_V_OUT; 294 | ALU_FLAG_N_OUT <= out[7]; 295 | end 296 | `INSTRUCTION_SUB, 297 | `INSTRUCTION_SUBI, 298 | `INSTRUCTION_CP, 299 | `INSTRUCTION_CPI: 300 | begin 301 | ALU_FLAG_H_OUT <= (in_1[3] & in_2[3])|(in_2[3] & ~out[3])|(~out[3] & in_1[3]); 302 | ALU_FLAG_S_OUT <= ALU_FLAG_N_OUT & ALU_FLAG_V_OUT; 303 | ALU_FLAG_V_OUT <= (in_1[7] & in_2[7] & ~out[7])|(~in_1[7] & ~in_2[7] & out[7]); 304 | ALU_FLAG_N_OUT <= out[7]; 305 | ALU_FLAG_Z_OUT <= &(~out[7:0]); 306 | end 307 | `INSTRUCTION_INC, 308 | `INSTRUCTION_DEC: 309 | begin 310 | ALU_FLAG_S_OUT <= ALU_FLAG_N_OUT & ALU_FLAG_V_OUT; 311 | ALU_FLAG_V_OUT <= &{out[7], ~out[6:0]}; 312 | ALU_FLAG_N_OUT <= out[7]; 313 | ALU_FLAG_Z_OUT <= &(~out[7:0]); 314 | end 315 | `INSTRUCTION_SBC, 316 | `INSTRUCTION_SBCI, 317 | `INSTRUCTION_CPC: 318 | begin 319 | ALU_FLAG_H_OUT <= (in_1[3] & in_2[3])|(in_2[3] & ~out[3])|(~out[3] & in_1[3]); 320 | ALU_FLAG_S_OUT <= ALU_FLAG_N_OUT & ALU_FLAG_V_OUT; 321 | ALU_FLAG_V_OUT <= (in_1[7] & in_2[7] & ~out[7])|(~in_1[7] & ~in_2[7] & out[7]); 322 | ALU_FLAG_N_OUT <= out[7]; 323 | ALU_FLAG_Z_OUT <= &(~{out[7:0], ALU_FLAG_Z_IN}); 324 | end 325 | `ifndef CORE_TYPE_REDUCED 326 | `ifndef CORE_TYPE_MINIMAL 327 | `INSTRUCTION_ADIW, 328 | `INSTRUCTION_SBIW: 329 | begin 330 | ALU_FLAG_S_OUT <= ALU_FLAG_N_OUT & ALU_FLAG_V_OUT; 331 | ALU_FLAG_V_OUT <= ALU_FLAG_C_OUT; 332 | ALU_FLAG_N_OUT <= out[15]; 333 | ALU_FLAG_Z_OUT <= &(~out[15:0]); 334 | end 335 | `endif 336 | `endif 337 | `INSTRUCTION_AND, 338 | `INSTRUCTION_OR, 339 | `INSTRUCTION_COM, 340 | `INSTRUCTION_EOR: 341 | begin 342 | ALU_FLAG_S_OUT <= ALU_FLAG_N_OUT & ALU_FLAG_V_OUT; 343 | ALU_FLAG_V_OUT <= 1'b0; 344 | ALU_FLAG_N_OUT <= out[7]; 345 | ALU_FLAG_Z_OUT <= &(~out[7:0]); 346 | end 347 | `INSTRUCTION_NEG: 348 | begin 349 | ALU_FLAG_H_OUT <= out[3] + ~in_1[3]; 350 | ALU_FLAG_S_OUT <= ALU_FLAG_N_OUT & ALU_FLAG_V_OUT; 351 | ALU_FLAG_V_OUT <= &{out[7], ~out[6:0]}; 352 | ALU_FLAG_N_OUT <= out[7]; 353 | ALU_FLAG_Z_OUT <= &(~out[7:0]); 354 | end 355 | `INSTRUCTION_ASR: 356 | begin 357 | ALU_FLAG_S_OUT <= ALU_FLAG_N_OUT & ALU_FLAG_V_OUT; 358 | ALU_FLAG_V_OUT <= 1'b0; 359 | ALU_FLAG_N_OUT <= out[7]; 360 | ALU_FLAG_Z_OUT <= &(~out[7:0]); 361 | end 362 | `INSTRUCTION_LSR, 363 | `INSTRUCTION_ROR: 364 | begin 365 | ALU_FLAG_H_OUT <= in_1[3]; 366 | ALU_FLAG_S_OUT <= ALU_FLAG_N_OUT & ALU_FLAG_V_OUT; 367 | ALU_FLAG_V_OUT <= ALU_FLAG_N_OUT & ALU_FLAG_C_OUT; 368 | ALU_FLAG_N_OUT <= 0; 369 | ALU_FLAG_Z_OUT <= &(~out[7:0]); 370 | end 371 | `INSTRUCTION_SEx_CLx: 372 | begin 373 | case(inst[6:4]) 374 | 3'd1: ALU_FLAG_Z_OUT <= inst[7]; 375 | 3'd2: ALU_FLAG_N_OUT <= inst[7]; 376 | 3'd3: ALU_FLAG_V_OUT <= inst[7]; 377 | 3'd4: ALU_FLAG_S_OUT <= inst[7]; 378 | 3'd5: ALU_FLAG_H_OUT <= inst[7]; 379 | 3'd6: ALU_FLAG_T_OUT <= inst[7]; 380 | 3'd7: ALU_FLAG_I_OUT <= inst[7]; 381 | endcase 382 | end 383 | `ifndef CORE_TYPE_REDUCED 384 | `ifndef CORE_TYPE_MINIMAL 385 | `ifndef CORE_TYPE_CLASSIC_8K 386 | `ifndef CORE_TYPE_CLASSIC_128K 387 | `INSTRUCTION_MUL, 388 | `INSTRUCTION_FMUL: ALU_FLAG_Z_OUT <= &(~out[15:0]); 389 | `INSTRUCTION_MULS, 390 | `INSTRUCTION_MULSU, 391 | `INSTRUCTION_FMULS, 392 | `INSTRUCTION_FMULSU: ALU_FLAG_Z_OUT <= &(~out[14:0]); 393 | `endif 394 | `endif 395 | `endif 396 | `endif 397 | endcase 398 | end 399 | 400 | endmodule 401 | -------------------------------------------------------------------------------- /xmega_core/mega_alu_h.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This IP is the Atmel XMEGA ALU header definition file. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | 22 | `define ALU_FLAG_C 0 23 | `define ALU_FLAG_Z 1 24 | `define ALU_FLAG_N 2 25 | `define ALU_FLAG_V 3 26 | `define ALU_FLAG_S 4 27 | `define ALU_FLAG_H 5 28 | `define ALU_FLAG_T 6 29 | `define ALU_FLAG_I 7 30 | 31 | 32 | -------------------------------------------------------------------------------- /xmega_core/mega_core_cfg_h.v: -------------------------------------------------------------------------------- 1 | 2 | //`define CORE_TYPE_REDUCED 3 | //`define CORE_TYPE_MINIMAL 4 | //`define CORE_TYPE_CLASSIC_8K 5 | //`define CORE_TYPE_CLASSIC_128K 6 | //`define CORE_TYPE_ENCHANCED_8K 7 | `define CORE_TYPE_ENCHANCED_128K 8 | //`define CORE_TYPE_ENCHANCED_4M//Not implemented 9 | //`define CORE_TYPE_XMEGA 10 | 11 | 12 | -------------------------------------------------------------------------------- /xmega_core/mega_core_h.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This IP is the Atmel XMEGA CPU header definition file. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | //`define USE_MULTIPLYER 22 | 23 | 24 | `define STEP0 0 25 | `define STEP1 1 26 | `define STEP2 2 27 | `define STEP3 3 28 | `define STEP4 4 29 | 30 | 31 | 32 | `define INSTRUCTION_NOP 16'b0000000000000000 33 | `define INSTRUCTION_MOVW 16'b00000001xxxxxxxx//00000001DDDDRRRR 34 | `define INSTRUCTION_MULS 16'b00000010xxxxxxxx//00000010ddddrrrr 35 | `define INSTRUCTION_MULSU 16'b000000110xxx0xxx//000000110ddd0rrr 36 | `define INSTRUCTION_FMUL 16'b000000110xxx1xxx//000000110ddd1rrr 37 | `define INSTRUCTION_FMULS 16'b000000111xxx0xxx//000000111dddurrr 38 | `define INSTRUCTION_FMULSU 16'b000000111xxx1xxx//000000111dddurrr 39 | `define INSTRUCTION_CPC_CP 16'b000x01xxxxxxxxxx//000i01rdddddrrrr 40 | `define INSTRUCTION_CPC 16'b000001xxxxxxxxxx//000001rdddddrrrr 41 | `define INSTRUCTION_CP 16'b000101xxxxxxxxxx//000101rdddddrrrr 42 | `define INSTRUCTION_SBC_SUB_ADD_ADC 16'b000x1xxxxxxxxxxx//000i1irdddddrrrr 43 | `define INSTRUCTION_SBC 16'b000010xxxxxxxxxx//000010rdddddrrrr 44 | `define INSTRUCTION_SUB 16'b000110xxxxxxxxxx//000110rdddddrrrr 45 | `define INSTRUCTION_ADD 16'b000011xxxxxxxxxx//000011rdddddrrrr 46 | `define INSTRUCTION_ADC 16'b000111xxxxxxxxxx//000111rdddddrrrr 47 | `define INSTRUCTION_CPSE 16'b000100xxxxxxxxxx//000100rdddddrrrr 48 | `define INST_AND_EOR_OR_MOV 16'b0010xxxxxxxxxxxx//0010iirdddddrrrr 49 | `define INSTRUCTION_AND 16'b001000xxxxxxxxxx//001000rdddddrrrr 50 | `define INSTRUCTION_EOR 16'b001001xxxxxxxxxx//001001rdddddrrrr 51 | `define INSTRUCTION_OR 16'b001010xxxxxxxxxx//001010rdddddrrrr 52 | `define INSTRUCTION_MOV 16'b001011xxxxxxxxxx//001011rdddddrrrr 53 | `define INSTRUCTION_CPI 16'b0011xxxxxxxxxxxx//0011kkkkddddkkkk 54 | `define INSTRUCTION_SUBI_SBCI 16'b010xxxxxxxxxxxxx//010ikkkkddddkkkk 55 | `define INSTRUCTION_SUBI 16'b0101xxxxxxxxxxxx//0101kkkkddddkkkk 56 | `define INSTRUCTION_SBCI 16'b0100xxxxxxxxxxxx//0100kkkkddddkkkk 57 | `define INSTRUCTION_ORI_ANDI 16'b011xxxxxxxxxxxxx//011ikkkkddddkkkk 58 | `define INSTRUCTION_ORI_SBR 16'b0110xxxxxxxxxxxx//0110kkkkddddkkkk 59 | `define INSTRUCTION_ANDI_CBR 16'b0111xxxxxxxxxxxx//0111kkkkddddkkkk 60 | 61 | `define INSTRUCTION_LDD_STD 16'b10x0xxxxxxxxxxxx//10k0kksdddddykkk 62 | `define INSTRUCTION_LDS_STS 16'b100100xxxxxx0000//100100sddddd0000 63 | `define INSTRUCTION_LD_ST_YZP 16'b100100xxxxxxx001//100100sdddddy001 64 | `define INSTRUCTION_LD_ST_YZN 16'b100100xxxxxxx010//100100sdddddy010 65 | `define INSTRUCTION_LPM_R 16'b1001000xxxxx0100//1001000ddddd01q0 66 | `define INSTRUCTION_LPM_R_P 16'b1001000xxxxx0101//1001000ddddd01q1 67 | `define INSTRUCTION_XCH 16'b1001001xxxxx0100//1001001ddddd0100 68 | `define INSTRUCTION_LAS 16'b1001001xxxxx0101//1001001ddddd0101 69 | `define INSTRUCTION_LAC 16'b1001001xxxxx0110//1001001ddddd0110 70 | `define INSTRUCTION_LAT 16'b1001001xxxxx0111//1001001ddddd0111 71 | `define INSTRUCTION_LD_ST_X 16'b100100xxxxxx1100//100100sddddd1100 72 | `define INSTRUCTION_LD_ST_XP 16'b100100xxxxxx1101//100100sddddd1101 73 | `define INSTRUCTION_LD_ST_XN 16'b100100xxxxxx1110//100100sddddd1110 74 | `define INSTRUCTION_POP_PUSH 16'b100100xxxxxx1111//100100sddddd1111 75 | `define INST_COM_NEG_SWAP_INC 16'b1001010xxxxx00xx//1001010ddddd00xx 76 | `define INSTRUCTION_COM 16'b1001010xxxxx0000//1001010ddddd0000 77 | `define INSTRUCTION_NEG 16'b1001010xxxxx0001//1001010ddddd0001 78 | `define INSTRUCTION_SWAP 16'b1001010xxxxx0010//1001010ddddd0010 79 | `define INSTRUCTION_INC 16'b1001010xxxxx0011//1001010ddddd0011 80 | `define INSTRUCTION_ASR 16'b1001010xxxxx0101//1001010ddddd0101 81 | `define INSTRUCTION_LSR 16'b1001010xxxxx0110//1001010ddddd0110 82 | `define INSTRUCTION_ROR 16'b1001010xxxxx0111//1001010ddddd0111 83 | `define INSTRUCTION_SEx_CLx 16'b10010100xxxx1000//10010100Bbbb1000 84 | `define INSTRUCTION_RET_RETI 16'b10010101000x1000//10010101000x1000 85 | `define INSTRUCTION_RET 16'b1001010100001000//1001010100001000 86 | `define INSTRUCTION_RETI 16'b1001010100011000//1001010100001000 87 | `define INSTRUCTION_SLEEP 16'b1001010110000000//1001010100001000 88 | `define INSTRUCTION_BREAK 16'b1001010110011000//1001010100011000 89 | `define INSTRUCTION_WDR 16'b1001010110101000//1001010100101000 90 | `define INSTRUCTION_LPM_ELPM 16'b10010101110x1000//10010101110q1000 91 | `define INSTRUCTION_SPM 16'b1001010111101000//1001010111101000 92 | `define INSTRUCTION_SPM_Z_P 16'b1001010111111000//1001010111111000 93 | `define INSTRUCTION_IJMP_ICALL 16'b1001010x00001001//1001010c000e1001 94 | `define INSTRUCTION_IJMP 16'b1001010000001001//1001010c000e1001 95 | `define INSTRUCTION_ICALL 16'b1001010100001001//1001010c000e1001 96 | `define INSTRUCTION_DEC 16'b1001010xxxxx1010//1001010ddddd1010 97 | `define INSTRUCTION_DES 16'b10010100xxxx1011//10010100kkkk1011 98 | `define INSTRUCTION_JMP_CALL 16'b1001010xxxxx11xx//1001010kkkkk11ck 99 | `define INSTRUCTION_JMP 16'b1001010xxxxx110x//1001010kkkkk110k 100 | `define INSTRUCTION_CALL 16'b1001010xxxxx111x//1001010kkkkk111k 101 | `define INSTRUCTION_ADIW_SBIW 16'b1001011xxxxxxxxx//10010110kkppkkkk 102 | `define INSTRUCTION_ADIW 16'b10010110xxxxxxxx//10010110kkppkkkk 103 | `define INSTRUCTION_SBIW 16'b10010111xxxxxxxx//10010111kkppkkkk 104 | `define INSTRUCTION_CBI_SBI 16'b100110x0xxxxxxxx//100110B0aaaaabbb 105 | `define INSTRUCTION_SBIC_SBIS 16'b100110x1xxxxxxxx//100110B1aaaaabbb 106 | `define INSTRUCTION_MUL 16'b100111xxxxxxxxxx//100111rdddddrrrr 107 | `define INSTRUCTION_IN_OUT 16'b1011xxxxxxxxxxxx//1011saadddddaaaa 108 | `define INSTRUCTION_RJMP_RCALL 16'b110xxxxxxxxxxxxx//110cxxxxxxxxxxxx 109 | `define INSTRUCTION_RJMP 16'b1100xxxxxxxxxxxx//1100xxxxxxxxxxxx 110 | `define INSTRUCTION_RCALL 16'b1101xxxxxxxxxxxx//1101xxxxxxxxxxxx 111 | `define INSTRUCTION_LDI 16'b1110xxxxxxxxxxxx//1110KKKKddddKKKK 112 | `define INSTRUCTION_COND_BRANCH 16'b11110xxxxxxxxxxx//11110Bxxxxxxxbbb 113 | `define INSTRUCTION_BLD_BST 16'b111110xxxxxx0xxx//111110sddddd0bbb 114 | `define INSTRUCTION_SBRC_SBRS 16'b111111xxxxxx0xxx//111111Bddddd0bbb 115 | -------------------------------------------------------------------------------- /xmega_core/mega_regs.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This IP is the 32 reg memory 1 in and 2 out selectable in 8 or 16 bit for the Atmel XMEGA CPU implementation. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | `timescale 1ns / 1ps 22 | 23 | module mega_regs ( 24 | input clk, 25 | input [4:0]rw_addr, 26 | input [15:0]rw_data, 27 | input rw_16bit, 28 | input write, 29 | input [4:0]rd_addr_d, 30 | output [15:0]rd_data_d, 31 | input rd_16bit_d, 32 | input read_d, 33 | input [4:0]rd_addr_r, 34 | output [15:0]rd_data_r, 35 | input rd_16bit_r, 36 | input read_r 37 | ); 38 | 39 | reg [7:0]REGL[0:15]; 40 | reg [7:0]REGH[0:15]; 41 | 42 | reg [4:0]k; 43 | 44 | initial 45 | begin 46 | for (k = 0; k < 16; k = k + 1) 47 | begin 48 | REGL[k] = 0; 49 | REGH[k] = 0; 50 | end 51 | end 52 | 53 | always @ (posedge clk) 54 | begin 55 | if(write) 56 | begin 57 | if(!rw_16bit & !rw_addr[0]) 58 | REGL[rw_addr[4:1]] <= rw_data[7:0]; 59 | else if(!rw_16bit & rw_addr[0]) 60 | REGH[rw_addr[4:1]] <= rw_data[7:0]; 61 | else 62 | begin 63 | REGL[rw_addr[4:1]] <= rw_data[7:0]; 64 | REGH[rw_addr[4:1]] <= rw_data[15:8]; 65 | end 66 | end 67 | end 68 | 69 | assign rd_data_d = (read_d) ? (rd_16bit_d) ? {REGH[rd_addr_d[4:1]], REGL[rd_addr_d[4:1]]} : (rd_addr_d[0]) ? REGH[rd_addr_d[4:1]] : REGL[rd_addr_d[4:1]] : 16'bz; 70 | assign rd_data_r = (read_r) ? (rd_16bit_r) ? {REGH[rd_addr_r[4:1]], REGL[rd_addr_r[4:1]]} : (rd_addr_r[0]) ? REGH[rd_addr_r[4:1]] : REGL[rd_addr_r[4:1]] : 16'bz; 71 | 72 | endmodule 73 | -------------------------------------------------------------------------------- /xmega_core/sim_uc.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This is the simulation file for Atmel XMEGA CPU implementation.. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | `timescale 1ns / 1ps 22 | 23 | `define BUS_ADDR_PGM_LEN 11 /* < in 16-bit instructions */ 24 | `define BUS_ADDR_DATA_LEN 8 /* < in bytes */ 25 | 26 | module sim_uc( 27 | //output reg [7:0]port_out, 28 | //input [7:0]port_in 29 | ); 30 | 31 | reg [7:0]port_out; 32 | wire [7:0]port_in = port_out; 33 | 34 | 35 | reg rst = 0; 36 | reg clk = 0; 37 | always #(1) clk <= ~clk; // clocking device 38 | 39 | //wire pgm_re; 40 | wire [`BUS_ADDR_PGM_LEN-1:0] pgm_addr; 41 | wire [15:0] pgm_data; 42 | wire data_re; 43 | wire data_we; 44 | wire [`BUS_ADDR_DATA_LEN-1:0] data_addr; 45 | wire [7:0]data_in; 46 | wire [7:0]data_out; 47 | 48 | wire io_re; 49 | wire io_we; 50 | wire [5:0] io_addr; 51 | wire [7:0] io_out; 52 | wire [7:0] io_in; 53 | 54 | 55 | rom #( 56 | .bus_addr_pgm_width(`BUS_ADDR_PGM_LEN), 57 | .rom_path("core1ROMsym.mem") 58 | )rom( 59 | .pmem_a(pgm_addr), 60 | .pmem_d(pgm_data) 61 | 62 | ); 63 | 64 | ram #( 65 | .bus_addr_data_width(`BUS_ADDR_DATA_LEN), 66 | .ram_path("NONE") 67 | )ram( 68 | .clk(clk), 69 | .dmem_re(data_re), 70 | .dmem_we(data_we), 71 | .dmem_a(data_addr), 72 | .dmem_r(data_in), 73 | .dmem_w(data_out) 74 | ); 75 | 76 | reg [7:0]out_led; 77 | wire io_select_0 = (io_addr == 0 & (io_we | io_re)) ? 1'b1:1'b0; 78 | 79 | always @ (*) 80 | begin 81 | if(io_select_0 & io_we) 82 | port_out <= io_out; 83 | end 84 | 85 | assign io_in = (io_re & io_select_0) ? port_in : 8'bz; // 86 | 87 | initial begin 88 | rst = 0; 89 | #1; 90 | rst = 1; 91 | #1; 92 | rst = 0; 93 | 94 | port_out = 8'haa; 95 | #14000; 96 | $finish; 97 | end 98 | 99 | mega_core #( 100 | .bus_addr_pgm_width(`BUS_ADDR_PGM_LEN), 101 | .bus_addr_data_width(`BUS_ADDR_DATA_LEN) 102 | )core( 103 | .rst(rst), 104 | .clk(clk), 105 | 106 | //.pgm_re(1'b1), 107 | .pgm_addr(pgm_addr), 108 | .pgm_data(pgm_data), 109 | 110 | .data_re(data_re), 111 | .data_we(data_we), 112 | .data_addr(data_addr), 113 | .data_in(data_in), 114 | .data_out(data_out), 115 | 116 | .io_re(io_re), 117 | .io_we(io_we), 118 | .io_addr(io_addr), 119 | .io_out(io_out), 120 | .io_in(io_in) 121 | ); 122 | 123 | endmodule 124 | 125 | -------------------------------------------------------------------------------- /xmega_core/top_uc.v: -------------------------------------------------------------------------------- 1 | /* 2 | * This IP is the top of Atmel XMEGA CPU implementation. 3 | * 4 | * Copyright (C) 2017 Iulian Gheorghiu 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either version 2 9 | * of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | `timescale 1ns / 1ps 22 | 23 | `define BUS_ADDR_PGM_LEN 11 /* < in 16-bit instructions */ 24 | `define BUS_ADDR_DATA_LEN 8 /* < in bytes */ 25 | 26 | module top_uc( 27 | input rst, 28 | input clk, 29 | output reg [2:0]RGB0, 30 | output reg [2:0]RGB1, 31 | output reg [2:0]RGB2, 32 | output reg [2:0]RGB3, 33 | output reg [3:0]LED, 34 | input [3:0]SW, 35 | input [3:0]BTN 36 | 37 | ); 38 | 39 | 40 | //wire pgm_re; 41 | wire [`BUS_ADDR_PGM_LEN-1:0] pgm_addr; 42 | wire [15:0] pgm_data; 43 | wire data_re; 44 | wire data_we; 45 | wire [`BUS_ADDR_DATA_LEN-1:0] data_addr; 46 | wire [7:0]data_in; 47 | wire [7:0]data_out; 48 | 49 | wire io_re; 50 | wire io_we; 51 | wire [5:0] io_addr; 52 | wire [7:0] io_out; 53 | wire [7:0] io_in; 54 | 55 | 56 | wire core_clk; 57 | wire CLKOUT1; 58 | wire CLKOUT2; 59 | wire CLKOUT3; 60 | wire CLKOUT4; 61 | wire CLKOUT5; 62 | wire CLKFB; 63 | wire LOCKED; 64 | 65 | PLLE2_BASE #( 66 | .BANDWIDTH("OPTIMIZED"), // OPTIMIZED, HIGH, LOW 67 | .CLKFBOUT_MULT(10), // Multiply value for all CLKOUT, (2-64) 68 | .CLKFBOUT_PHASE(0.0), // Phase offset in degrees of CLKFB, (-360.000-360.000). 69 | .CLKIN1_PERIOD(10.0), // Input clock period in ns to ps resolution (i.e. 33.333 is 30 MHz). 70 | // CLKOUT0_DIVIDE - CLKOUT5_DIVIDE: Divide amount for each CLKOUT (1-128) 71 | .CLKOUT0_DIVIDE(9), 72 | .CLKOUT1_DIVIDE(1), 73 | .CLKOUT2_DIVIDE(1), 74 | .CLKOUT3_DIVIDE(1), 75 | .CLKOUT4_DIVIDE(1), 76 | .CLKOUT5_DIVIDE(1), 77 | // CLKOUT0_DUTY_CYCLE - CLKOUT5_DUTY_CYCLE: Duty cycle for each CLKOUT (0.001-0.999). 78 | .CLKOUT0_DUTY_CYCLE(0.5), 79 | .CLKOUT1_DUTY_CYCLE(0.5), 80 | .CLKOUT2_DUTY_CYCLE(0.5), 81 | .CLKOUT3_DUTY_CYCLE(0.5), 82 | .CLKOUT4_DUTY_CYCLE(0.5), 83 | .CLKOUT5_DUTY_CYCLE(0.5), 84 | // CLKOUT0_PHASE - CLKOUT5_PHASE: Phase offset for each CLKOUT (-360.000-360.000). 85 | .CLKOUT0_PHASE(0.0), 86 | .CLKOUT1_PHASE(0.0), 87 | .CLKOUT2_PHASE(0.0), 88 | .CLKOUT3_PHASE(0.0), 89 | .CLKOUT4_PHASE(0.0), 90 | .CLKOUT5_PHASE(0.0), 91 | .DIVCLK_DIVIDE(1), // Master division value, (1-56) 92 | .REF_JITTER1(0.0), // Reference input jitter in UI, (0.000-0.999). 93 | .STARTUP_WAIT("FALSE") // Delay DONE until PLL Locks, ("TRUE"/"FALSE") 94 | ) 95 | PLLE2_BASE_inst ( 96 | // Clock Outputs: 1-bit (each) output: User configurable clock outputs 97 | .CLKOUT0(core_clk), // 1-bit output: CLKOUT0 98 | .CLKOUT1(CLKOUT1), // 1-bit output: CLKOUT1 99 | .CLKOUT2(CLKOUT2), // 1-bit output: CLKOUT2 100 | .CLKOUT3(CLKOUT3), // 1-bit output: CLKOUT3 101 | .CLKOUT4(CLKOUT4), // 1-bit output: CLKOUT4 102 | .CLKOUT5(CLKOUT5), // 1-bit output: CLKOUT5 103 | // Feedback Clocks: 1-bit (each) output: Clock feedback ports 104 | .CLKFBOUT(CLKFB), // 1-bit output: Feedback clock 105 | .LOCKED(LOCKED), // 1-bit output: LOCK 106 | .CLKIN1(clk), // 1-bit input: Input clock 107 | // Control Ports: 1-bit (each) input: PLL control ports 108 | .PWRDWN(1'b0), // 1-bit input: Power-down 109 | .RST(~rst), // 1-bit input: Reset 110 | // Feedback Clocks: 1-bit (each) input: Clock feedback ports 111 | .CLKFBIN(CLKFB) // 1-bit input: Feedback clock 112 | ); 113 | 114 | 115 | rom #( 116 | .bus_addr_pgm_width(`BUS_ADDR_PGM_LEN), 117 | .rom_path("core1ROM.mem") 118 | )rom( 119 | .pmem_a(pgm_addr), 120 | .pmem_d(pgm_data) 121 | 122 | ); 123 | 124 | ram #( 125 | .bus_addr_data_width(`BUS_ADDR_DATA_LEN), 126 | .ram_path("NONE") 127 | )ram( 128 | .clk(core_clk), 129 | .dmem_re(data_re), 130 | .dmem_we(data_we), 131 | .dmem_a(data_addr), 132 | .dmem_r(data_in), 133 | .dmem_w(data_out) 134 | ); 135 | 136 | reg [7:0]out_led; 137 | wire io_select_0 = (io_addr == 0 & (io_we | io_re)) ? 1'b1:1'b0; 138 | 139 | always @ (posedge core_clk) 140 | begin 141 | if(io_select_0 & io_we) 142 | {LED, RGB0[1], RGB1[1], RGB2[1], RGB3[1]} <= io_out; 143 | end 144 | 145 | assign io_in = (io_re & io_select_0) ? {BTN, SW} : 8'bz; // 146 | 147 | reg RST = 0; 148 | 149 | initial begin 150 | RST = 0; 151 | #1; 152 | RST = 1; 153 | #1000; 154 | $finish; 155 | end 156 | 157 | mega_core #( 158 | .bus_addr_pgm_width(`BUS_ADDR_PGM_LEN), 159 | .bus_addr_data_width(`BUS_ADDR_DATA_LEN) 160 | )core( 161 | .rst(~rst), 162 | .clk(core_clk), 163 | 164 | //.pgm_re(1'b1), 165 | .pgm_addr(pgm_addr), 166 | .pgm_data(pgm_data), 167 | 168 | .data_re(data_re), 169 | .data_we(data_we), 170 | .data_addr(data_addr), 171 | .data_in(data_in), 172 | .data_out(data_out), 173 | 174 | .io_re(io_re), 175 | .io_we(io_we), 176 | .io_addr(io_addr), 177 | .io_out(io_out), 178 | .io_in(io_in) 179 | ); 180 | 181 | endmodule 182 | --------------------------------------------------------------------------------