├── .gitignore ├── netlist ├── Setup.hs ├── netlist.cabal ├── LICENSE └── Language │ └── Netlist │ ├── Examples.hs │ ├── Util.hs │ ├── Inline.hs │ └── AST.hs ├── verilog ├── Setup.hs ├── examples │ ├── up_counter.v │ ├── hello_pli.v │ ├── encoder_4to2_gates.v │ ├── t_gate_switch.v │ ├── nand_switch.v │ ├── d_latch_gates.v │ ├── xor_switch.v │ ├── latch_udp.v │ ├── decoder_2to4_gates.v │ ├── srff_udp.v │ ├── xor2_input.v │ ├── README │ ├── mux_21_udp.v │ ├── misc1.v │ ├── half_adder_gates.v │ ├── or2_input.v │ ├── dff_udp.v │ ├── parity_using_bitwise.v │ ├── mux_2to1_gates.v │ ├── not_switch.v │ ├── mux_4to1_gates.v │ ├── full_adder_gates.v │ ├── d_latch_switch.v │ ├── jkff_udp.v │ ├── full_subtracter_gates.v │ ├── decoder_using_assign.v │ ├── lfsr_updown_tb.v │ ├── mux21_switch.v │ ├── parity_using_assign.v │ ├── rom_using_file.v │ ├── mux_using_assign.v │ ├── tff_sync_reset.v │ ├── parity_using_function2.v │ ├── dff_sync_reset.v │ ├── dlatch_reset.v │ ├── tff_async_reset.v │ ├── dff_async_reset.v │ ├── parity_using_function.v │ ├── mux_using_case.v │ ├── mux_using_if.v │ ├── lfsr_updown.v │ ├── one_hot_cnt.v │ ├── up_down_counter.v │ ├── up_counter_load.v │ ├── rom_using_case.v │ ├── clk_div.v │ ├── lfsr.v │ ├── gray_counter.v │ ├── arbiter_tb.v │ ├── GrayCounter.v │ ├── encoder_using_case.v │ ├── decoder_using_case.v │ ├── rom.v │ ├── pri_encoder_using_assign.v │ ├── divide_by_3.v │ ├── serial_crc.v │ ├── clk_div_45.v │ ├── ram_sp_ar_aw.v │ ├── parallel_crc.v │ ├── ram_sp_sr_sw.v │ ├── ram_sp_ar_sw.v │ ├── cam.v │ ├── encoder_using_if.v │ ├── pri_encoder_using_if.v │ ├── ram_dp_sr_sw.v │ ├── ram_dp_ar_aw.v │ ├── syn_fifo.v │ ├── arbiter.v │ ├── uart.v │ └── aFifo.v ├── Language │ ├── Verilog.hs │ └── Verilog │ │ ├── Syntax.hs │ │ ├── Syntax │ │ ├── Ident.hs │ │ └── Expression.hs │ │ ├── ParserTest.hs │ │ └── PrettyPrint.hs ├── verilog.cabal └── LICENSE ├── netlist-to-verilog ├── Setup.hs ├── netlist-to-verilog.cabal ├── LICENSE └── Language │ └── Netlist │ └── GenVerilog.hs ├── netlist-to-vhdl ├── Setup.hs ├── netlist-to-vhdl.cabal ├── LICENSE └── Language │ └── Netlist │ └── GenVHDL.hs ├── Makefile └── README.org /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | package.conf.d/ 3 | -------------------------------------------------------------------------------- /netlist/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /verilog/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /netlist-to-verilog/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /netlist-to-vhdl/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /verilog/examples/up_counter.v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pheaver/netlist-verilog/HEAD/verilog/examples/up_counter.v -------------------------------------------------------------------------------- /verilog/examples/hello_pli.v: -------------------------------------------------------------------------------- 1 | module hello_pli (); 2 | 3 | initial begin 4 | $hello; 5 | #10 $finish; 6 | end 7 | 8 | endmodule 9 | -------------------------------------------------------------------------------- /verilog/examples/encoder_4to2_gates.v: -------------------------------------------------------------------------------- 1 | module encoder_4to2_gates (i0,i1,i2,i3,y); 2 | input i0,i1,i2,i3; 3 | output [1:0] y; 4 | 5 | or o1 (y[0],i1,i3); 6 | or o2 (y[1],i2,i3); 7 | 8 | endmodule 9 | -------------------------------------------------------------------------------- /verilog/examples/t_gate_switch.v: -------------------------------------------------------------------------------- 1 | module t_gate_switch (L,R,nC,C); 2 | inout L; 3 | inout R; 4 | input nC; 5 | input C; 6 | 7 | //Syntax: keyword unique_name (drain. source, gate); 8 | pmos p1 (L,R,nC); 9 | nmos p2 (L,R,C); 10 | 11 | endmodule 12 | -------------------------------------------------------------------------------- /verilog/examples/nand_switch.v: -------------------------------------------------------------------------------- 1 | module nand_switch(a,b,out); 2 | input a,b; 3 | output out; 4 | 5 | supply0 vss; 6 | supply1 vdd; 7 | wire net1; 8 | 9 | pmos p1 (vdd,out,a); 10 | pmos p2 (vdd,out,b); 11 | nmos n1 (vss,net1,a); 12 | nmos n2 (net1,out,b); 13 | 14 | endmodule -------------------------------------------------------------------------------- /verilog/examples/d_latch_gates.v: -------------------------------------------------------------------------------- 1 | module d_latch_gates(d,clk,q,q_bar); 2 | input d,clk; 3 | output q, q_bar; 4 | 5 | wire n1,n2,n3; 6 | 7 | not (n1,d); 8 | 9 | nand (n2,d,clk); 10 | nand (n3,n1,clk); 11 | 12 | nand (q,q_bar,n2); 13 | nand (q_bar,q,n3); 14 | 15 | endmodule 16 | -------------------------------------------------------------------------------- /verilog/examples/xor_switch.v: -------------------------------------------------------------------------------- 1 | module nor2_switch (a,b,y); 2 | input a, b; 3 | output y; 4 | 5 | supply1 power; 6 | supply0 ground; 7 | 8 | wire connect; 9 | 10 | nmos (y,ground,a); 11 | nmos (y,ground,b); 12 | pmos (y,connect,b); 13 | pmos (power,connect,a); 14 | 15 | endmodule 16 | -------------------------------------------------------------------------------- /verilog/examples/latch_udp.v: -------------------------------------------------------------------------------- 1 | primitive latch_udp(q, clock, data) ; 2 | output q; reg q ; 3 | input clock, data; 4 | table 5 | // clock data q q+ 6 | 0 1 : ? : 1 ; 7 | 0 0 : ? : 0 ; 8 | 1 ? : ? : - ; // - = no change 9 | endtable 10 | endprimitive 11 | -------------------------------------------------------------------------------- /verilog/examples/decoder_2to4_gates.v: -------------------------------------------------------------------------------- 1 | module decoder_2to4_gates (x,y,f0,f1,f2,f3); 2 | input x,y; 3 | output f0,f1,f2,f3; 4 | 5 | wire n1,n2; 6 | 7 | not i1 (n1,x); 8 | not i2 (n2,y); 9 | and a1 (f0,n1,n2); 10 | and a2 (f1,n1,y); 11 | and a3 (f2,x,n2); 12 | and a4 (f3,x,y); 13 | 14 | endmodule 15 | -------------------------------------------------------------------------------- /verilog/examples/srff_udp.v: -------------------------------------------------------------------------------- 1 | primitive srff_udp (q,s,r); 2 | output q; 3 | input s,r; 4 | 5 | reg q; 6 | 7 | initial q = 1'b1; 8 | 9 | table 10 | // s r q q+ 11 | 1 0 : ? : 1 ; 12 | f 0 : 1 : - ; 13 | 0 r : ? : 0 ; 14 | 0 f : 0 : - ; 15 | 1 1 : ? : 0 ; 16 | endtable 17 | 18 | endprimitive 19 | -------------------------------------------------------------------------------- /verilog/examples/xor2_input.v: -------------------------------------------------------------------------------- 1 | primitive xor2_input (c,a,b); 2 | output c; 3 | input a,b; 4 | table 5 | 0 0 : 0; 6 | 0 1 : 1; 7 | 1 0 : 1; 8 | 1 1 : 0; 9 | x 1 : x; 10 | 1 x : x; 11 | x 0 : x; 12 | 0 x : x; 13 | x x : x; 14 | endtable 15 | endprimitive 16 | -------------------------------------------------------------------------------- /verilog/examples/README: -------------------------------------------------------------------------------- 1 | This directory contains some example Verilog files that are used to test the 2 | parser and pretty-printer. They were downloaded from 3 | http://www.asic-world.com/examples/verilog/index.html 4 | 5 | Copyright (c) 1998-2010 Deepak Kumar Tala 6 | All rights reserved 7 | deepak@asic-world.com 8 | -------------------------------------------------------------------------------- /verilog/examples/mux_21_udp.v: -------------------------------------------------------------------------------- 1 | primitive mux_21_udp(out, sel, i0, i1); 2 | output out; 3 | input sel, i0, i1; 4 | table 5 | // sel i0 i1 out 6 | 0 0 ? : 0 ; // 1 7 | 0 1 ? : 1 ; // 2 8 | 1 ? 0 : 0 ; // 3 9 | 1 ? 1 : 1 ; // 4 10 | ? 0 0 : 0 ; // 5 11 | ? 1 1 : 1 ; // 6 12 | endtable 13 | endprimitive 14 | -------------------------------------------------------------------------------- /verilog/examples/misc1.v: -------------------------------------------------------------------------------- 1 | module misc1 (a,b,c,d,y); 2 | input a, b,c,d; 3 | output y; 4 | 5 | wire net1,net2,net3; 6 | 7 | supply1 vdd; 8 | supply0 vss; 9 | 10 | // y = !((a+b+c).d) 11 | 12 | pmos p1 (vdd,net1,a); 13 | pmos p2 (net1,net2,b); 14 | pmos p3 (net2,y,c); 15 | pmos p4 (vdd,y,d); 16 | 17 | nmos n1 (vss,net3,a); 18 | nmos n2 (vss,net3,b); 19 | nmos n3 (vss,net3,c); 20 | nmos n4 (net3,y,d); 21 | 22 | endmodule 23 | -------------------------------------------------------------------------------- /verilog/examples/half_adder_gates.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : half_adder_gates 3 | // File Name : half_adder_gates.v 4 | // Function : CCITT Serial CRC 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module half_adder_gates(x,y,sum,carry); 8 | input x,y; 9 | output sum,carry; 10 | 11 | and U_carry (carry,x,y); 12 | xor U_sum (sum,x,y); 13 | 14 | endmodule 15 | -------------------------------------------------------------------------------- /verilog/examples/or2_input.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : or2_input 3 | // File Name : or2_input.v 4 | // Function : 2 Input OR Gate Using UDP 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | primitive or2_input (c,a,b); 8 | output c; 9 | input a,b; 10 | table 11 | //a b : c 12 | 1 ? : 1; 13 | ? 1 : 1; 14 | 0 0 : 0; 15 | 0 x : x; 16 | x 0 : x; 17 | endtable 18 | endprimitive 19 | -------------------------------------------------------------------------------- /verilog/examples/dff_udp.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : dff_udp 3 | // File Name : dff_udp.v 4 | // Function : D Flip Flop 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | primitive dff_udp (q,clk,d); 8 | input clk,d; 9 | output q; 10 | reg q; 11 | table 12 | // clk d : q : q+ 13 | r 0 : ? : 0 ; 14 | r 1 : ? : 1 ; 15 | f ? : ? : - ; 16 | ? * : ? : - ; 17 | endtable 18 | endprimitive 19 | -------------------------------------------------------------------------------- /verilog/examples/parity_using_bitwise.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : parity_using_bitwise 3 | // File Name : parity_using_bitwise.v 4 | // Function : Parity using bitwise xor 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module parity_using_bitwise ( 8 | data_in , // 8 bit data in 9 | parity_out // 1 bit parity out 10 | ); 11 | output parity_out ; 12 | input [7:0] data_in ; 13 | 14 | assign parity_out = ^data_in; 15 | 16 | endmodule 17 | -------------------------------------------------------------------------------- /verilog/examples/mux_2to1_gates.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : mux_2to1_gates 3 | // File Name : mux_2to1_gates.v 4 | // Function : 2:1 Mux using Gate Primitives 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module mux_2to1_gates(a,b,sel,y); 8 | input a,b,sel; 9 | output y; 10 | 11 | wire sel,a_sel,b_sel; 12 | 13 | not U_inv (inv_sel,sel); 14 | and U_anda (asel,a,inv_sel), 15 | U_andb (bsel,b,sel); 16 | or U_or (y,asel,bsel); 17 | 18 | endmodule 19 | -------------------------------------------------------------------------------- /verilog/examples/not_switch.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : not_switch 3 | // File Name : not_switch.v 4 | // Function : NOT Gate Using Switch Primitives 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module not_switch (out, in); 8 | output out; 9 | input in; 10 | 11 | supply1 power; 12 | supply0 ground; 13 | 14 | pmos (out, power, in); 15 | nmos (out, ground, in); 16 | 17 | endmodule 18 | -------------------------------------------------------------------------------- /verilog/examples/mux_4to1_gates.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : mux_4to1_gates 3 | // File Name : mux_4to1_gates.v 4 | // Function : 4:1 Mux Using Gates 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module mux_4to1_gates(a,b,c,d,sel,y); 8 | input a,b,c,d; 9 | input [1:0] sel; 10 | output y; 11 | 12 | wire mux_1,mux_2; 13 | 14 | mux_2to1_gates U_mux1 (a,b,sel[0],mux_1), 15 | U_mux2 (c,d,sel[0],mux_2), 16 | U_mux3 (mux_1,mux_2,sel[1],y); 17 | 18 | endmodule 19 | -------------------------------------------------------------------------------- /verilog/examples/full_adder_gates.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : full_adder_gates 3 | // File Name : full_adder_gates.v 4 | // Function : Full Adder Using Gates 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module full_adder_gates(x,y,z,sum,carry); 8 | input x,y,z; 9 | output sum,carry; 10 | wire and1,and2,and3,sum1; 11 | 12 | and U_and1 (and1,x,y), 13 | U_and2 (and2,x,z), 14 | U_and3 (and3,y,z); 15 | or U_or (carry,and1,and2,and3); 16 | xor U_sum (sum,x,y,z); 17 | 18 | endmodule 19 | -------------------------------------------------------------------------------- /verilog/examples/d_latch_switch.v: -------------------------------------------------------------------------------- 1 | module not_switch (out, in); 2 | output out; 3 | input in; 4 | 5 | supply1 power; 6 | supply0 ground; 7 | 8 | pmos (out, power, in); 9 | nmos (out, ground, in); 10 | 11 | endmodule 12 | 13 | module d_latch_switch(clk,d,q); 14 | input clk,d; 15 | output q; 16 | 17 | wire clkn, net1, qn; 18 | 19 | not_switch i1 (clkn,clk); 20 | 21 | pmos p1 (d,q,clkn); 22 | nmos n1 (d,q,clk); 23 | 24 | pmos p2 (q,net1,clk); 25 | nmos n2 (q,net1,clkn); 26 | 27 | not_switch i2 (qn,q); 28 | not_switch i3 (net1,qn); 29 | 30 | endmodule 31 | -------------------------------------------------------------------------------- /verilog/examples/jkff_udp.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : jkff_udp 3 | // File Name : jkff_udp.v 4 | // Function : JK Flip Flop Using UDP 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | primitive jkff_udp (q,clk,j,k); 8 | input clk,j,k; 9 | output q; 10 | reg q; 11 | table 12 | // clk j k : q : q+ 13 | r 0 0 : ? : - ; 14 | r 0 1 : ? : 0 ; 15 | r 1 0 : ? : 1 ; 16 | r 1 1 : 0 : 1 ; 17 | r 1 1 : 1 : 0 ; 18 | f ? ? : ? : - ; 19 | ? * ? : ? : - ; 20 | ? ? * : ? : - ; 21 | endtable 22 | endprimitive 23 | -------------------------------------------------------------------------------- /verilog/Language/Verilog.hs: -------------------------------------------------------------------------------- 1 | -- ----------------------------------------------------------------------------- 2 | -- Copyright (c) 2010 Signali Corp. 3 | -- ----------------------------------------------------------------------------- 4 | 5 | module Language.Verilog ( module Language.Verilog.Syntax 6 | , module Language.Verilog.Parser 7 | , module Language.Verilog.PrettyPrint 8 | ) where 9 | 10 | import Language.Verilog.Syntax 11 | import Language.Verilog.Parser 12 | import Language.Verilog.PrettyPrint 13 | 14 | -- ----------------------------------------------------------------------------- 15 | -------------------------------------------------------------------------------- /verilog/examples/full_subtracter_gates.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : full_subtracter_gates 3 | // File Name : full_subtracter_gates.v 4 | // Function : Full Subtracter Using Gates 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module full_subtracter_gates(x,y,z,difference,borrow); 8 | input x,y,z; 9 | output difference,borrow; 10 | 11 | wire inv_x,borrow1,borrow2,borrow3; 12 | 13 | not (inv_x,x); 14 | and U_borrow1 (borrow1,inv_x,y), 15 | U_borrow2 (borrow2,inv_x,z), 16 | U_borrow3 (borrow3,y,z); 17 | 18 | xor U_diff (difference,borrow1,borrow2,borrows); 19 | 20 | endmodule 21 | -------------------------------------------------------------------------------- /verilog/examples/decoder_using_assign.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : decoder_using_assign 3 | // File Name : decoder_using_assign.v 4 | // Function : decoder using assign 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module decoder_using_assign ( 8 | binary_in , // 4 bit binary input 9 | decoder_out , // 16-bit out 10 | enable // Enable for the decoder 11 | ); 12 | input [3:0] binary_in ; 13 | input enable ; 14 | output [15:0] decoder_out ; 15 | 16 | wire [15:0] decoder_out ; 17 | 18 | assign decoder_out = (enable) ? (1 << binary_in) : 16'b0 ; 19 | 20 | endmodule 21 | -------------------------------------------------------------------------------- /verilog/examples/lfsr_updown_tb.v: -------------------------------------------------------------------------------- 1 | module tb(); 2 | reg clk; 3 | reg reset; 4 | reg enable; 5 | reg up_down; 6 | 7 | wire [`WIDTH-1 : 0] count; 8 | wire overflow; 9 | 10 | initial begin 11 | $monitor("rst %b en %b updown %b cnt %b overflow %b", 12 | reset,enable,up_down,count, overflow); 13 | clk = 0; 14 | reset = 1; 15 | enable = 0; 16 | up_down = 0; 17 | #10 reset = 0; 18 | #1 enable = 1; 19 | #20 up_down = 1; 20 | #30 $finish; 21 | end 22 | 23 | always #1 clk = ~clk; 24 | 25 | lfsr_updown U( 26 | .clk ( clk ), 27 | .reset ( reset ), 28 | .enable ( enable ), 29 | .up_down ( up_down ), 30 | .count ( count ), 31 | .overflow ( overflow ) 32 | ); 33 | 34 | endmodule 35 | -------------------------------------------------------------------------------- /verilog/examples/mux21_switch.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : mux21_switch 3 | // File Name : mux21_switch.v 4 | // Function : 2:1 Mux using Switch Primitives 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module mux21_switch (out, ctrl, in1, in2); 8 | 9 | output out; 10 | input ctrl, in1, in2; 11 | wire w; 12 | 13 | supply1 power; 14 | supply0 ground; 15 | 16 | pmos N1 (w, power, ctrl); 17 | nmos N2 (w, ground, ctrl); 18 | 19 | cmos C1 (out, in1, w, ctrl); 20 | cmos C2 (out, in2, ctrl, w); 21 | 22 | endmodule 23 | -------------------------------------------------------------------------------- /verilog/examples/parity_using_assign.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : parity_using_assign 3 | // File Name : parity_using_assign.v 4 | // Function : Parity using assign 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module parity_using_assign ( 8 | data_in , // 8 bit data in 9 | parity_out // 1 bit parity out 10 | ); 11 | output parity_out ; 12 | input [7:0] data_in ; 13 | 14 | wire parity_out ; 15 | 16 | assign parity_out = (data_in[0] ^ data_in[1]) ^ 17 | (data_in[2] ^ data_in[3]) ^ 18 | (data_in[4] ^ data_in[5]) ^ 19 | (data_in[6] ^ data_in[7]); 20 | 21 | endmodule 22 | -------------------------------------------------------------------------------- /verilog/examples/rom_using_file.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : rom_using_file 3 | // File Name : rom_using_file.v 4 | // Function : ROM using readmemh 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module rom_using_file ( 8 | address , // Address input 9 | data , // Data output 10 | read_en , // Read Enable 11 | ce // Chip Enable 12 | ); 13 | input [7:0] address; 14 | output [7:0] data; 15 | input read_en; 16 | input ce; 17 | 18 | reg [7:0] mem [0:255] ; 19 | 20 | assign data = (ce && read_en) ? mem[address] : 8'b0; 21 | 22 | initial begin 23 | $readmemb("memory.list", mem); // memory_list is memory file 24 | end 25 | 26 | endmodule 27 | -------------------------------------------------------------------------------- /verilog/Language/Verilog/Syntax.hs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | -- | 3 | -- Module : Language.Verilog.Syntax 4 | -- Copyright : (c) Signali Corp. 2010 5 | -- License : All rights reserved 6 | -- 7 | -- Maintainer : pweaver@signalicorp.com 8 | -- Stability : experimental 9 | -- Portability : ghc 10 | -- 11 | -- Verilog syntax: the abstract syntax tree (AST) and related modules. 12 | -------------------------------------------------------------------------------- 13 | 14 | module Language.Verilog.Syntax 15 | ( 16 | -- * Abstract syntax tree 17 | module Language.Verilog.Syntax.AST, 18 | ) where 19 | 20 | import Language.Verilog.Syntax.AST 21 | 22 | -------------------------------------------------------------------------------- 23 | -------------------------------------------------------------------------------- /verilog/examples/mux_using_assign.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : mux_using_assign 3 | // File Name : mux_using_assign.v 4 | // Function : 2:1 Mux using Assign 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module mux_using_assign( 8 | din_0 , // Mux first input 9 | din_1 , // Mux Second input 10 | sel , // Select input 11 | mux_out // Mux output 12 | ); 13 | //-----------Input Ports--------------- 14 | input din_0, din_1, sel ; 15 | //-----------Output Ports--------------- 16 | output mux_out; 17 | //------------Internal Variables-------- 18 | wire mux_out; 19 | //-------------Code Start----------------- 20 | assign mux_out = (sel) ? din_1 : din_0; 21 | 22 | endmodule //End Of Module mux 23 | -------------------------------------------------------------------------------- /verilog/examples/tff_sync_reset.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : tff_sync_reset 3 | // File Name : tff_sync_reset.v 4 | // Function : T flip-flop sync reset 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module tff_sync_reset ( 8 | data , // Data Input 9 | clk , // Clock Input 10 | reset , // Reset input 11 | q // Q output 12 | ); 13 | //-----------Input Ports--------------- 14 | input data, clk, reset ; 15 | //-----------Output Ports--------------- 16 | output q; 17 | //------------Internal Variables-------- 18 | reg q; 19 | //-------------Code Starts Here--------- 20 | always @ ( posedge clk) 21 | if (~reset) begin 22 | q <= 1'b0; 23 | end else if (data) begin 24 | q <= !q; 25 | end 26 | 27 | endmodule //End Of Module tff_async_reset 28 | -------------------------------------------------------------------------------- /verilog/examples/parity_using_function2.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : parity_using_function2 3 | // File Name : parity_using_function2.v 4 | // Function : Parity using function 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module parity_using_function2 ( 8 | data_in , // 8 bit data in 9 | parity_out // 1 bit parity out 10 | ); 11 | output parity_out ; 12 | input [7:0] data_in ; 13 | 14 | wire parity_out ; 15 | function parity; 16 | input [31:0] data; 17 | integer i; 18 | begin 19 | parity = 0; 20 | for (i = 0; i < 32; i = i + 1) begin 21 | parity = parity ^ data[i]; 22 | end 23 | end 24 | endfunction 25 | 26 | always @ (data_in) 27 | begin 28 | parity_out = parity(data_in); 29 | end 30 | 31 | endmodule 32 | -------------------------------------------------------------------------------- /verilog/examples/dff_sync_reset.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : dff_sync_reset 3 | // File Name : dff_sync_reset.v 4 | // Function : D flip-flop sync reset 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module dff_sync_reset ( 8 | data , // Data Input 9 | clk , // Clock Input 10 | reset , // Reset input 11 | q // Q output 12 | ); 13 | //-----------Input Ports--------------- 14 | input data, clk, reset ; 15 | 16 | //-----------Output Ports--------------- 17 | output q; 18 | 19 | //------------Internal Variables-------- 20 | reg q; 21 | 22 | //-------------Code Starts Here--------- 23 | always @ ( posedge clk) 24 | if (~reset) begin 25 | q <= 1'b0; 26 | end else begin 27 | q <= data; 28 | end 29 | 30 | endmodule //End Of Module dff_sync_reset 31 | -------------------------------------------------------------------------------- /verilog/examples/dlatch_reset.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : dlatch_reset 3 | // File Name : dlatch_reset.v 4 | // Function : DLATCH async reset 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module dlatch_reset ( 8 | data , // Data Input 9 | en , // LatchInput 10 | reset , // Reset input 11 | q // Q output 12 | ); 13 | //-----------Input Ports--------------- 14 | input data, en, reset ; 15 | 16 | //-----------Output Ports--------------- 17 | output q; 18 | 19 | //------------Internal Variables-------- 20 | reg q; 21 | 22 | //-------------Code Starts Here--------- 23 | always @ ( en or reset or data) 24 | if (~reset) begin 25 | q <= 1'b0; 26 | end else if (en) begin 27 | q <= data; 28 | end 29 | 30 | endmodule //End Of Module dlatch_reset 31 | -------------------------------------------------------------------------------- /verilog/examples/tff_async_reset.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : tff_async_reset 3 | // File Name : tff_async_reset.v 4 | // Function : T flip-flop async reset 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module tff_async_reset ( 8 | data , // Data Input 9 | clk , // Clock Input 10 | reset , // Reset input 11 | q // Q output 12 | ); 13 | //-----------Input Ports--------------- 14 | input data, clk, reset ; 15 | //-----------Output Ports--------------- 16 | output q; 17 | //------------Internal Variables-------- 18 | reg q; 19 | //-------------Code Starts Here--------- 20 | always @ ( posedge clk or negedge reset) 21 | if (~reset) begin 22 | q <= 1'b0; 23 | end else if (data) begin 24 | q <= !q; 25 | end 26 | 27 | endmodule //End Of Module tff_async_reset 28 | -------------------------------------------------------------------------------- /verilog/examples/dff_async_reset.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : dff_async_reset 3 | // File Name : dff_async_reset.v 4 | // Function : D flip-flop async reset 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module dff_async_reset ( 8 | data , // Data Input 9 | clk , // Clock Input 10 | reset , // Reset input 11 | q // Q output 12 | ); 13 | //-----------Input Ports--------------- 14 | input data, clk, reset ; 15 | 16 | //-----------Output Ports--------------- 17 | output q; 18 | 19 | //------------Internal Variables-------- 20 | reg q; 21 | 22 | //-------------Code Starts Here--------- 23 | always @ ( posedge clk or negedge reset) 24 | if (~reset) begin 25 | q <= 1'b0; 26 | end else begin 27 | q <= data; 28 | end 29 | 30 | endmodule //End Of Module dff_async_reset 31 | -------------------------------------------------------------------------------- /verilog/examples/parity_using_function.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : parity_using_function 3 | // File Name : parity_using_function.v 4 | // Function : Parity using function 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module parity_using_function ( 8 | data_in , // 8 bit data in 9 | parity_out // 1 bit parity out 10 | ); 11 | output parity_out ; 12 | input [7:0] data_in ; 13 | 14 | wire parity_out ; 15 | 16 | function parity; 17 | input [31:0] data; 18 | begin 19 | parity = (data_in[0] ^ data_in[1]) ^ 20 | (data_in[2] ^ data_in[3]) ^ 21 | (data_in[4] ^ data_in[5]) ^ 22 | (data_in[6] ^ data_in[7]); 23 | end 24 | endfunction 25 | 26 | 27 | assign parity_out = parity(data_in); 28 | 29 | endmodule 30 | -------------------------------------------------------------------------------- /netlist-to-vhdl/netlist-to-vhdl.cabal: -------------------------------------------------------------------------------- 1 | name: netlist-to-vhdl 2 | version: 0.2 3 | synopsis: Convert a Netlist AST to VHDL 4 | description: Convert a Netlist AST to VHDL 5 | category: Language 6 | license: BSD3 7 | license-file: LICENSE 8 | copyright: Copyright (c) 2010 University of Kansas 9 | author: Garrin Kimmell 10 | maintainer: garrin.kimmell@gmail.com 11 | package-url: git://github.com/pheaver/netlist-verilog.git 12 | build-type: Simple 13 | cabal-version: >=1.6 14 | 15 | flag base4 16 | Description: Compile using base-4 instead of base-3 17 | Default: True 18 | 19 | Library 20 | ghc-options: -Wall 21 | 22 | exposed-modules: Language.Netlist.GenVHDL 23 | 24 | build-depends: netlist == 0.2, pretty >= 1.0 25 | 26 | if flag(base4) 27 | build-depends: base == 4.* 28 | else 29 | build-depends: base == 3.* 30 | -------------------------------------------------------------------------------- /verilog/examples/mux_using_case.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : mux_using_case 3 | // File Name : mux_using_case.v 4 | // Function : 2:1 Mux using Case 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module mux_using_case( 8 | din_0 , // Mux first input 9 | din_1 , // Mux Second input 10 | sel , // Select input 11 | mux_out // Mux output 12 | ); 13 | //-----------Input Ports--------------- 14 | input din_0, din_1, sel ; 15 | //-----------Output Ports--------------- 16 | output mux_out; 17 | //------------Internal Variables-------- 18 | reg mux_out; 19 | //-------------Code Starts Here--------- 20 | always @ (sel or din_0 or din_1) 21 | begin : MUX 22 | case(sel ) 23 | 1'b0 : mux_out = din_0; 24 | 1'b1 : mux_out = din_1; 25 | endcase 26 | end 27 | 28 | endmodule //End Of Module mux 29 | -------------------------------------------------------------------------------- /verilog/examples/mux_using_if.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : mux_using_if 3 | // File Name : mux_using_if.v 4 | // Function : 2:1 Mux using If 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module mux_using_if( 8 | din_0 , // Mux first input 9 | din_1 , // Mux Second input 10 | sel , // Select input 11 | mux_out // Mux output 12 | ); 13 | //-----------Input Ports--------------- 14 | input din_0, din_1, sel ; 15 | //-----------Output Ports--------------- 16 | output mux_out; 17 | //------------Internal Variables-------- 18 | reg mux_out; 19 | //-------------Code Starts Here--------- 20 | always @ (sel or din_0 or din_1) 21 | begin : MUX 22 | if (sel == 1'b0) begin 23 | mux_out = din_0; 24 | end else begin 25 | mux_out = din_1 ; 26 | end 27 | end 28 | 29 | endmodule //End Of Module mux 30 | -------------------------------------------------------------------------------- /verilog/examples/lfsr_updown.v: -------------------------------------------------------------------------------- 1 | `define WIDTH 8 2 | module lfsr_updown ( 3 | clk , // Clock input 4 | reset , // Reset input 5 | enable , // Enable input 6 | up_down , // Up Down input 7 | count , // Count output 8 | overflow // Overflow output 9 | ); 10 | 11 | input clk; 12 | input reset; 13 | input enable; 14 | input up_down; 15 | 16 | output [`WIDTH-1 : 0] count; 17 | output overflow; 18 | 19 | reg [`WIDTH-1 : 0] count; 20 | 21 | assign overflow = (up_down) ? (count == {{`WIDTH-1{1'b0}}, 1'b1}) : 22 | (count == {1'b1, {`WIDTH-1{1'b0}}}) ; 23 | 24 | always @(posedge clk) 25 | if (reset) 26 | count <= {`WIDTH{1'b0}}; 27 | else if (enable) begin 28 | if (up_down) begin 29 | count <= {~(^(count & `WIDTH'b01100011)),count[`WIDTH-1:1]}; 30 | end else begin 31 | count <= {count[`WIDTH-2:0],~(^(count & `WIDTH'b10110001))}; 32 | end 33 | end 34 | 35 | endmodule 36 | -------------------------------------------------------------------------------- /verilog/examples/one_hot_cnt.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : one_hot_cnt 3 | // File Name : one_hot_cnt.v 4 | // Function : 8 bit one hot counter 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module one_hot_cnt ( 8 | out , // Output of the counter 9 | enable , // enable for counter 10 | clk , // clock input 11 | reset // reset input 12 | ); 13 | //----------Output Ports-------------- 14 | output [7:0] out; 15 | 16 | //------------Input Ports-------------- 17 | input enable, clk, reset; 18 | 19 | //------------Internal Variables-------- 20 | reg [7:0] out; 21 | 22 | //-------------Code Starts Here------- 23 | always @ (posedge clk) 24 | if (reset) begin 25 | out <= 8'b0000_0001 ; 26 | end else if (enable) begin 27 | out <= {out[6],out[5],out[4],out[3], 28 | out[2],out[1],out[0],out[7]}; 29 | end 30 | 31 | endmodule 32 | -------------------------------------------------------------------------------- /verilog/examples/up_down_counter.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : up_down_counter 3 | // File Name : up_down_counter.v 4 | // Function : Up down counter 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module up_down_counter ( 8 | out , // Output of the counter 9 | up_down , // up_down control for counter 10 | clk , // clock input 11 | reset // reset input 12 | ); 13 | //----------Output Ports-------------- 14 | output [7:0] out; 15 | //------------Input Ports-------------- 16 | input [7:0] data; 17 | input up_down, clk, reset; 18 | //------------Internal Variables-------- 19 | reg [7:0] out; 20 | //-------------Code Starts Here------- 21 | always @(posedge clk) 22 | if (reset) begin // active high reset 23 | out <= 8'b0 ; 24 | end else if (up_down) begin 25 | out <= out + 1; 26 | end else begin 27 | out <= out - 1; 28 | end 29 | 30 | endmodule 31 | -------------------------------------------------------------------------------- /netlist-to-verilog/netlist-to-verilog.cabal: -------------------------------------------------------------------------------- 1 | name: netlist-to-verilog 2 | version: 0.1 3 | synopsis: Convert a Netlist AST to a Verilog AST 4 | description: Convert a Netlist AST to a Verilog AST 5 | category: Language 6 | license: BSD3 7 | license-file: LICENSE 8 | copyright: Copyright (c) 2010 Signali Corp. 9 | Copyright (c) 2010 Philip Weaver 10 | author: Philip Weaver 11 | maintainer: philip.weaver@gmail.com 12 | package-url: git://github.com/pheaver/netlist-verilog.git 13 | build-type: Simple 14 | cabal-version: >=1.6 15 | 16 | flag base4 17 | Description: Compile using base-4 instead of base-3 18 | Default: True 19 | 20 | Library 21 | ghc-options: -Wall 22 | 23 | exposed-modules: Language.Netlist.GenVerilog 24 | 25 | build-depends: netlist == 0.2, verilog == 0.2 26 | 27 | if flag(base4) 28 | build-depends: base == 4.* 29 | else 30 | build-depends: base == 3.* 31 | 32 | -------------------------------------------------------------------------------- /verilog/examples/up_counter_load.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : up_counter_load 3 | // File Name : up_counter_load.v 4 | // Function : Up counter with load 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module up_counter_load ( 8 | out , // Output of the counter 9 | data , // Parallel load for the counter 10 | load , // Parallel load enable 11 | enable , // Enable counting 12 | clk , // clock input 13 | reset // reset input 14 | ); 15 | //----------Output Ports-------------- 16 | output [7:0] out; 17 | //------------Input Ports-------------- 18 | input [7:0] data; 19 | input load, enable, clk, reset; 20 | //------------Internal Variables-------- 21 | reg [7:0] out; 22 | //-------------Code Starts Here------- 23 | always @(posedge clk) 24 | if (reset) begin 25 | out <= 8'b0 ; 26 | end else if (load) begin 27 | out <= data; 28 | end else if (enable) begin 29 | out <= out + 1; 30 | end 31 | 32 | endmodule 33 | -------------------------------------------------------------------------------- /verilog/examples/rom_using_case.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : rom_using_case 3 | // File Name : rom_using_case.v 4 | // Function : ROM using case 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module rom_using_case ( 8 | address , // Address input 9 | data , // Data output 10 | read_en , // Read Enable 11 | ce // Chip Enable 12 | ); 13 | input [3:0] address; 14 | output [7:0] data; 15 | input read_en; 16 | input ce; 17 | 18 | reg [7:0] data ; 19 | 20 | always @ (ce or read_en or address) 21 | begin 22 | case (address) 23 | 0 : data = 10; 24 | 1 : data = 55; 25 | 2 : data = 244; 26 | 3 : data = 0; 27 | 4 : data = 1; 28 | 5 : data = 8'hff; 29 | 6 : data = 8'h11; 30 | 7 : data = 8'h1; 31 | 8 : data = 8'h10; 32 | 9 : data = 8'h0; 33 | 10 : data = 8'h10; 34 | 11 : data = 8'h15; 35 | 12 : data = 8'h60; 36 | 13 : data = 8'h90; 37 | 14 : data = 8'h70; 38 | 15 : data = 8'h90; 39 | endcase 40 | end 41 | 42 | endmodule 43 | -------------------------------------------------------------------------------- /verilog/examples/clk_div.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : clk_div 3 | // File Name : clk_div.v 4 | // Function : Divide by two counter 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | 8 | module clk_div (clk_in, enable,reset, clk_out); 9 | // --------------Port Declaration----------------------- 10 | input clk_in ; 11 | input reset ; 12 | input enable ; 13 | output clk_out ; 14 | //--------------Port data type declaration------------- 15 | wire clk_in ; 16 | wire enable ; 17 | //--------------Internal Registers---------------------- 18 | reg clk_out ; 19 | //--------------Code Starts Here----------------------- 20 | always @ (posedge clk_in) 21 | if (reset) begin 22 | clk_out <= 1'b0; 23 | end else if (enable) begin 24 | clk_out <= !clk_out ; 25 | end 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /verilog/examples/lfsr.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : lfsr 3 | // File Name : lfsr.v 4 | // Function : Linear feedback shift register 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module lfsr ( 8 | out , // Output of the counter 9 | enable , // Enable for counter 10 | clk , // clock input 11 | reset // reset input 12 | ); 13 | 14 | //----------Output Ports-------------- 15 | output [7:0] out; 16 | //------------Input Ports-------------- 17 | input [7:0] data; 18 | input enable, clk, reset; 19 | //------------Internal Variables-------- 20 | reg [7:0] out; 21 | wire linear_feedback; 22 | 23 | //-------------Code Starts Here------- 24 | assign linear_feedback = !(out[7] ^ out[3]); 25 | 26 | always @(posedge clk) 27 | if (reset) begin // active high reset 28 | out <= 8'b0 ; 29 | end else if (enable) begin 30 | out <= {out[6],out[5], 31 | out[4],out[3], 32 | out[2],out[1], 33 | out[0], linear_feedback}; 34 | end 35 | 36 | endmodule // End Of Module counter 37 | -------------------------------------------------------------------------------- /verilog/examples/gray_counter.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : gray_counter 3 | // File Name : gray_counter.v 4 | // Function : 8 bit gray counterS 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module gray_counter ( 8 | out , // counter out 9 | enable , // enable for counter 10 | clk , // clock 11 | rst // active hight reset 12 | ); 13 | 14 | //------------Input Ports-------------- 15 | input clk, rst, enable; 16 | //----------Output Ports---------------- 17 | output [ 7:0] out; 18 | //------------Internal Variables-------- 19 | wire [7:0] out; 20 | reg [7:0] count; 21 | //-------------Code Starts Here--------- 22 | always @ (posedge clk) 23 | if (rst) 24 | count <= 0; 25 | else if (enable) 26 | count <= count + 1; 27 | 28 | assign out = { count[7], (count[7] ^ count[6]),(count[6] ^ 29 | count[5]),(count[5] ^ count[4]), (count[4] ^ 30 | count[3]),(count[3] ^ count[2]), (count[2] ^ 31 | count[1]),(count[1] ^ count[0]) }; 32 | 33 | endmodule 34 | -------------------------------------------------------------------------------- /verilog/Language/Verilog/Syntax/Ident.hs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | -- | 3 | -- Module : Language.Verilog.Syntax.Ident 4 | -- Copyright : (c) Signali Corp. 2010 5 | -- License : All rights reserved 6 | -- 7 | -- Maintainer : pweaver@signalicorp.com 8 | -- Stability : experimental 9 | -- Portability : ghc 10 | -- 11 | -- Definition of Verilog identifiers. 12 | -------------------------------------------------------------------------------- 13 | 14 | {-# LANGUAGE DeriveDataTypeable #-} 15 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} 16 | 17 | module Language.Verilog.Syntax.Ident 18 | ( -- * Identifier 19 | Ident(..) 20 | ) where 21 | 22 | import Data.Binary ( Binary ) 23 | import Data.Generics ( Data, Typeable ) 24 | 25 | -------------------------------------------------------------------------------- 26 | 27 | -- TODO check if an identifier is valid; convert to valid identifier 28 | 29 | newtype Ident = Ident String 30 | deriving (Eq, Ord, Show, Binary, Data, Typeable) 31 | 32 | -------------------------------------------------------------------------------- 33 | -------------------------------------------------------------------------------- /netlist/netlist.cabal: -------------------------------------------------------------------------------- 1 | name: netlist 2 | version: 0.2 3 | synopsis: Netlist AST 4 | description: A very simplified and generic netlist designed to be compatible with 5 | Hardware Description Languages (HDLs) like Verilog and VHDL. 6 | Includes a simple inliner. 7 | category: Language 8 | license: BSD3 9 | license-file: LICENSE 10 | copyright: Copyright (c) 2010 Signali Corp. 11 | Copyright (c) 2010 Philip Weaver 12 | author: Philip Weaver 13 | maintainer: philip.weaver@gmail.com 14 | package-url: git://github.com/pheaver/netlist-verilog.git 15 | build-type: Simple 16 | cabal-version: >=1.6 17 | 18 | flag base4 19 | Description: Compile using base-4 instead of base-3 20 | Default: True 21 | 22 | Library 23 | ghc-options: -Wall 24 | 25 | exposed-modules: Language.Netlist.AST, 26 | Language.Netlist.Inline, 27 | Language.Netlist.Util 28 | other-modules: Language.Netlist.Examples 29 | 30 | build-depends: binary, containers 31 | if flag(base4) 32 | build-depends: base == 4.*, syb 33 | else 34 | build-depends: base == 3.* 35 | -------------------------------------------------------------------------------- /verilog/verilog.cabal: -------------------------------------------------------------------------------- 1 | name: verilog 2 | version: 0.2 3 | synopsis: Verilog AST and pretty printer 4 | description: Verilog AST and pretty printer -- parser to come later 5 | category: Language 6 | license: BSD3 7 | license-file: LICENSE 8 | copyright: Copyright (c) 2010 Signali Corp. 9 | Copyright (c) 2010 Philip Weaver 10 | author: Philip Weaver 11 | maintainer: philip.weaver@gmail.com 12 | package-url: git://github.com/pheaver/netlist-verilog.git 13 | build-type: Simple 14 | cabal-version: >=1.6 15 | 16 | flag base4 17 | Description: Compile using base-4 instead of base-3 18 | Default: True 19 | 20 | Library 21 | ghc-options: -Wall 22 | 23 | exposed-modules: Language.Verilog.Syntax, 24 | Language.Verilog.Syntax.Expression, 25 | Language.Verilog.Syntax.Ident, 26 | Language.Verilog.Syntax.AST, 27 | Language.Verilog.Parser, 28 | Language.Verilog.PrettyPrint, 29 | Language.Verilog 30 | 31 | build-depends: binary, pretty, parsec == 3.*, mtl 32 | if flag(base4) 33 | build-depends: base == 4.*, syb 34 | else 35 | build-depends: base == 3.* 36 | -------------------------------------------------------------------------------- /verilog/examples/arbiter_tb.v: -------------------------------------------------------------------------------- 1 | `include "arbiter.v" 2 | module top (); 3 | 4 | reg clk; 5 | reg rst; 6 | reg req3; 7 | reg req2; 8 | reg req1; 9 | reg req0; 10 | wire gnt3; 11 | wire gnt2; 12 | wire gnt1; 13 | wire gnt0; 14 | 15 | // Clock generator 16 | always #1 clk = ~clk; 17 | 18 | initial begin 19 | $dumpfile ("arbiter.vcd"); 20 | $dumpvars(); 21 | clk = 0; 22 | rst = 1; 23 | req0 = 0; 24 | req1 = 0; 25 | req2 = 0; 26 | req3 = 0; 27 | #10 rst = 0; 28 | repeat (1) @ (posedge clk); 29 | req0 <= 1; 30 | repeat (1) @ (posedge clk); 31 | req0 <= 0; 32 | repeat (1) @ (posedge clk); 33 | req0 <= 1; 34 | req1 <= 1; 35 | repeat (1) @ (posedge clk); 36 | req2 <= 1; 37 | req1 <= 0; 38 | repeat (1) @ (posedge clk); 39 | req3 <= 1; 40 | req2 <= 0; 41 | repeat (1) @ (posedge clk); 42 | req3 <= 0; 43 | repeat (1) @ (posedge clk); 44 | req0 <= 0; 45 | repeat (1) @ (posedge clk); 46 | #10 $finish; 47 | end 48 | 49 | // Connect the DUT 50 | arbiter U ( 51 | clk, 52 | rst, 53 | req3, 54 | req2, 55 | req1, 56 | req0, 57 | gnt3, 58 | gnt2, 59 | gnt1, 60 | gnt0 61 | ); 62 | 63 | endmodule 64 | -------------------------------------------------------------------------------- /verilog/examples/GrayCounter.v: -------------------------------------------------------------------------------- 1 | //========================================== 2 | // Function : Code Gray counter. 3 | // Coder : Alex Claros F. 4 | // Date : 15/May/2005. 5 | //======================================= 6 | 7 | `timescale 1ns/1ps 8 | 9 | module GrayCounter 10 | #(parameter COUNTER_WIDTH = 4) 11 | 12 | (output reg [COUNTER_WIDTH-1:0] GrayCount_out, //'Gray' code count output. 13 | 14 | input wire Enable_in, //Count enable. 15 | input wire Clear_in, //Count reset. 16 | 17 | input wire Clk); 18 | 19 | /////////Internal connections & variables/////// 20 | reg [COUNTER_WIDTH-1:0] BinaryCount; 21 | 22 | /////////Code/////////////////////// 23 | 24 | always @ (posedge Clk) 25 | if (Clear_in) begin 26 | BinaryCount <= {COUNTER_WIDTH{1'b 0}} + 1; //Gray count begins @ '1' with 27 | GrayCount_out <= {COUNTER_WIDTH{1'b 0}}; // first 'Enable_in'. 28 | end 29 | else if (Enable_in) begin 30 | BinaryCount <= BinaryCount + 1; 31 | GrayCount_out <= {BinaryCount[COUNTER_WIDTH-1], 32 | BinaryCount[COUNTER_WIDTH-2:0] ^ BinaryCount[COUNTER_WIDTH-1:1]}; 33 | end 34 | 35 | endmodule 36 | -------------------------------------------------------------------------------- /verilog/examples/encoder_using_case.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : encoder_using_case 3 | // File Name : encoder_using_case.v 4 | // Function : Encoder using Case 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module encoder_using_case( 8 | binary_out , // 4 bit binary Output 9 | encoder_in , // 16-bit Input 10 | enable // Enable for the encoder 11 | ); 12 | output [3:0] binary_out ; 13 | input enable ; 14 | input [15:0] encoder_in ; 15 | 16 | reg [3:0] binary_out ; 17 | 18 | always @ (enable or encoder_in) 19 | begin 20 | binary_out = 0; 21 | if (enable) begin 22 | case (encoder_in) 23 | 16'h0002 : binary_out = 1; 24 | 16'h0004 : binary_out = 2; 25 | 16'h0008 : binary_out = 3; 26 | 16'h0010 : binary_out = 4; 27 | 16'h0020 : binary_out = 5; 28 | 16'h0040 : binary_out = 6; 29 | 16'h0080 : binary_out = 7; 30 | 16'h0100 : binary_out = 8; 31 | 16'h0200 : binary_out = 9; 32 | 16'h0400 : binary_out = 10; 33 | 16'h0800 : binary_out = 11; 34 | 16'h1000 : binary_out = 12; 35 | 16'h2000 : binary_out = 13; 36 | 16'h4000 : binary_out = 14; 37 | 16'h8000 : binary_out = 15; 38 | endcase 39 | end 40 | end 41 | 42 | endmodule 43 | -------------------------------------------------------------------------------- /verilog/examples/decoder_using_case.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : decoder_using_case 3 | // File Name : decoder_using_case.v 4 | // Function : decoder using case 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module decoder_using_case ( 8 | binary_in , // 4 bit binary input 9 | decoder_out , // 16-bit out 10 | enable // Enable for the decoder 11 | ); 12 | input [3:0] binary_in ; 13 | input enable ; 14 | output [15:0] decoder_out ; 15 | 16 | reg [15:0] decoder_out ; 17 | 18 | always @ (enable or binary_in) 19 | begin 20 | decoder_out = 0; 21 | if (enable) begin 22 | case (binary_in) 23 | 4'h0 : decoder_out = 16'h0001; 24 | 4'h1 : decoder_out = 16'h0002; 25 | 4'h2 : decoder_out = 16'h0004; 26 | 4'h3 : decoder_out = 16'h0008; 27 | 4'h4 : decoder_out = 16'h0010; 28 | 4'h5 : decoder_out = 16'h0020; 29 | 4'h6 : decoder_out = 16'h0040; 30 | 4'h7 : decoder_out = 16'h0080; 31 | 4'h8 : decoder_out = 16'h0100; 32 | 4'h9 : decoder_out = 16'h0200; 33 | 4'hA : decoder_out = 16'h0400; 34 | 4'hB : decoder_out = 16'h0800; 35 | 4'hC : decoder_out = 16'h1000; 36 | 4'hD : decoder_out = 16'h2000; 37 | 4'hE : decoder_out = 16'h4000; 38 | 4'hF : decoder_out = 16'h8000; 39 | endcase 40 | end 41 | end 42 | 43 | endmodule 44 | -------------------------------------------------------------------------------- /verilog/examples/rom.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : rom 3 | // File Name : rom.v 4 | // Function : ROM Using readmemb 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module rom ( 8 | address , // Address input 9 | data , // Data output 10 | read_en , // Read Enable 11 | ce // Chip Enable 12 | ); 13 | input [7:0] address; 14 | output [7:0] data; 15 | input read_en; 16 | input ce; 17 | 18 | 19 | reg [7:0] mem [0:255] ; 20 | integer file_pointer; 21 | 22 | assign data = (ce && read_en) ? mem[address] : 8'b0; 23 | 24 | integer i; 25 | 26 | initial begin 27 | $readmemb("memory.list",mem); 28 | end 29 | 30 | 31 | endmodule 32 | 33 | 34 | module rom_tb; 35 | reg [7:0] address; 36 | reg read_en, ce; 37 | wire [7:0] data; 38 | integer i; 39 | 40 | initial begin 41 | address = 0; 42 | read_en = 0; 43 | ce = 0; 44 | #10 $monitor ("address = %h, data = %h, read_en = %b, ce = %b", address, data, read_en, ce); 45 | for (i = 0; i <256; i = i +1 )begin 46 | #5 address = i; 47 | read_en = 1; 48 | ce = 1; 49 | #5 read_en = 0; 50 | ce = 0; 51 | address = 0; 52 | end 53 | end 54 | 55 | rom U( 56 | address , // Address input 57 | data , // Data output 58 | read_en , // Read Enable 59 | ce // Chip Enable 60 | ); 61 | 62 | endmodule 63 | 64 | 65 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | all: derive 3 | 4 | PACKAGEDB=package.conf.d 5 | 6 | ifneq (,$(findstring CYGWIN, $(ARCH))) 7 | PREFIX_PATH:=$(shell cygpath.exe -m -w $(PWD))/dist 8 | PACKAGEDB_PATH:=$(shell cygpath.exe -m -w $(abspath $(PACKAGEDB))) 9 | else 10 | PREFIX_PATH=$(PWD)/dist 11 | PACKAGEDB_PATH=$(abspath $(PACKAGEDB)) 12 | endif 13 | 14 | .PHONY: packagedb 15 | packagedb: $(PACKAGEDB) 16 | $(PACKAGEDB): 17 | ghc-pkg init $(PACKAGEDB) 18 | 19 | install-local: 20 | cd netlist && cabal install --prefix=$(PREFIX_PATH) --package-db=$(PACKAGEDB_PATH) 21 | cd netlist-to-vhdl && cabal install --prefix=$(PREFIX_PATH) --package-db=$(PACKAGEDB_PATH) 22 | cd verilog && cabal install --prefix=$(PREFIX_PATH) --package-db=$(PACKAGEDB_PATH) 23 | cd netlist-to-verilog && cabal install --prefix=$(PREFIX_PATH) --package-db=$(PACKAGEDB_PATH) 24 | 25 | .PHONY: derive 26 | # run derive on every file that has derived instances in it. 27 | # generated boilerplate code for instances of Binary. 28 | .PHONY: derive 29 | derive: 30 | @for f in `grep -l OPTIONS_DERIVE -r --include=*.hs .`; do \ 31 | echo derive $$f; derive $$f; \ 32 | sed -i -e 's/[ \t]*$$//g' $$f; done 33 | 34 | .PHONY: delete-trailing-whitespace 35 | delete-trailing-whitespace: 36 | @for f in `/usr/bin/find . -iname \*.hs`; do \ 37 | sed -i -e 's/[ \t]*$$//g' $$f; done 38 | 39 | 40 | hudson: 41 | cd netlist && cabal install 42 | cd netlist-to-vhdl && cabal install 43 | -------------------------------------------------------------------------------- /netlist-to-vhdl/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 The University of Kansas 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions 6 | are met: 7 | 1. Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | 3. The names of the authors may not be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 19 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | -------------------------------------------------------------------------------- /verilog/examples/pri_encoder_using_assign.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : pri_encoder_using_assign 3 | // File Name : pri_encoder_using_assign.v 4 | // Function : Pri Encoder using assign 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module pri_encoder_using_assign ( 8 | binary_out , // 4 bit binary output 9 | encoder_in , // 16-bit input 10 | enable // Enable for the encoder 11 | ); 12 | 13 | output [3:0] binary_out ; 14 | input enable ; 15 | input [15:0] encoder_in ; 16 | 17 | wire [3:0] binary_out ; 18 | 19 | assign binary_out = (!enable) ? 0 : ( 20 | (encoder_in == 16'bxxxx_xxxx_xxxx_xxx1) ? 0 : 21 | (encoder_in == 16'bxxxx_xxxx_xxxx_xx10) ? 1 : 22 | (encoder_in == 16'bxxxx_xxxx_xxxx_x100) ? 2 : 23 | (encoder_in == 16'bxxxx_xxxx_xxxx_1000) ? 3 : 24 | (encoder_in == 16'bxxxx_xxxx_xxx1_0000) ? 4 : 25 | (encoder_in == 16'bxxxx_xxxx_xx10_0000) ? 5 : 26 | (encoder_in == 16'bxxxx_xxxx_x100_0000) ? 6 : 27 | (encoder_in == 16'bxxxx_xxxx_1000_0000) ? 7 : 28 | (encoder_in == 16'bxxxx_xxx1_0000_0000) ? 8 : 29 | (encoder_in == 16'bxxxx_xx10_0000_0000) ? 9 : 30 | (encoder_in == 16'bxxxx_x100_0000_0000) ? 10 : 31 | (encoder_in == 16'bxxxx_1000_0000_0000) ? 11 : 32 | (encoder_in == 16'bxxx1_0000_0000_0000) ? 12 : 33 | (encoder_in == 16'bxx10_0000_0000_0000) ? 13 : 34 | (encoder_in == 16'bx100_0000_0000_0000) ? 14 : 15); 35 | 36 | endmodule 37 | -------------------------------------------------------------------------------- /verilog/examples/divide_by_3.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : divide_by_3 3 | // File Name : divide_by_3.v 4 | // Function : Divide By 3 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module divide_by_3 ( 8 | clk_in , //Input Clock 9 | reset , // Reset Input 10 | clk_out // Output Clock 11 | ); 12 | //-----------Input Ports--------------- 13 | input clk_in; 14 | input reset; 15 | //-----------Output Ports--------------- 16 | output clk_out; 17 | //------------Internal Variables-------- 18 | reg [1:0] pos_cnt; 19 | reg [1:0] neg_cnt; 20 | //-------------Code Start----------------- 21 | // Posedge counter 22 | always @ (posedge clk_in) 23 | if (reset) begin 24 | pos_cnt <= 0; 25 | end else begin 26 | pos_cnt <= (pos_cnt == 2) ? 0 : pos_cnt + 1; 27 | end 28 | // Neg edge counter 29 | always @ (negedge clk_in) 30 | if (reset) begin 31 | neg_cnt <= 0; 32 | end else begin 33 | neg_cnt <= (neg_cnt == 2) ? 0 : neg_cnt + 1; 34 | end 35 | 36 | assign clk_out = ((pos_cnt != 2) && (neg_cnt != 2)); 37 | 38 | endmodule 39 | 40 | // Testbench to check the divide_by_3 logic 41 | module test(); 42 | reg reset, clk_in; 43 | wire clk_out; 44 | divide_by_3 U ( 45 | .clk_in (clk_in), 46 | .reset (reset), 47 | .clk_out (clk_out) 48 | ); 49 | 50 | initial begin 51 | clk_in = 0; 52 | reset = 0; 53 | #2 reset = 1; 54 | #2 reset = 0; 55 | #100 $finish; 56 | end 57 | 58 | always #1 clk_in = ~clk_in; 59 | 60 | endmodule 61 | -------------------------------------------------------------------------------- /verilog/examples/serial_crc.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : serial_crc_ccitt 3 | // File Name : serial_crc.v 4 | // Function : CCITT Serial CRC 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module serial_crc_ccitt ( 8 | clk , 9 | reset , 10 | enable , 11 | init , 12 | data_in , 13 | crc_out 14 | ); 15 | //-----------Input Ports--------------- 16 | input clk ; 17 | input reset ; 18 | input enable ; 19 | input init ; 20 | input data_in ; 21 | //-----------Output Ports--------------- 22 | output [15:0] crc_out; 23 | //------------Internal Variables-------- 24 | reg [15:0] lfsr; 25 | //-------------Code Start----------------- 26 | assign crc_out = lfsr; 27 | // Logic to CRC Calculation 28 | always @ (posedge clk) 29 | if (reset) begin 30 | lfsr <= 16'hFFFF; 31 | end else if (enable) begin 32 | if (init) begin 33 | lfsr <= 16'hFFFF; 34 | end else begin 35 | lfsr[0] <= data_in ^ lfsr[15]; 36 | lfsr[1] <= lfsr[0]; 37 | lfsr[2] <= lfsr[1]; 38 | lfsr[3] <= lfsr[2]; 39 | lfsr[4] <= lfsr[3]; 40 | lfsr[5] <= lfsr[4] ^ data_in ^ lfsr[15]; 41 | lfsr[6] <= lfsr[5]; 42 | lfsr[7] <= lfsr[6]; 43 | lfsr[8] <= lfsr[7]; 44 | lfsr[9] <= lfsr[8]; 45 | lfsr[10] <= lfsr[9]; 46 | lfsr[11] <= lfsr[10]; 47 | lfsr[12] <= lfsr[11] ^ data_in ^ lfsr[15]; 48 | lfsr[13] <= lfsr[12]; 49 | lfsr[14] <= lfsr[13]; 50 | lfsr[15] <= lfsr[14]; 51 | end 52 | end 53 | 54 | endmodule 55 | -------------------------------------------------------------------------------- /netlist/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2010, Signali Corp. 2 | 3 | All Rights Reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the author nor the names of other contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /verilog/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2010, Signali Corp. 2 | 3 | All Rights Reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the author nor the names of other contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /netlist-to-verilog/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2010, Signali Corp. 2 | 3 | All Rights Reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name of the author nor the names of other contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /verilog/examples/clk_div_45.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : clk_div_45 3 | // File Name : clk_div_45.v 4 | // Function : Divide by 4.5 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module clk_div_45 ( 8 | clk_in, // Input Clock 9 | enable, // Enable is sync with falling edge of clk_in 10 | clk_out // Output Clock 11 | ); 12 | 13 | // --------------Port Declaration----------------------- 14 | input clk_in ; 15 | input enable ; 16 | output clk_out ; 17 | 18 | //--------------Port data type declaration------------- 19 | wire clk_in ; 20 | wire enable ; 21 | wire clk_out ; 22 | 23 | //--------------Internal Registers---------------------- 24 | reg [3:0] counter1 ; 25 | reg [3:0] counter2 ; 26 | reg toggle1 ; 27 | reg toggle2 ; 28 | 29 | //--------------Code Starts Here----------------------- 30 | always @ (posedge clk_in) 31 | if (enable == 1'b0) begin 32 | counter1 <= 4'b0; 33 | toggle1 <= 0; 34 | end else if ((counter1 == 3 && toggle2) || (~toggle1 && counter1 == 4)) begin 35 | counter1 <= 4'b0; 36 | toggle1 <= ~toggle1; 37 | end else begin 38 | counter1 <= counter1 + 1; 39 | end 40 | 41 | always @ (negedge clk_in) 42 | if (enable == 1'b0) begin 43 | counter2 <= 4'b0; 44 | toggle2 <= 0; 45 | end else if ((counter2 == 3 && ~toggle2) || (toggle2 && counter2 == 4)) begin 46 | counter2 <= 4'b0; 47 | toggle2 <= ~toggle2; 48 | end else begin 49 | counter2 <= counter2 + 1; 50 | end 51 | 52 | assign clk_out = (counter1 <3 && counter2 < 3) & enable; 53 | 54 | endmodule 55 | -------------------------------------------------------------------------------- /verilog/examples/ram_sp_ar_aw.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : ram_sp_ar_aw 3 | // File Name : ram_sp_ar_aw.v 4 | // Function : Asynchronous read write RAM 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module ram_sp_ar_aw ( 8 | address , // Address Input 9 | data , // Data bi-directional 10 | cs , // Chip Select 11 | we , // Write Enable/Read Enable 12 | oe // Output Enable 13 | ); 14 | parameter DATA_WIDTH = 8 ; 15 | parameter ADDR_WIDTH = 8 ; 16 | parameter RAM_DEPTH = 1 << ADDR_WIDTH; 17 | 18 | //--------------Input Ports----------------------- 19 | input [ADDR_WIDTH-1:0] address ; 20 | input cs ; 21 | input we ; 22 | input oe ; 23 | 24 | //--------------Inout Ports----------------------- 25 | inout [DATA_WIDTH-1:0] data ; 26 | 27 | //--------------Internal variables---------------- 28 | reg [DATA_WIDTH-1:0] data_out ; 29 | reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1]; 30 | 31 | //--------------Code Starts Here------------------ 32 | 33 | // Tri-State Buffer control 34 | // output : When we = 0, oe = 1, cs = 1 35 | assign data = (cs && oe && !we) ? data_out : 8'bz; 36 | 37 | // Memory Write Block 38 | // Write Operation : When we = 1, cs = 1 39 | always @ (address or data or cs or we) 40 | begin : MEM_WRITE 41 | if ( cs && we ) begin 42 | mem[address] = data; 43 | end 44 | end 45 | 46 | // Memory Read Block 47 | // Read Operation : When we = 0, oe = 1, cs = 1 48 | always @ (address or cs or we or oe) 49 | begin : MEM_READ 50 | if (cs && !we && oe) begin 51 | data_out = mem[address]; 52 | end 53 | end 54 | 55 | endmodule // End of Module ram_sp_ar_aw 56 | -------------------------------------------------------------------------------- /verilog/examples/parallel_crc.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : parallel_crc_ccitt 3 | // File Name : parallel_crc.v 4 | // Function : CCITT Parallel CRC 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module parallel_crc_ccitt ( 8 | clk , 9 | reset , 10 | enable , 11 | init , 12 | data_in , 13 | crc_out 14 | ); 15 | //-----------Input Ports--------------- 16 | input clk ; 17 | input reset ; 18 | input enable ; 19 | input init ; 20 | input [7:0] data_in ; 21 | //-----------Output Ports--------------- 22 | output [15:0] crc_out; 23 | //------------Internal Variables-------- 24 | reg [15:0] crc_reg; 25 | wire [15:0] next_crc; 26 | //-------------Code Start----------------- 27 | assign crc_out = crc_reg; 28 | // CRC Control logic 29 | always @ (posedge clk) 30 | if (reset) begin 31 | crc_reg <= 16'hFFFF; 32 | end else if (enable) begin 33 | if (init) begin 34 | crc_reg <= 16'hFFFF; 35 | end else begin 36 | crc_reg <= next_crc; 37 | end 38 | end 39 | // Parallel CRC calculation 40 | assign next_crc[0] = data_in[7] ^ data_in[0] ^ crc_reg[4] ^ crc_reg[11]; 41 | assign next_crc[1] = data_in[1] ^ crc_reg[5]; 42 | assign next_crc[2] = data_in[2] ^ crc_reg[6]; 43 | assign next_crc[3] = data_in[3] ^ crc_reg[7]; 44 | assign next_crc[4] = data_in[4] ^ crc_reg[8]; 45 | assign next_crc[5] = data_in[7] ^ data_in[5] ^ data_in[0] ^ crc_reg[4] ^ crc_reg[9] ^ crc_reg[11]; 46 | assign next_crc[6] = data_in[6] ^ data_in[1] ^ crc_reg[5] ^ crc_reg[10]; 47 | assign next_crc[7] = data_in[7] ^ data_in[2] ^ crc_reg[6] ^ crc_reg[11]; 48 | assign next_crc[8] = data_in[3] ^ crc_reg[0] ^ crc_reg[7]; 49 | assign next_crc[9] = data_in[4] ^ crc_reg[1] ^ crc_reg[8]; 50 | assign next_crc[10] = data_in[5] ^ crc_reg[2] ^ crc_reg[9]; 51 | assign next_crc[11] = data_in[6] ^ crc_reg[3] ^ crc_reg[10]; 52 | 53 | endmodule 54 | -------------------------------------------------------------------------------- /verilog/examples/ram_sp_sr_sw.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : ram_sp_sr_sw 3 | // File Name : ram_sp_sr_sw.v 4 | // Function : Synchronous read write RAM 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module ram_sp_sr_sw ( 8 | clk , // Clock Input 9 | address , // Address Input 10 | data , // Data bi-directional 11 | cs , // Chip Select 12 | we , // Write Enable/Read Enable 13 | oe // Output Enable 14 | ); 15 | 16 | parameter DATA_WIDTH = 8 ; 17 | parameter ADDR_WIDTH = 8 ; 18 | parameter RAM_DEPTH = 1 << ADDR_WIDTH; 19 | 20 | //--------------Input Ports----------------------- 21 | input clk ; 22 | input [ADDR_WIDTH-1:0] address ; 23 | input cs ; 24 | input we ; 25 | input oe ; 26 | 27 | //--------------Inout Ports----------------------- 28 | inout [DATA_WIDTH-1:0] data ; 29 | 30 | //--------------Internal variables---------------- 31 | reg [DATA_WIDTH-1:0] data_out ; 32 | reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1]; 33 | reg oe_r; 34 | 35 | //--------------Code Starts Here------------------ 36 | 37 | // Tri-State Buffer control 38 | // output : When we = 0, oe = 1, cs = 1 39 | assign data = (cs && oe && !we) ? data_out : 8'bz; 40 | 41 | // Memory Write Block 42 | // Write Operation : When we = 1, cs = 1 43 | always @ (posedge clk) 44 | begin : MEM_WRITE 45 | if ( cs && we ) begin 46 | mem[address] = data; 47 | end 48 | end 49 | 50 | // Memory Read Block 51 | // Read Operation : When we = 0, oe = 1, cs = 1 52 | always @ (posedge clk) 53 | begin : MEM_READ 54 | if (cs && !we && oe) begin 55 | data_out = mem[address]; 56 | oe_r = 1; 57 | end else begin 58 | oe_r = 0; 59 | end 60 | end 61 | 62 | endmodule // End of Module ram_sp_sr_sw 63 | -------------------------------------------------------------------------------- /verilog/examples/ram_sp_ar_sw.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : ram_sp_ar_sw 3 | // File Name : ram_sp_ar_sw.v 4 | // Function : Asynchronous read write RAM 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module ram_sp_ar_sw ( 8 | clk , // Clock Input 9 | address , // Address Input 10 | data , // Data bi-directional 11 | cs , // Chip Select 12 | we , // Write Enable/Read Enable 13 | oe // Output Enable 14 | ); 15 | 16 | parameter DATA_WIDTH = 8 ; 17 | parameter ADDR_WIDTH = 8 ; 18 | parameter RAM_DEPTH = 1 << ADDR_WIDTH; 19 | 20 | //--------------Input Ports----------------------- 21 | input clk ; 22 | input [ADDR_WIDTH-1:0] address ; 23 | input cs ; 24 | input we ; 25 | input oe ; 26 | 27 | //--------------Inout Ports----------------------- 28 | inout [DATA_WIDTH-1:0] data ; 29 | 30 | //--------------Internal variables---------------- 31 | reg [DATA_WIDTH-1:0] data_out ; 32 | reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1]; 33 | 34 | //--------------Code Starts Here------------------ 35 | 36 | // Tri-State Buffer control 37 | // output : When we = 0, oe = 1, cs = 1 38 | assign data = (cs && oe && !we) ? data_out : 8'bz; 39 | 40 | // Memory Write Block 41 | // Write Operation : When we = 1, cs = 1 42 | always @ (posedge clk) 43 | begin : MEM_WRITE 44 | if ( cs && we ) begin 45 | mem[address] = data; 46 | end 47 | end 48 | 49 | // Memory Read Block 50 | // Read Operation : When we = 0, oe = 1, cs = 1 51 | always @ (address or cs or we or oe) 52 | begin : MEM_READ 53 | if (cs && !we && oe) begin 54 | data_out = mem[address]; 55 | end 56 | end 57 | 58 | endmodule // End of Module ram_sp_ar_sw 59 | -------------------------------------------------------------------------------- /verilog/examples/cam.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : cam 3 | // File Name : cam.v 4 | // Function : CAM 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module cam ( 8 | clk , // Cam clock 9 | cam_enable , // Cam enable 10 | cam_data_in , // Cam data to match 11 | cam_hit_out , // Cam match has happened 12 | cam_addr_out // Cam output address 13 | ); 14 | 15 | parameter ADDR_WIDTH = 8; 16 | parameter DEPTH = 1 << ADDR_WIDTH; 17 | //------------Input Ports-------------- 18 | input clk; 19 | input cam_enable; 20 | input [DEPTH-1:0] cam_data_in; 21 | //----------Output Ports-------------- 22 | output cam_hit_out; 23 | output [ADDR_WIDTH-1:0] cam_addr_out; 24 | //------------Internal Variables-------- 25 | reg [ADDR_WIDTH-1:0] cam_addr_out; 26 | reg cam_hit_out; 27 | reg [ADDR_WIDTH-1:0] cam_addr_combo; 28 | reg cam_hit_combo; 29 | reg found_match; 30 | integer i; 31 | //-------------Code Starts Here------- 32 | always @(cam_data_in) begin 33 | cam_addr_combo = {ADDR_WIDTH{1'b0}}; 34 | found_match = 1'b0; 35 | cam_hit_combo = 1'b0; 36 | for (i=0; i), replaceExtension, takeExtension) 9 | import Text.PrettyPrint (render) 10 | import Text.Parsec (parse) 11 | import Text.Parsec.ByteString (parseFromFile) 12 | 13 | import Language.Verilog.Parser 14 | import Language.Verilog.PrettyPrint (ppVerilog) 15 | import Language.Verilog.Syntax (Verilog) 16 | 17 | -------------------------------------------------------------------------------- 18 | 19 | examples_dir :: FilePath 20 | examples_dir = "./verilog/examples" 21 | 22 | check_all :: IO () 23 | check_all 24 | = do files <- getDirectoryContents examples_dir 25 | sequence_ [ check f 26 | | f <- files 27 | , takeExtension f == ".v" 28 | ] 29 | return () 30 | 31 | check :: FilePath -> IO () 32 | check baseName 33 | = do result1 <- parseFromFile verilogFile fp 34 | case result1 of 35 | Left err1 -> do writeFile fp_err1 (show err1 ++ "\n") 36 | putStrLn ("Fail1: " ++ baseName) 37 | Right ast1 -> do let str1 = render (ppVerilog ast1) 38 | writeFile fp1 str1 39 | result2 <- parseFromFile verilogFile fp1 40 | case result2 of 41 | Left err2 -> do writeFile fp_err2 (show err2 ++ "\n") 42 | putStrLn ("Fail2: " ++ baseName) 43 | Right ast2 -> do let str2 = render (ppVerilog ast2) 44 | writeFile fp2 str2 45 | if (ast1 == ast2) 46 | then putStrLn ("Match: " ++ baseName) 47 | else do writeFile fp_err3 "" 48 | putStrLn ("No match: " ++ baseName) 49 | where 50 | fp = examples_dir baseName 51 | fp1 = replaceExtension fp "v.2" 52 | fp2 = replaceExtension fp "v.3" 53 | fp_err1 = replaceExtension fp "err1" 54 | fp_err2 = replaceExtension fp "err2" 55 | fp_err3 = replaceExtension fp "err3" 56 | 57 | parseVerilog :: String -> Verilog 58 | parseVerilog x 59 | = case parse verilogFile "" x of 60 | Left err -> error (show err) 61 | Right y -> y 62 | 63 | test :: FilePath -> IO () 64 | test fp 65 | = do x <- run fp 66 | putStrLn (render (ppVerilog x)) 67 | 68 | run :: FilePath -> IO Verilog 69 | run fp 70 | = do x <- parseFromFile verilogFile fp 71 | case x of 72 | Left err -> error (show err) 73 | Right y -> return y 74 | 75 | -------------------------------------------------------------------------------- 76 | 77 | -------------------------------------------------------------------------------- /verilog/examples/syn_fifo.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : syn_fifo 3 | // File Name : syn_fifo.v 4 | // Function : Synchronous (single clock) FIFO 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module syn_fifo ( 8 | clk , // Clock input 9 | rst , // Active high reset 10 | wr_cs , // Write chip select 11 | rd_cs , // Read chipe select 12 | data_in , // Data input 13 | rd_en , // Read enable 14 | wr_en , // Write Enable 15 | data_out , // Data Output 16 | empty , // FIFO empty 17 | full // FIFO full 18 | ); 19 | 20 | // FIFO constants 21 | parameter DATA_WIDTH = 8; 22 | parameter ADDR_WIDTH = 8; 23 | parameter RAM_DEPTH = (1 << ADDR_WIDTH); 24 | // Port Declarations 25 | input clk ; 26 | input rst ; 27 | input wr_cs ; 28 | input rd_cs ; 29 | input rd_en ; 30 | input wr_en ; 31 | input [DATA_WIDTH-1:0] data_in ; 32 | output full ; 33 | output empty ; 34 | output [DATA_WIDTH-1:0] data_out ; 35 | 36 | //-----------Internal variables------------------- 37 | reg [ADDR_WIDTH-1:0] wr_pointer; 38 | reg [ADDR_WIDTH-1:0] rd_pointer; 39 | reg [ADDR_WIDTH :0] status_cnt; 40 | reg [DATA_WIDTH-1:0] data_out ; 41 | wire [DATA_WIDTH-1:0] data_ram ; 42 | 43 | //-----------Variable assignments--------------- 44 | assign full = (status_cnt == (RAM_DEPTH-1)); 45 | assign empty = (status_cnt == 0); 46 | 47 | //-----------Code Start--------------------------- 48 | always @ (posedge clk or posedge rst) 49 | begin : WRITE_POINTER 50 | if (rst) begin 51 | wr_pointer <= 0; 52 | end else if (wr_cs && wr_en ) begin 53 | wr_pointer <= wr_pointer + 1; 54 | end 55 | end 56 | 57 | always @ (posedge clk or posedge rst) 58 | begin : READ_POINTER 59 | if (rst) begin 60 | rd_pointer <= 0; 61 | end else if (rd_cs && rd_en ) begin 62 | rd_pointer <= rd_pointer + 1; 63 | end 64 | end 65 | 66 | always @ (posedge clk or posedge rst) 67 | begin : READ_DATA 68 | if (rst) begin 69 | data_out <= 0; 70 | end else if (rd_cs && rd_en ) begin 71 | data_out <= data_ram; 72 | end 73 | end 74 | 75 | always @ (posedge clk or posedge rst) 76 | begin : STATUS_COUNTER 77 | if (rst) begin 78 | status_cnt <= 0; 79 | // Read but no write. 80 | end else if ((rd_cs && rd_en) && !(wr_cs && wr_en) 81 | && (status_cnt != 0)) begin 82 | status_cnt <= status_cnt - 1; 83 | // Write but no read. 84 | end else if ((wr_cs && wr_en) && !(rd_cs && rd_en) 85 | && (status_cnt != RAM_DEPTH)) begin 86 | status_cnt <= status_cnt + 1; 87 | end 88 | end 89 | 90 | ram_dp_ar_aw #(DATA_WIDTH,ADDR_WIDTH)DP_RAM ( 91 | .address_0 (wr_pointer) , // address_0 input 92 | .data_0 (data_in) , // data_0 bi-directional 93 | .cs_0 (wr_cs) , // chip select 94 | .we_0 (wr_en) , // write enable 95 | .oe_0 (1'b0) , // output enable 96 | .address_1 (rd_pointer) , // address_q input 97 | .data_1 (data_ram) , // data_1 bi-directional 98 | .cs_1 (rd_cs) , // chip select 99 | .we_1 (1'b0) , // Read enable 100 | .oe_1 (rd_en) // output enable 101 | ); 102 | 103 | endmodule 104 | -------------------------------------------------------------------------------- /netlist/Language/Netlist/Util.hs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | -- | 3 | -- Module : Language.Netlist.Util 4 | -- Copyright : (c) Signali Corp. 2010 5 | -- License : All rights reserved 6 | -- 7 | -- Maintainer : pweaver@signalicorp.com 8 | -- Stability : experimental 9 | -- Portability : non-portable 10 | -- 11 | -- Utility functions for constructing Netlist AST elements. 12 | -------------------------------------------------------------------------------- 13 | 14 | module Language.Netlist.Util where 15 | 16 | import Language.Netlist.AST 17 | 18 | -- ----------------------------------------------------------------------------- 19 | 20 | data Direction = Up | Down 21 | 22 | unsizedInteger :: Integer -> Expr 23 | unsizedInteger = unsizedIntegral 24 | 25 | unsizedIntegral :: Integral a => a -> Expr 26 | unsizedIntegral = ExprLit Nothing . ExprNum . toInteger 27 | 28 | sizedInteger :: Int -> Integer -> Expr 29 | sizedInteger = sizedIntegral 30 | 31 | sizedIntegral :: Integral a => Int -> a -> Expr 32 | sizedIntegral sz = ExprLit (Just sz) . ExprNum . toInteger 33 | 34 | -- | Given a direction and size, maybe generate a 'Range', where a size of 1 35 | -- yields 'Nothing'. 36 | makeRange :: Direction -> Size -> Maybe Range 37 | makeRange _ 1 = Nothing 38 | makeRange d sz 39 | | sz > 1 40 | = let upper = unsizedIntegral (sz - 1) 41 | lower = unsizedInteger 0 42 | in Just $ case d of 43 | Up -> Range lower upper 44 | Down -> Range upper lower 45 | 46 | | otherwise 47 | = error ("makeRange: invalid size: " ++ show sz) 48 | 49 | -- | Concatenate a list of expressions, unless there is just one expression. 50 | exprConcat :: [Expr] -> Expr 51 | exprConcat [e] = e 52 | exprConcat es = ExprConcat es 53 | 54 | -- | Make a 'Seq' statement from a list of statements, unless there is just one 55 | -- statement. 56 | statements :: [Stmt] -> Stmt 57 | statements [x] = x 58 | statements xs = Seq xs 59 | 60 | -- ----------------------------------------------------------------------------- 61 | 62 | -- | generate a process declaration for a generic register based on the following: 63 | -- 64 | -- * the register name (as an expression) 65 | -- 66 | -- * clock expression 67 | -- 68 | -- * width of the register 69 | -- 70 | -- * optional asynchronous reset and initial value 71 | -- 72 | -- * optional clock enable 73 | -- 74 | -- * optional synchronous restart and initial value 75 | -- 76 | -- * optional load enable 77 | -- 78 | -- * when enabled, the expression to assign to the identifier 79 | -- 80 | -- You can implement a shift register by passing in a concatenation for the 81 | -- register expression and the input expression, though that is not compatible 82 | -- with VHDL. 83 | -- 84 | 85 | -- TODO 86 | -- * support negative-edge triggered clock/reset, active-low reset/restart 87 | -- * support true clock enable (as opposed to load enable)? 88 | 89 | generateReg :: Expr -> Expr -> Maybe (Expr, Expr) -> Maybe (Expr, Expr) -> 90 | Maybe Expr -> Expr -> Decl 91 | generateReg x clk mb_reset mb_restart mb_enable expr 92 | = ProcessDecl (Event clk PosEdge) mb_reset' stmt2 93 | where 94 | mb_reset' = case mb_reset of 95 | Just (reset, initial) -> Just (Event reset PosEdge, Assign x initial) 96 | Nothing -> Nothing 97 | 98 | stmt2 = case mb_restart of 99 | Just (restart, initial) 100 | -> If restart (Assign x initial) (Just stmt1) 101 | Nothing 102 | -> stmt1 103 | 104 | stmt1 = case mb_enable of 105 | Just enable -> If enable stmt0 Nothing 106 | Nothing -> stmt0 107 | 108 | stmt0 = Assign x expr 109 | 110 | -- ----------------------------------------------------------------------------- 111 | -------------------------------------------------------------------------------- /verilog/examples/arbiter.v: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------- 2 | // A four level, round-robin arbiter. This was 3 | // orginally coded by WD Peterson in VHDL. 4 | //---------------------------------------------------- 5 | module arbiter ( 6 | clk, 7 | rst, 8 | req3, 9 | req2, 10 | req1, 11 | req0, 12 | gnt3, 13 | gnt2, 14 | gnt1, 15 | gnt0 16 | ); 17 | // --------------Port Declaration----------------------- 18 | input clk; 19 | input rst; 20 | input req3; 21 | input req2; 22 | input req1; 23 | input req0; 24 | output gnt3; 25 | output gnt2; 26 | output gnt1; 27 | output gnt0; 28 | 29 | //--------------Internal Registers---------------------- 30 | wire [1:0] gnt ; 31 | wire comreq ; 32 | wire beg ; 33 | wire [1:0] lgnt ; 34 | wire lcomreq ; 35 | reg lgnt0 ; 36 | reg lgnt1 ; 37 | reg lgnt2 ; 38 | reg lgnt3 ; 39 | reg lasmask ; 40 | reg lmask0 ; 41 | reg lmask1 ; 42 | reg ledge ; 43 | 44 | //--------------Code Starts Here----------------------- 45 | always @ (posedge clk) 46 | if (rst) begin 47 | lgnt0 <= 0; 48 | lgnt1 <= 0; 49 | lgnt2 <= 0; 50 | lgnt3 <= 0; 51 | end else begin 52 | lgnt0 <=(~lcomreq & ~lmask1 & ~lmask0 & ~req3 & ~req2 & ~req1 & req0) 53 | | (~lcomreq & ~lmask1 & lmask0 & ~req3 & ~req2 & req0) 54 | | (~lcomreq & lmask1 & ~lmask0 & ~req3 & req0) 55 | | (~lcomreq & lmask1 & lmask0 & req0 ) 56 | | ( lcomreq & lgnt0 ); 57 | lgnt1 <=(~lcomreq & ~lmask1 & ~lmask0 & req1) 58 | | (~lcomreq & ~lmask1 & lmask0 & ~req3 & ~req2 & req1 & ~req0) 59 | | (~lcomreq & lmask1 & ~lmask0 & ~req3 & req1 & ~req0) 60 | | (~lcomreq & lmask1 & lmask0 & req1 & ~req0) 61 | | ( lcomreq & lgnt1); 62 | lgnt2 <=(~lcomreq & ~lmask1 & ~lmask0 & req2 & ~req1) 63 | | (~lcomreq & ~lmask1 & lmask0 & req2) 64 | | (~lcomreq & lmask1 & ~lmask0 & ~req3 & req2 & ~req1 & ~req0) 65 | | (~lcomreq & lmask1 & lmask0 & req2 & ~req1 & ~req0) 66 | | ( lcomreq & lgnt2); 67 | lgnt3 <=(~lcomreq & ~lmask1 & ~lmask0 & req3 & ~req2 & ~req1) 68 | | (~lcomreq & ~lmask1 & lmask0 & req3 & ~req2) 69 | | (~lcomreq & lmask1 & ~lmask0 & req3) 70 | | (~lcomreq & lmask1 & lmask0 & req3 & ~req2 & ~req1 & ~req0) 71 | | ( lcomreq & lgnt3); 72 | end 73 | 74 | //---------------------------------------------------- 75 | // lasmask state machine. 76 | //---------------------------------------------------- 77 | assign beg = (req3 | req2 | req1 | req0) & ~lcomreq; 78 | always @ (posedge clk) 79 | begin 80 | lasmask <= (beg & ~ledge & ~lasmask); 81 | ledge <= (beg & ~ledge & lasmask) 82 | | (beg & ledge & ~lasmask); 83 | end 84 | 85 | //---------------------------------------------------- 86 | // comreq logic. 87 | //---------------------------------------------------- 88 | assign lcomreq = ( req3 & lgnt3 ) 89 | | ( req2 & lgnt2 ) 90 | | ( req1 & lgnt1 ) 91 | | ( req0 & lgnt0 ); 92 | 93 | //---------------------------------------------------- 94 | // Encoder logic. 95 | //---------------------------------------------------- 96 | assign lgnt = {(lgnt3 | lgnt2),(lgnt3 | lgnt1)}; 97 | 98 | //---------------------------------------------------- 99 | // lmask register. 100 | //---------------------------------------------------- 101 | always @ (posedge clk ) 102 | if( rst ) begin 103 | lmask1 <= 0; 104 | lmask0 <= 0; 105 | end else if(lasmask) begin 106 | lmask1 <= lgnt[1]; 107 | lmask0 <= lgnt[0]; 108 | end else begin 109 | lmask1 <= lmask1; 110 | lmask0 <= lmask0; 111 | end 112 | 113 | assign comreq = lcomreq; 114 | assign gnt = lgnt; 115 | //---------------------------------------------------- 116 | // Drive the outputs 117 | //---------------------------------------------------- 118 | assign gnt3 = lgnt3; 119 | assign gnt2 = lgnt2; 120 | assign gnt1 = lgnt1; 121 | assign gnt0 = lgnt0; 122 | 123 | endmodule 124 | -------------------------------------------------------------------------------- /verilog/examples/uart.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------- 2 | // Design Name : uart 3 | // File Name : uart.v 4 | // Function : Simple UART 5 | // Coder : Deepak Kumar Tala 6 | //----------------------------------------------------- 7 | module uart ( 8 | reset , 9 | txclk , 10 | ld_tx_data , 11 | tx_data , 12 | tx_enable , 13 | tx_out , 14 | tx_empty , 15 | rxclk , 16 | uld_rx_data , 17 | rx_data , 18 | rx_enable , 19 | rx_in , 20 | rx_empty 21 | ); 22 | // Port declarations 23 | input reset ; 24 | input txclk ; 25 | input ld_tx_data ; 26 | input [7:0] tx_data ; 27 | input tx_enable ; 28 | output tx_out ; 29 | output tx_empty ; 30 | input rxclk ; 31 | input uld_rx_data ; 32 | output [7:0] rx_data ; 33 | input rx_enable ; 34 | input rx_in ; 35 | output rx_empty ; 36 | 37 | // Internal Variables 38 | reg [7:0] tx_reg ; 39 | reg tx_empty ; 40 | reg tx_over_run ; 41 | reg [3:0] tx_cnt ; 42 | reg tx_out ; 43 | reg [7:0] rx_reg ; 44 | reg [7:0] rx_data ; 45 | reg [3:0] rx_sample_cnt ; 46 | reg [3:0] rx_cnt ; 47 | reg rx_frame_err ; 48 | reg rx_over_run ; 49 | reg rx_empty ; 50 | reg rx_d1 ; 51 | reg rx_d2 ; 52 | reg rx_busy ; 53 | 54 | // UART RX Logic 55 | always @ (posedge rxclk or posedge reset) 56 | if (reset) begin 57 | rx_reg <= 0; 58 | rx_data <= 0; 59 | rx_sample_cnt <= 0; 60 | rx_cnt <= 0; 61 | rx_frame_err <= 0; 62 | rx_over_run <= 0; 63 | rx_empty <= 1; 64 | rx_d1 <= 1; 65 | rx_d2 <= 1; 66 | rx_busy <= 0; 67 | end else begin 68 | // Synchronize the asynch signal 69 | rx_d1 <= rx_in; 70 | rx_d2 <= rx_d1; 71 | // Uload the rx data 72 | if (uld_rx_data) begin 73 | rx_data <= rx_reg; 74 | rx_empty <= 1; 75 | end 76 | // Receive data only when rx is enabled 77 | if (rx_enable) begin 78 | // Check if just received start of frame 79 | if (!rx_busy && !rx_d2) begin 80 | rx_busy <= 1; 81 | rx_sample_cnt <= 1; 82 | rx_cnt <= 0; 83 | end 84 | // Start of frame detected, Proceed with rest of data 85 | if (rx_busy) begin 86 | rx_sample_cnt <= rx_sample_cnt + 1; 87 | // Logic to sample at middle of data 88 | if (rx_sample_cnt == 7) begin 89 | if ((rx_d2 == 1) && (rx_cnt == 0)) begin 90 | rx_busy <= 0; 91 | end else begin 92 | rx_cnt <= rx_cnt + 1; 93 | // Start storing the rx data 94 | if (rx_cnt > 0 && rx_cnt < 9) begin 95 | rx_reg[rx_cnt - 1] <= rx_d2; 96 | end 97 | if (rx_cnt == 9) begin 98 | rx_busy <= 0; 99 | // Check if End of frame received correctly 100 | if (rx_d2 == 0) begin 101 | rx_frame_err <= 1; 102 | end else begin 103 | rx_empty <= 0; 104 | rx_frame_err <= 0; 105 | // Check if last rx data was not unloaded, 106 | rx_over_run <= (rx_empty) ? 0 : 1; 107 | end 108 | end 109 | end 110 | end 111 | end 112 | end 113 | if (!rx_enable) begin 114 | rx_busy <= 0; 115 | end 116 | end 117 | 118 | // UART TX Logic 119 | always @ (posedge txclk or posedge reset) 120 | if (reset) begin 121 | tx_reg <= 0; 122 | tx_empty <= 1; 123 | tx_over_run <= 0; 124 | tx_out <= 1; 125 | tx_cnt <= 0; 126 | end else begin 127 | if (ld_tx_data) begin 128 | if (!tx_empty) begin 129 | tx_over_run <= 0; 130 | end else begin 131 | tx_reg <= tx_data; 132 | tx_empty <= 0; 133 | end 134 | end 135 | if (tx_enable && !tx_empty) begin 136 | tx_cnt <= tx_cnt + 1; 137 | if (tx_cnt == 0) begin 138 | tx_out <= 0; 139 | end 140 | if (tx_cnt > 0 && tx_cnt < 9) begin 141 | tx_out <= tx_reg[tx_cnt -1]; 142 | end 143 | if (tx_cnt == 9) begin 144 | tx_out <= 1; 145 | tx_cnt <= 0; 146 | tx_empty <= 1; 147 | end 148 | end 149 | if (!tx_enable) begin 150 | tx_cnt <= 0; 151 | end 152 | end 153 | 154 | endmodule 155 | -------------------------------------------------------------------------------- /verilog/examples/aFifo.v: -------------------------------------------------------------------------------- 1 | //========================================== 2 | // Function : Asynchronous FIFO (w/ 2 asynchronous clocks). 3 | // Coder : Alex Claros F. 4 | // Date : 15/May/2005. 5 | // Notes : This implementation is based on the article 6 | // 'Asynchronous FIFO in Virtex-II FPGAs' 7 | // writen by Peter Alfke. This TechXclusive 8 | // article can be downloaded from the 9 | // Xilinx website. It has some minor modifications. 10 | //========================================= 11 | 12 | `timescale 1ns/1ps 13 | 14 | module aFifo 15 | #(parameter DATA_WIDTH = 8, 16 | ADDRESS_WIDTH = 4, 17 | FIFO_DEPTH = (1 << ADDRESS_WIDTH)) 18 | //Reading port 19 | (output reg [DATA_WIDTH-1:0] Data_out, 20 | output reg Empty_out, 21 | input wire ReadEn_in, 22 | input wire RClk, 23 | //Writing port. 24 | input wire [DATA_WIDTH-1:0] Data_in, 25 | output reg Full_out, 26 | input wire WriteEn_in, 27 | input wire WClk, 28 | 29 | input wire Clear_in); 30 | 31 | /////Internal connections & variables////// 32 | reg [DATA_WIDTH-1:0] Mem [FIFO_DEPTH-1:0]; 33 | wire [ADDRESS_WIDTH-1:0] pNextWordToWrite, pNextWordToRead; 34 | wire EqualAddresses; 35 | wire NextWriteAddressEn, NextReadAddressEn; 36 | wire Set_Status, Rst_Status; 37 | reg Status; 38 | wire PresetFull, PresetEmpty; 39 | 40 | //////////////Code/////////////// 41 | //Data ports logic: 42 | //(Uses a dual-port RAM). 43 | //'Data_out' logic: 44 | always @ (posedge RClk) 45 | if (ReadEn_in & !Empty_out) 46 | Data_out <= Mem[pNextWordToRead]; 47 | 48 | //'Data_in' logic: 49 | always @ (posedge WClk) 50 | if (WriteEn_in & !Full_out) 51 | Mem[pNextWordToWrite] <= Data_in; 52 | 53 | //Fifo addresses support logic: 54 | //'Next Addresses' enable logic: 55 | assign NextWriteAddressEn = WriteEn_in & ~Full_out; 56 | assign NextReadAddressEn = ReadEn_in & ~Empty_out; 57 | 58 | //Addreses (Gray counters) logic: 59 | GrayCounter GrayCounter_pWr 60 | (.GrayCount_out(pNextWordToWrite), 61 | 62 | .Enable_in(NextWriteAddressEn), 63 | .Clear_in(Clear_in), 64 | 65 | .Clk(WClk) 66 | ); 67 | 68 | GrayCounter GrayCounter_pRd 69 | (.GrayCount_out(pNextWordToRead), 70 | .Enable_in(NextReadAddressEn), 71 | .Clear_in(Clear_in), 72 | .Clk(RClk) 73 | ); 74 | 75 | 76 | //'EqualAddresses' logic: 77 | assign EqualAddresses = (pNextWordToWrite == pNextWordToRead); 78 | 79 | //'Quadrant selectors' logic: 80 | assign Set_Status = (pNextWordToWrite[ADDRESS_WIDTH-2] ~^ pNextWordToRead[ADDRESS_WIDTH-1]) & 81 | (pNextWordToWrite[ADDRESS_WIDTH-1] ^ pNextWordToRead[ADDRESS_WIDTH-2]); 82 | 83 | assign Rst_Status = (pNextWordToWrite[ADDRESS_WIDTH-2] ^ pNextWordToRead[ADDRESS_WIDTH-1]) & 84 | (pNextWordToWrite[ADDRESS_WIDTH-1] ~^ pNextWordToRead[ADDRESS_WIDTH-2]); 85 | 86 | //'Status' latch logic: 87 | always @ (Set_Status, Rst_Status, Clear_in) //D Latch w/ Asynchronous Clear & Preset. 88 | if (Rst_Status | Clear_in) 89 | Status = 0; //Going 'Empty'. 90 | else if (Set_Status) 91 | Status = 1; //Going 'Full'. 92 | 93 | //'Full_out' logic for the writing port: 94 | assign PresetFull = Status & EqualAddresses; //'Full' Fifo. 95 | 96 | always @ (posedge WClk, posedge PresetFull) //D Flip-Flop w/ Asynchronous Preset. 97 | if (PresetFull) 98 | Full_out <= 1; 99 | else 100 | Full_out <= 0; 101 | 102 | //'Empty_out' logic for the reading port: 103 | assign PresetEmpty = ~Status & EqualAddresses; //'Empty' Fifo. 104 | 105 | always @ (posedge RClk, posedge PresetEmpty) //D Flip-Flop w/ Asynchronous Preset. 106 | if (PresetEmpty) 107 | Empty_out <= 1; 108 | else 109 | Empty_out <= 0; 110 | 111 | endmodule 112 | -------------------------------------------------------------------------------- /netlist/Language/Netlist/Inline.hs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | -- | 3 | -- Module : Language.Netlist.Inline 4 | -- Copyright : (c) Signali Corp. 2010 5 | -- License : All rights reserved 6 | -- 7 | -- Maintainer : pweaver@signalicorp.com 8 | -- Stability : experimental 9 | -- Portability : non-portable 10 | -- 11 | -- A simple inliner for a Netlist AST ('Language.Netlist.AST'). 12 | -------------------------------------------------------------------------------- 13 | 14 | {-# LANGUAGE Rank2Types, PatternGuards #-} 15 | 16 | module Language.Netlist.Inline ( inlineModule ) where 17 | 18 | import Data.Generics 19 | --import Data.List 20 | import Data.Maybe 21 | import Data.Map (Map) 22 | import qualified Data.Map as Map 23 | 24 | import Language.Netlist.AST 25 | 26 | -- ----------------------------------------------------------------------------- 27 | 28 | -- | Produce a new module in which some variables have been inlined. An 29 | -- expression is inlined (and it\'s declaration removed) if it only used in one 30 | -- place in the entire module. 31 | inlineModule :: Module -> Module 32 | inlineModule (Module name inputs outputs statics decls) 33 | = Module name inputs outputs statics decls'' 34 | where 35 | deps = getIdentExprs decls 36 | bs = getBindings decls 37 | bs' = Map.filterWithKey (shouldInline (map fst outputs) deps) bs 38 | decls' = replaceExprs bs' decls 39 | decls'' = removeDecls (Map.keys bs') decls' 40 | 41 | -- given a list of identifier-to-expression bindings, replace the identifiers 42 | -- everywhere in an AST. Note: "everywhere" applies bottom-up. We want 43 | -- everywhere', which is top-down. 44 | replaceExprs :: forall a. (Data a) => Map Ident Expr -> a -> a 45 | replaceExprs bs a = everywhere' (mkT f) a 46 | where 47 | f e 48 | | ExprVar x <- e, Just e' <- Map.lookup x bs 49 | = e' -- replaceExprs bs e' 50 | | otherwise = e 51 | 52 | -- this is essentially a DCE pass. it removes the declarations that have been inlined. 53 | removeDecls :: [Ident] -> [Decl] -> [Decl] 54 | removeDecls xs = mapMaybe f 55 | where 56 | f d@(NetDecl x _ _) 57 | = if elem x xs then Nothing else Just d 58 | f d@(NetAssign x _) 59 | = if elem x xs then Nothing else Just d 60 | f decl 61 | = Just decl 62 | 63 | -- ----------------------------------------------------------------------------- 64 | -- utility functions 65 | 66 | getBindings :: [Decl] -> Map Ident Expr 67 | getBindings = Map.unions . map getDeclBinding 68 | 69 | getDeclBinding :: Decl -> Map Ident Expr 70 | getDeclBinding (NetDecl x _ (Just expr)) 71 | = Map.singleton x expr 72 | getDeclBinding (NetAssign x expr) 73 | = Map.singleton x expr 74 | getDeclBinding _ 75 | = Map.empty 76 | 77 | shouldInline :: [Ident] -> Map Ident [Expr] -> Ident -> Expr -> Bool 78 | shouldInline ignore deps x e 79 | | x `notElem` ignore, Just n <- checkUsers 80 | = case e of 81 | -- always inline trivial expressions regardless of the number of users. 82 | ExprLit _ _ -> True 83 | ExprString _ -> True 84 | ExprVar _ -> True 85 | ExprIndex _ _ -> True 86 | ExprSlice _ _ _ -> True 87 | -- ExprSliceOff _ _ _ -> True 88 | 89 | -- never inline case expressions. as far as we know, there's no case 90 | -- /expression/ in Verilog. we leave ExprCase alone here so that it may 91 | -- be easier to translate to, for example, a case /statement/ in a 92 | -- combinational process in HDL. 93 | ExprCase {} -> False 94 | 95 | -- any complex expressions should only be inlined if they're used once. 96 | _ -> n == 1 97 | 98 | | otherwise 99 | = False 100 | where 101 | -- returns Nothing if this identifier cannot be inlined because it is 102 | -- referred to by a Index/Project/FuncCall. returns Just n if the only 103 | -- users are 'n' number of ExprVar expressions. 104 | checkUsers 105 | = if all checkUser zs then Just (length zs) else Nothing 106 | where 107 | zs = fromMaybe [] (Map.lookup x deps) 108 | checkUser (ExprVar _) = True 109 | checkUser _ = False 110 | 111 | -- map each identifier to every expression that directly refers to that identifier. 112 | getIdentExprs :: forall a. (Data a) => a -> Map Ident [Expr] 113 | getIdentExprs a = f Map.empty (getAll a) 114 | where 115 | f :: Map Ident [Expr] -> [Expr] -> Map Ident [Expr] 116 | f m [] = m 117 | f m (expr:rest) 118 | = f m' rest 119 | where m' = case maybeExprIdent expr of 120 | Just v -> Map.insertWith (++) v [expr] m 121 | Nothing -> m 122 | 123 | -- generically get a list of all terms of a certain type. 124 | getAll :: forall a b. (Data a, Typeable b) => a -> [b] 125 | getAll = listify (\_ -> True) 126 | 127 | -- if an expression references an identifier directly, return the identifier. 128 | -- note that subexpressions are not counted here! 129 | maybeExprIdent :: Expr -> Maybe Ident 130 | maybeExprIdent (ExprVar x) = Just x 131 | maybeExprIdent (ExprIndex x _) = Just x 132 | maybeExprIdent (ExprSlice x _ _) = Just x 133 | maybeExprIdent (ExprSliceOff x _ _) = Just x 134 | maybeExprIdent (ExprFunCall x _) = Just x 135 | maybeExprIdent _ = Nothing 136 | 137 | -- ----------------------------------------------------------------------------- 138 | -------------------------------------------------------------------------------- /netlist-to-verilog/Language/Netlist/GenVerilog.hs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | -- | 3 | -- Module : Language.Netlist.GenVerilog 4 | -- Copyright : (c) Signali Corp. 2010 5 | -- License : All rights reserved 6 | -- 7 | -- Maintainer : pweaver@signalicorp.com 8 | -- Stability : experimental 9 | -- Portability : non-portable (DeriveDataTypeable) 10 | -- 11 | -- Translate a Netlist AST into a Verilog AST. 12 | -- 13 | -- The @netlist@ package defines the Netlist AST and the @verilog@ package 14 | -- defines the Verilog AST. 15 | -- 16 | -- Not every Netlist AST is compatible with Verilog. For example, the Netlist 17 | -- AST permits left- and right-rotate operators, which are not supported in 18 | -- Verilog. 19 | -------------------------------------------------------------------------------- 20 | {-# LANGUAGE ViewPatterns #-} 21 | 22 | -- TODO: endianness - currently we're hardcoded to little endian verilog 23 | 24 | module Language.Netlist.GenVerilog ( mk_module 25 | , mk_decl 26 | , mk_stmt 27 | , mk_expr 28 | ) where 29 | 30 | import Numeric ( showIntAtBase ) 31 | 32 | import Language.Netlist.AST 33 | import qualified Language.Verilog.Syntax as V 34 | 35 | -- ----------------------------------------------------------------------------- 36 | 37 | mk_module :: Module -> V.Module 38 | mk_module (Module name ins outs statics decls) 39 | = V.Module (mk_ident name) ports items 40 | where 41 | params= [ V.ParamDeclItem (V.ParamDecl [V.ParamAssign (mk_ident x) (mk_expr expr)]) 42 | | (x, expr) <- statics 43 | ] 44 | ports = map (mk_ident . fst) ins ++ map (mk_ident . fst) outs 45 | items = [ V.InputDeclItem (V.InputDecl (fmap mk_range mb_range) [mk_ident x]) 46 | | (x, mb_range) <- ins ] ++ 47 | 48 | [ V.OutputDeclItem (V.OutputDecl (fmap mk_range mb_range) [mk_ident x]) 49 | | (x, mb_range) <- outs ] ++ 50 | 51 | params ++ 52 | concatMap mk_decl decls 53 | 54 | 55 | mk_decl :: Decl -> [V.Item] 56 | mk_decl (NetDecl x mb_range mb_expr) 57 | = [V.NetDeclItem decl] 58 | where 59 | mb_range' = fmap (V.SimpleRange . mk_range) mb_range 60 | decl = case mb_expr of 61 | Nothing -> V.NetDecl V.Net_wire mb_range' Nothing [mk_ident x] 62 | Just expr -> V.NetDeclAssign V.Net_wire Nothing mb_range' Nothing 63 | [(mk_ident x, mk_expr expr)] 64 | 65 | mk_decl (NetAssign x expr) 66 | = [V.AssignItem Nothing Nothing [mkAssign x expr]] 67 | 68 | mk_decl (MemDecl x mb_range1 mb_range2) 69 | = [V.RegDeclItem (V.RegDecl V.Reg_reg (fmap mk_range mb_range2) 70 | [case mb_range1 of 71 | Nothing -> V.RegVar (mk_ident x) Nothing 72 | Just r -> V.MemVar (mk_ident x) (mk_range r) 73 | ])] 74 | 75 | mk_decl (InstDecl mod_name inst_name params inputs outputs) 76 | = [V.InstanceItem (V.Instance (mk_ident mod_name) v_params [inst])] 77 | where 78 | v_params = Right [ V.Parameter (mk_ident x) (mk_expr expr) 79 | | (x, expr) <- params ] 80 | inst = V.Inst (mk_ident inst_name) Nothing (V.NamedConnections cs) 81 | cs = [ V.NamedConnection (mk_ident x) (mk_expr expr) 82 | | (x, expr) <- inputs ++ outputs ] 83 | 84 | mk_decl (InitProcessDecl stmt) 85 | = [V.InitialItem (mk_stmt stmt)] 86 | 87 | mk_decl (CommentDecl str) 88 | = [V.CommentItem str] 89 | 90 | mk_decl (ProcessDecl (Event (mk_expr -> clk) edge) Nothing stmt) 91 | = [V.AlwaysItem (V.EventControlStmt e (Just s))] 92 | where 93 | e = V.EventControlExpr event 94 | s = V.IfStmt cond (Just (mk_stmt stmt)) Nothing 95 | 96 | (event, cond) = edge_helper edge clk 97 | 98 | mk_decl (ProcessDecl (Event (mk_expr -> clk) clk_edge) 99 | (Just (Event (mk_expr -> reset) reset_edge, reset_stmt)) stmt) 100 | = [V.AlwaysItem (V.EventControlStmt e (Just s1))] 101 | where 102 | e = V.EventControlExpr (V.EventOr clk_event reset_event) 103 | 104 | s1 = V.IfStmt reset_cond (Just (mk_stmt reset_stmt)) (Just s2) 105 | s2 = V.IfStmt clk_cond (Just (mk_stmt stmt)) Nothing 106 | 107 | (clk_event, clk_cond) = edge_helper clk_edge clk 108 | (reset_event, reset_cond) = edge_helper reset_edge reset 109 | 110 | edge_helper :: Edge -> V.Expression -> (V.EventExpr, V.Expression) 111 | edge_helper PosEdge x = (V.EventPosedge x, x) 112 | edge_helper NegEdge x = (V.EventNegedge x, V.ExprUnary V.UBang x) 113 | 114 | mk_range :: Range -> V.Range 115 | mk_range (Range e1 e2) 116 | = V.Range (mk_expr e1) (mk_expr e2) 117 | 118 | mk_stmt :: Stmt -> V.Statement 119 | mk_stmt (Assign x expr) 120 | = V.NonBlockingAssignment (mk_expr x) Nothing (mk_expr expr) 121 | mk_stmt (If cond s1 mb_s2) 122 | = V.IfStmt (mk_expr cond) (Just (mk_stmt s1)) (fmap mk_stmt mb_s2) 123 | mk_stmt (Case e case_items mb_default) 124 | = V.CaseStmt V.Case (mk_expr e) $ 125 | [ V.CaseItem (map mk_expr es) (Just (mk_stmt stmt)) 126 | | (es, stmt) <- case_items ] 127 | ++ 128 | case mb_default of 129 | Just stmt -> [V.CaseDefault (Just (mk_stmt stmt))] 130 | Nothing -> [] 131 | mk_stmt (Seq stmts) 132 | = V.SeqBlock Nothing [] (map mk_stmt stmts) 133 | mk_stmt (FunCallStmt x es) 134 | | head x == '$' 135 | = V.TaskStmt (mk_ident (tail x)) (Just (map mk_expr es)) 136 | | otherwise 137 | = error ("FunCallStmt " ++ x) 138 | 139 | mk_lit :: Maybe Size -> ExprLit -> V.Number 140 | mk_lit mb_sz lit 141 | = V.IntNum Nothing (fmap show mb_sz) mb_base str 142 | -- Note that this does not truncate 'str' if its length is more than the size. 143 | where 144 | hexdigits = "0123456789abcdef" 145 | 146 | (str, mb_base) 147 | = case lit of 148 | ExprNum x 149 | -> case mb_sz of 150 | Just n 151 | | n <= 4 -> (showIntAtBase 2 (hexdigits !!) x "", Just V.BinBase) 152 | | otherwise -> (showIntAtBase 16 (hexdigits !!) x "", Just V.HexBase) 153 | Nothing -> (show x, Nothing) 154 | ExprBit b -> ([bit_char b], Nothing) 155 | ExprBitVector bs -> (map bit_char bs, Just V.BinBase) 156 | 157 | bit_char :: Bit -> Char 158 | bit_char T = '1' 159 | bit_char F = '0' 160 | bit_char U = 'x' 161 | bit_char Z = 'z' 162 | 163 | mk_expr :: Expr -> V.Expression 164 | mk_expr (ExprLit mb_size lit) 165 | = V.ExprNum $ mk_lit mb_size lit 166 | 167 | mk_expr (ExprString x) 168 | = V.ExprString x 169 | mk_expr (ExprVar x) 170 | = expr_var x 171 | mk_expr (ExprIndex x e) 172 | = V.ExprIndex (mk_ident x) (mk_expr e) 173 | mk_expr (ExprSlice x e1 e2) 174 | = V.ExprSlice (mk_ident x) (mk_expr e1) (mk_expr e2) 175 | mk_expr (ExprSliceOff x e i) 176 | = f (mk_ident x) (mk_expr e) (V.intExpr (abs i)) 177 | where 178 | f = if i < 0 then V.ExprSliceMinus else V.ExprSlicePlus 179 | mk_expr (ExprConcat exprs) 180 | = V.ExprConcat (map mk_expr exprs) 181 | mk_expr (ExprUnary op expr) 182 | = V.ExprUnary (unary_op op) (mk_expr expr) 183 | mk_expr (ExprBinary op expr1 expr2) 184 | = V.ExprBinary (binary_op op) (mk_expr expr1) (mk_expr expr2) 185 | mk_expr (ExprCond expr1 expr2 expr3) 186 | = V.ExprCond (mk_expr expr1) (mk_expr expr2) (mk_expr expr3) 187 | mk_expr (ExprFunCall x es) 188 | = V.ExprFunCall (mk_ident x) (map mk_expr es) 189 | 190 | mk_expr ExprCase{} 191 | = error "GenVerilog: Not yet supported: ExprCase" 192 | 193 | mk_ident :: Ident -> V.Ident 194 | mk_ident x = V.Ident x 195 | 196 | expr_var :: Ident -> V.Expression 197 | expr_var x = V.ExprVar (mk_ident x) 198 | 199 | mkAssign :: Ident -> Expr -> V.Assignment 200 | mkAssign ident expr 201 | = V.Assignment (expr_var ident) (mk_expr expr) 202 | 203 | unary_op :: UnaryOp -> V.UnaryOp 204 | unary_op UPlus = V.UPlus 205 | unary_op UMinus = V.UMinus 206 | unary_op LNeg = V.UBang 207 | unary_op Neg = V.UTilde 208 | unary_op UAnd = V.UAnd 209 | unary_op UNand = V.UNand 210 | unary_op UOr = V.UOr 211 | unary_op UNor = V.UNor 212 | unary_op UXor = V.UXor 213 | unary_op UXnor = V.UXnor 214 | 215 | binary_op :: BinaryOp -> V.BinaryOp 216 | binary_op Pow = V.Pow 217 | binary_op Plus = V.Plus 218 | binary_op Minus = V.Minus 219 | binary_op Times = V.Times 220 | binary_op Divide = V.Divide 221 | binary_op Modulo = V.Modulo 222 | binary_op Equals = V.Equals 223 | binary_op NotEquals = V.NotEquals 224 | binary_op CEquals = V.CEquals 225 | binary_op CNotEquals = V.CNotEquals 226 | binary_op LAnd = V.LAnd 227 | binary_op LOr = V.LOr 228 | binary_op LessThan = V.LessThan 229 | binary_op LessEqual = V.LessEqual 230 | binary_op GreaterThan = V.GreaterThan 231 | binary_op GreaterEqual = V.GreaterEqual 232 | binary_op And = V.And 233 | binary_op Nand = V.Nand 234 | binary_op Or = V.Or 235 | binary_op Nor = V.Nor 236 | binary_op Xor = V.Xor 237 | binary_op Xnor = V.Xnor 238 | binary_op ShiftLeft = V.ShiftLeft 239 | binary_op ShiftRight = V.ShiftRight 240 | binary_op RotateLeft = error "GenVerilog: no left-rotate operator in Verilog" 241 | binary_op RotateRight = error "GenVerilog: no right-rotate operator in Verilog" 242 | 243 | -- ----------------------------------------------------------------------------- 244 | -------------------------------------------------------------------------------- /netlist-to-vhdl/Language/Netlist/GenVHDL.hs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | -- | 3 | -- Module : Language.Netlist.GenVHDL 4 | -- Copyright : (c) University of Kansas 2010 5 | -- License : All rights reserved 6 | -- 7 | -- Maintainer : garrin.kimmell@gmail.com 8 | -- Stability : experimental 9 | -- Portability : non-portable 10 | -- 11 | -- Translates a Netlist AST ('Language.Netlist.AST') to VHDL. 12 | -------------------------------------------------------------------------------- 13 | 14 | module Language.Netlist.GenVHDL(genVHDL) where 15 | 16 | import Language.Netlist.AST 17 | 18 | import Text.PrettyPrint 19 | import Data.Maybe(catMaybes) 20 | 21 | 22 | -- | Generate a 'Language.Netlist.AST.Module' as a VHDL file . The ['String'] argument 23 | -- is the list of extra modules to import, typically [\"work.all\"]. 24 | genVHDL :: Module -> [String] -> String 25 | genVHDL m others = render vhdl ++ "\n" 26 | where 27 | vhdl = imports others $$ 28 | entity m $$ 29 | architecture m 30 | 31 | imports :: [String] -> Doc 32 | imports others = vcat 33 | [ text "library IEEE" <> semi 34 | , text "use IEEE.STD_LOGIC_1164.ALL" <> semi 35 | , text "use IEEE.NUMERIC_STD.ALL" <> semi 36 | ] $$ vcat [ 37 | text ("use " ++ other) <> semi 38 | | other <- others 39 | ] 40 | 41 | 42 | entity :: Module -> Doc 43 | entity m = text "entity" <+> text (module_name m) <+> text "is" $$ 44 | nest 2 (text "port" <> parens (vcat $ punctuate semi ports) <> semi) $$ 45 | text "end" <+> text "entity" <+> text (module_name m) <> semi 46 | 47 | where ports = [text i <+> colon <+> text "in" <+> slv_type ran | (i,ran) <- module_inputs m ] ++ 48 | [text i <+> colon <+> text "out" <+> slv_type ran | (i,ran) <- module_outputs m ] 49 | 50 | 51 | architecture :: Module -> Doc 52 | architecture m = text "architecture" <+> text "str" <+> text "of" <+> text (module_name m) <+> text "is" $$ 53 | nest 2 (decls (module_decls m)) $$ 54 | text "begin" $$ 55 | nest 2 (insts (module_decls m)) $$ 56 | text "end" <+> text "architecture" <+> text "str" <> semi 57 | 58 | decls :: [Decl] -> Doc 59 | decls [] = empty 60 | decls ds = (vcat $ punctuate semi $ catMaybes $ map decl ds) <> semi 61 | 62 | decl :: Decl -> Maybe Doc 63 | decl (NetDecl i r Nothing) = Just $ 64 | text "signal" <+> text i <+> colon <+> slv_type r 65 | 66 | decl (NetDecl i r (Just init)) = Just $ 67 | text "signal" <+> text i <+> colon <+> slv_type r <+> text ":=" <+> expr init 68 | 69 | decl (MemDecl i Nothing dsize) = Just $ 70 | text "signal" <+> text i <+> colon <+> slv_type dsize 71 | 72 | decl (MemDecl i (Just asize) dsize) = Just $ 73 | text "type" <+> mtype <+> text "is" <+> 74 | text "array" <+> range asize <+> text "of" <+> slv_type dsize <> semi $$ 75 | text "signal" <+> text i <> text "_ram" <+> colon <+> mtype 76 | where mtype = text i <> text "_memory_type" 77 | 78 | decl _d = Nothing 79 | 80 | insts :: [Decl] -> Doc 81 | insts [] = empty 82 | insts is = case catMaybes $ zipWith inst gensyms is of 83 | [] -> empty 84 | is' -> (vcat $ punctuate semi is') <> semi 85 | where gensyms = ["proc" ++ show i | i <- [(0::Integer)..]] 86 | 87 | inst :: String -> Decl -> Maybe Doc 88 | inst _ (NetAssign i e) = Just $ text i <+> text "<=" <+> expr e 89 | 90 | inst gensym (ProcessDecl (Event clk edge) Nothing s) = Just $ 91 | text gensym <+> colon <+> text "process" <> senlist <+> text "is" $$ 92 | text "begin" $$ 93 | nest 2 (text "if" <+> nest 2 event <+> text "then" $$ 94 | nest 2 (stmt s) $$ 95 | text "end if" <> semi) $$ 96 | text "end process" <+> text gensym 97 | where 98 | senlist = parens $ expr clk 99 | event = case edge of 100 | PosEdge -> text "rising_edge" <> parens (expr clk) 101 | NegEdge -> text "falling_edge" <> parens (expr clk) 102 | 103 | inst gensym (ProcessDecl (Event clk clk_edge) 104 | (Just (Event reset reset_edge, reset_stmt)) s) = Just $ 105 | text gensym <+> colon <+> text "process" <> senlist <+> text "is" $$ 106 | text "begin" $$ 107 | nest 2 (text "if" <+> nest 2 reset_event <+> text "then" $$ 108 | nest 2 (stmt reset_stmt) $$ 109 | text "elsif" <+> nest 2 clk_event <+> text "then" $$ 110 | nest 2 (stmt s) $$ 111 | text "end if" <> semi) $$ 112 | text "end process" <+> text gensym 113 | where 114 | senlist = parens $ cat $ punctuate comma $ map expr [ clk, reset ] 115 | clk_event = case clk_edge of 116 | PosEdge -> text "rising_edge" <> parens (expr clk) 117 | NegEdge -> text "falling_edge" <> parens (expr clk) 118 | reset_event = case reset_edge of 119 | PosEdge -> expr reset <+> text "= '1'" 120 | NegEdge -> expr reset <+> text "= '0'" 121 | 122 | 123 | inst _ (InstDecl nm inst gens ins outs) = Just $ 124 | text inst <+> colon <+> text "entity" <+> text nm $$ 125 | gs $$ 126 | ps 127 | where 128 | gs | null gens = empty 129 | | otherwise = 130 | text "generic map" <+> 131 | (parens (cat (punctuate comma [text i <+> text "=>" <+> expr e | (i,e) <- gens]))) 132 | -- Assume that ports is never null 133 | ps = text "port map" <+> 134 | parens (cat (punctuate comma [text i <+> text "=>" <+> expr e | (i,e) <- (ins ++ outs)])) 135 | 136 | 137 | inst gensym (InitProcessDecl s) = Just $ 138 | text "-- synthesis_off" $$ 139 | text gensym <+> colon <+> text "process" <> senlist <+> text "is" $$ 140 | text "begin" $$ 141 | nest 2 (stmt s) $$ 142 | text "wait" <> semi $$ 143 | text "end process" <+> text gensym $$ 144 | text "-- synthesis_on" 145 | where senlist = parens empty 146 | 147 | -- TODO: get multline working 148 | inst _ (CommentDecl msg) = Just $ 149 | (vcat [ text "--" <+> text m | m <- lines msg ]) 150 | 151 | inst _ _d = Nothing 152 | 153 | stmt :: Stmt -> Doc 154 | stmt (Assign l r) = expr l <+> text "<=" <+> expr r <> semi 155 | stmt (Seq ss) = vcat (map stmt ss) 156 | stmt (If e t Nothing) = 157 | text "if" <+> expr e <+> text "then" $$ 158 | nest 2 (stmt t) $$ 159 | text "end if" <> semi 160 | stmt (If p t (Just e)) = 161 | text "if" <+> expr p <+> text "then" $$ 162 | nest 2 (stmt t) $$ 163 | text "else" $$ 164 | nest 2 (stmt e) $$ 165 | text "end if" <> semi 166 | stmt (Case d ps def) = 167 | text "case" <+> expr d <+> text "of" $$ 168 | vcat (map mkAlt ps) $$ 169 | defDoc $$ 170 | text "end case" <> semi 171 | where defDoc = maybe empty mkDefault def 172 | mkDefault s = text "when others =>" $$ 173 | nest 2 (stmt s) 174 | mkAlt ([g],s) = text "when" <+> expr g <+> text "=>" $$ 175 | nest 2 (stmt s) 176 | 177 | 178 | to_bits :: Integral a => Int -> a -> [Bit] 179 | to_bits size val = map (\x -> if odd x then T else F) 180 | $ reverse 181 | $ take size 182 | $ map (`mod` 2) 183 | $ iterate (`div` 2) 184 | $ val 185 | 186 | bit_char :: Bit -> Char 187 | bit_char T = '1' 188 | bit_char F = '0' 189 | bit_char U = 'U' -- 'U' means uninitialized, 190 | -- 'X' means forced to unknown. 191 | -- not completely sure that 'U' is the right choice here. 192 | bit_char Z = 'Z' 193 | 194 | bits :: [Bit] -> Doc 195 | bits = doubleQuotes . text . map bit_char 196 | 197 | expr_lit :: Maybe Size -> ExprLit -> Doc 198 | expr_lit Nothing (ExprNum i) = int $ fromIntegral i 199 | expr_lit (Just sz) (ExprNum i) = bits (to_bits sz i) 200 | expr_lit _ (ExprBit x) = quotes (char (bit_char x)) 201 | -- ok to ignore the size here? 202 | expr_lit Nothing (ExprBitVector xs) = bits xs 203 | expr_lit (Just sz) (ExprBitVector xs) = bits $ take sz xs 204 | 205 | expr :: Expr -> Doc 206 | expr (ExprLit mb_sz lit) = expr_lit mb_sz lit 207 | expr (ExprVar n) = text n 208 | expr (ExprIndex s i) = text s <> parens (expr i) 209 | expr (ExprSlice s h l) 210 | | h >= l = text s <> parens (expr h <+> text "downto" <+> expr l) 211 | | otherwise = text s <> parens (expr h <+> text "to" <+> expr l) 212 | 213 | expr (ExprConcat ss) = hcat $ punctuate (text " & ") (map expr ss) 214 | expr (ExprUnary op e) = lookupUnary op (expr e) 215 | expr (ExprBinary op a b) = lookupBinary op (expr a) (expr b) 216 | expr (ExprFunCall f args) = text f <> parens (cat $ punctuate comma $ map expr args) 217 | expr (ExprCond c t e) = expr t <+> text "when" <+> expr c <+> text "else" $$ expr e 218 | expr (ExprCase _ [] Nothing) = error "VHDL does not support non-defaulted ExprCase" 219 | expr (ExprCase _ [] (Just e)) = expr e 220 | expr (ExprCase e (([],_):alts) def) = expr (ExprCase e alts def) 221 | expr (ExprCase e ((p:ps,alt):alts) def) = 222 | expr (ExprCond (ExprBinary Equals e p) alt (ExprCase e ((ps,alt):alts) def)) 223 | expr x = text (show x) 224 | 225 | 226 | lookupUnary :: UnaryOp -> Doc -> Doc 227 | lookupUnary op e = text (unOp op) <> parens e 228 | 229 | unOp :: UnaryOp -> String 230 | unOp UPlus = "" 231 | unOp UMinus = "-" 232 | unOp LNeg = "not" 233 | unOp UAnd = "and" 234 | unOp UNand = "nand" 235 | unOp UOr = "or" 236 | unOp UNor = "nor" 237 | unOp UXor = "xor" 238 | unOp UXnor = "xnor" 239 | unOp Neg = "-" 240 | 241 | 242 | -- "(\\(.*\\), text \\(.*\\))," 243 | lookupBinary :: BinaryOp -> Doc -> Doc -> Doc 244 | lookupBinary op a b = parens $ a <+> text (binOp op) <+> b 245 | 246 | binOp :: BinaryOp -> String 247 | binOp Pow = "**" 248 | binOp Plus = "+" 249 | binOp Minus = "-" 250 | binOp Times = "*" 251 | binOp Divide = "/" 252 | binOp Modulo = "mod" 253 | binOp Equals = "=" 254 | binOp NotEquals = "!=" 255 | binOp CEquals = "=" 256 | binOp CNotEquals = "!=" 257 | binOp LAnd = "and" 258 | binOp LOr = "or" 259 | binOp LessThan = "<" 260 | binOp LessEqual = "<=" 261 | binOp GreaterThan = ">" 262 | binOp GreaterEqual = ">=" 263 | binOp And = "and" 264 | binOp Nand = "nand" 265 | binOp Or = "or" 266 | binOp Nor = "nor" 267 | binOp Xor = "xor" 268 | binOp Xnor = "xnor" 269 | binOp ShiftLeft = "sll" 270 | binOp ShiftRight = "srl" 271 | binOp RotateLeft = "rol" 272 | binOp RotateRight = "ror" 273 | 274 | slv_type :: Maybe Range -> Doc 275 | slv_type Nothing = text "std_logic" 276 | slv_type (Just r) = text "std_logic_vector" <> range r 277 | 278 | range :: Range -> Doc 279 | range (Range high low) = parens (expr high <+> text "downto" <+> expr low) 280 | -------------------------------------------------------------------------------- /verilog/Language/Verilog/Syntax/Expression.hs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | -- | 3 | -- Module : Language.Verilog.Syntax.Expression 4 | -- Copyright : (c) Signali Corp. 2010 5 | -- License : All rights reserved 6 | -- 7 | -- Maintainer : pweaver@signalicorp.com 8 | -- Stability : experimental 9 | -- Portability : ghc 10 | -- 11 | -- Abstract syntax tree definitions for Verilog expressions, operators, and 12 | -- constants. 13 | -------------------------------------------------------------------------------- 14 | 15 | {-# LANGUAGE DeriveDataTypeable, TypeOperators #-} 16 | {-# OPTIONS_DERIVE --append -d Binary #-} 17 | 18 | module Language.Verilog.Syntax.Expression 19 | ( -- * Identifiers 20 | Ident(..), 21 | 22 | -- * Expressions 23 | Expression, ConstExpr, Expression'(..), ConstExpr', 24 | Number(..), Base(..), Sign(..), intExpr, 25 | 26 | -- * Unary Operators 27 | UnaryOp(..), 28 | 29 | -- * Binary Operators 30 | BinaryOp(..), 31 | ) where 32 | 33 | import Data.Generics ( Data, Typeable ) 34 | import Data.Binary ( Binary(..), putWord8, getWord8 ) 35 | import Data.Maybe ( fromMaybe ) 36 | 37 | import Language.Verilog.Syntax.Ident 38 | 39 | -------------------------------------------------------------------------------- 40 | -- expressions 41 | 42 | -- | Expressions. The AST uses 'Number' to represent literals, which is a 43 | -- rather unstructured type (most values are left as strings). This type is 44 | -- parametrized over the type for literals so that the user can instantiate it 45 | -- with a more structured type, for example if they want to build a simulator or 46 | -- compiler. 47 | data Expression' x 48 | = ExprNum x 49 | -- | A variable reference 50 | | ExprVar Ident 51 | -- | A literal string, in quotes. Used for parameter values. 52 | | ExprString String 53 | -- | Index operator, e.g. @x[y]@. 54 | | ExprIndex Ident (Expression' x) 55 | -- | A slice operation of a range of indices, e.g. x[10:15]. 56 | | ExprSlice Ident (ConstExpr' x) (ConstExpr' x) 57 | -- | e.g. @x[y +: 10]@ 58 | | ExprSlicePlus Ident (Expression' x) (ConstExpr' x) 59 | -- | e.g. @x[y -: 10]@ 60 | | ExprSliceMinus Ident (Expression' x) (ConstExpr' x) 61 | -- | Concatenation, e.g. @{a, b, c}@ 62 | | ExprConcat [Expression' x] 63 | -- | Replication, e.g. @{10,{a, b, c}}@ 64 | | ExprMultiConcat (Expression' x) [Expression' x] 65 | -- TODO: 66 | -- | Application of a unary operator 67 | | ExprUnary UnaryOp (Expression' x) 68 | -- | Application of a binary operator 69 | | ExprBinary BinaryOp (Expression' x) (Expression' x) 70 | -- | Conditional expression, e.g. @x ? y : z@ 71 | | ExprCond (Expression' x) (Expression' x) (Expression' x) 72 | -- | Function call, e.g. @f(a, b, c)@ 73 | | ExprFunCall Ident [Expression' x] 74 | deriving (Eq, Ord, Show, Data, Typeable) 75 | 76 | type ConstExpr' x = Expression' x 77 | 78 | type ConstExpr = ConstExpr' Number 79 | type Expression = Expression' Number 80 | 81 | data Sign 82 | = Pos | Neg 83 | deriving (Eq, Ord, Data, Typeable) 84 | 85 | instance Show Sign where 86 | show Pos = "+" 87 | show Neg = "-" 88 | 89 | intExpr :: Integral a => a -> Expression 90 | intExpr x = ExprNum (IntNum Nothing Nothing Nothing (show x)) 91 | 92 | data Number 93 | -- | An integral value: sign, size, and base. 94 | = IntNum (Maybe Sign) (Maybe String) (Maybe Base) String 95 | -- | A real number: sign, integral integral, fractional part, exponent sign, 96 | -- and exponent value 97 | | RealNum (Maybe Sign) String (Maybe String) (Maybe (Maybe Sign, String)) 98 | deriving (Eq, Ord, Data, Typeable) 99 | 100 | instance Show Number where 101 | show (IntNum maybe_sign maybe_size maybe_base value) 102 | = maybe "" show maybe_sign ++ 103 | fromMaybe "" maybe_size ++ 104 | maybe "" show maybe_base ++ 105 | value 106 | 107 | show (RealNum maybe_sign int_part maybe_fract_part maybe_exponent) 108 | = maybe "" show maybe_sign ++ 109 | int_part ++ 110 | maybe "" ("."++) maybe_fract_part ++ 111 | case maybe_exponent of 112 | Just (mb_sign, e) -> "e" ++ (maybe "" show mb_sign) ++ e 113 | Nothing -> "" 114 | 115 | data Base = BinBase | OctBase | DecBase | HexBase 116 | deriving (Eq, Ord, Data, Typeable) 117 | 118 | instance Show Base where 119 | show x = ['\'', case x of 120 | BinBase -> 'b' 121 | OctBase -> 'o' 122 | DecBase -> 'd' 123 | HexBase -> 'h' 124 | ] 125 | 126 | -------------------------------------------------------------------------------- 127 | -- operators 128 | 129 | -- | Unary operators. @Uand@, @UNand@, @UOr@, @UNor@, @UXor@, and @UXnor@ are 130 | -- known as \"reduction operators\". They work just like Haskell\'s @fold@ 131 | -- function. 132 | data UnaryOp 133 | -- UTilde (~) is bitwise negation, UBang (!) is logical negation 134 | -- UAnd/UNand/UOr/UNor/UXor/UXnor are sometimes called "reduction operators" 135 | = UPlus -- ^ Unary plus operator: @+@ 136 | | UMinus -- ^ Unary 2\'s complement negation: @-@ 137 | | UBang -- ^ Logical negation, a.k.a NOT: @!@ 138 | | UTilde -- ^ Bitwise negation, a.k.a. 1\'s complement: @~@ 139 | | UAnd -- ^ @AND@ reduction operator: @&@ 140 | | UNand -- ^ @NAND@ reduction operator: @~&@ 141 | | UOr -- ^ @OR@ eduction operator: @|@ 142 | | UNor -- ^ @NOR@ reduction operator: @~|@ 143 | | UXor -- ^ @XOR@ reduction operator: @^@ 144 | | UXnor -- ^ @XNOR@ reduction operator: @^~@ or @~^@ 145 | deriving (Eq, Ord, Data, Typeable) 146 | 147 | instance Show UnaryOp where 148 | show UPlus = "+" 149 | show UMinus = "-" 150 | show UBang = "!" 151 | show UTilde = "~" 152 | show UAnd = "&" 153 | show UNand = "~&" 154 | show UOr = "|" 155 | show UNor = "~|" 156 | show UXor = "^" 157 | show UXnor = "^~" -- "~^" is also valid 158 | 159 | -- | Binary operators. 160 | data BinaryOp 161 | = Pow -- ^ Arithmetic exponentiation: @**@. Introduced in Verilog-2001. 162 | | Plus -- ^ Arithmetic addition: @+@. 163 | | Minus -- ^ Arithmetic subtraction: @-@ 164 | | Times -- ^ Arithmetic multiplication: @*@ 165 | | Divide -- ^ Arithmetic division: @/@ 166 | | Modulo -- ^ Arithmetic modulo: @%@ 167 | | Equals -- ^ Logical equality: @==@ 168 | | NotEquals -- ^ Logical inequality: @!=@ 169 | | CEquals -- ^ Case equality: @===@. 4-state logic, where @x@ and @z@ are 170 | -- taken literally. 171 | | CNotEquals -- ^ Case inequality: @!==@. 4-state logic, where @x@ and @z@ 172 | -- are taken literally. 173 | | LAnd -- ^ Logical @AND@ operation: @&&@ 174 | | LOr -- ^ Logical @OR@ operation: @||@ 175 | | LessThan -- ^ Less than: @<@ 176 | | LessEqual -- ^ Less than or equal to: @<=@ 177 | | GreaterThan -- ^ Greater than: @>@ 178 | | GreaterEqual -- ^ Greater than or equal to: @>=@ 179 | | And -- ^ Bitwise @AND@ operation: @&@ 180 | | Nand -- ^ Bitwise @NAND@ operation: @~&@ 181 | | Or -- ^ Bitwise @OR@ operation: @|@ 182 | | Nor -- ^ Bitwise @NOR@ operation: @~|@ 183 | | Xor -- ^ Bitwise @XOR@ operation: @^@ 184 | | Xnor -- ^ Bitwise @XNOR@ operation: @^~@ or @~^@ 185 | | ShiftLeft -- ^ Logical left shift: @<<@ 186 | | ShiftRight -- ^ Logical right shift: @>>@ 187 | deriving (Eq, Ord, Data, Typeable) 188 | 189 | instance Show BinaryOp where 190 | show Pow = "**" 191 | show Plus = "+" 192 | show Minus = "-" 193 | show Times = "*" 194 | show Divide = "/" 195 | show Modulo = "%" 196 | show Equals = "==" 197 | show NotEquals = "!=" 198 | show CEquals = "===" 199 | show CNotEquals = "!==" 200 | show LAnd = "&&" 201 | show LOr = "||" 202 | show LessThan = "<" 203 | show LessEqual = "<=" 204 | show GreaterThan = ">" 205 | show GreaterEqual = ">=" 206 | show And = "&" 207 | show Nand = "~&" 208 | show Or = "|" 209 | show Nor = "~|" 210 | show Xor = "^" 211 | show Xnor = "^~" 212 | show ShiftLeft = "<<" 213 | show ShiftRight = ">>" 214 | 215 | -------------------------------------------------------------------------------- 216 | -- GENERATED START 217 | 218 | 219 | instance (Binary x) => Binary (Expression' x) where 220 | put x 221 | = case x of 222 | ExprNum x1 -> do putWord8 0 223 | put x1 224 | ExprVar x1 -> do putWord8 1 225 | put x1 226 | ExprString x1 -> do putWord8 2 227 | put x1 228 | ExprIndex x1 x2 -> do putWord8 3 229 | put x1 230 | put x2 231 | ExprSlice x1 x2 x3 -> do putWord8 4 232 | put x1 233 | put x2 234 | put x3 235 | ExprSlicePlus x1 x2 x3 -> do putWord8 5 236 | put x1 237 | put x2 238 | put x3 239 | ExprSliceMinus x1 x2 x3 -> do putWord8 6 240 | put x1 241 | put x2 242 | put x3 243 | ExprConcat x1 -> do putWord8 7 244 | put x1 245 | ExprMultiConcat x1 x2 -> do putWord8 8 246 | put x1 247 | put x2 248 | ExprUnary x1 x2 -> do putWord8 9 249 | put x1 250 | put x2 251 | ExprBinary x1 x2 x3 -> do putWord8 10 252 | put x1 253 | put x2 254 | put x3 255 | ExprCond x1 x2 x3 -> do putWord8 11 256 | put x1 257 | put x2 258 | put x3 259 | ExprFunCall x1 x2 -> do putWord8 12 260 | put x1 261 | put x2 262 | get 263 | = do i <- getWord8 264 | case i of 265 | 0 -> do x1 <- get 266 | return (ExprNum x1) 267 | 1 -> do x1 <- get 268 | return (ExprVar x1) 269 | 2 -> do x1 <- get 270 | return (ExprString x1) 271 | 3 -> do x1 <- get 272 | x2 <- get 273 | return (ExprIndex x1 x2) 274 | 4 -> do x1 <- get 275 | x2 <- get 276 | x3 <- get 277 | return (ExprSlice x1 x2 x3) 278 | 5 -> do x1 <- get 279 | x2 <- get 280 | x3 <- get 281 | return (ExprSlicePlus x1 x2 x3) 282 | 6 -> do x1 <- get 283 | x2 <- get 284 | x3 <- get 285 | return (ExprSliceMinus x1 x2 x3) 286 | 7 -> do x1 <- get 287 | return (ExprConcat x1) 288 | 8 -> do x1 <- get 289 | x2 <- get 290 | return (ExprMultiConcat x1 x2) 291 | 9 -> do x1 <- get 292 | x2 <- get 293 | return (ExprUnary x1 x2) 294 | 10 -> do x1 <- get 295 | x2 <- get 296 | x3 <- get 297 | return (ExprBinary x1 x2 x3) 298 | 11 -> do x1 <- get 299 | x2 <- get 300 | x3 <- get 301 | return (ExprCond x1 x2 x3) 302 | 12 -> do x1 <- get 303 | x2 <- get 304 | return (ExprFunCall x1 x2) 305 | _ -> error "Corrupted binary data for Expression'" 306 | 307 | 308 | instance Binary Sign where 309 | put x 310 | = case x of 311 | Pos -> putWord8 0 312 | Neg -> putWord8 1 313 | get 314 | = do i <- getWord8 315 | case i of 316 | 0 -> return Pos 317 | 1 -> return Neg 318 | _ -> error "Corrupted binary data for Sign" 319 | 320 | 321 | instance Binary Number where 322 | put x 323 | = case x of 324 | IntNum x1 x2 x3 x4 -> do putWord8 0 325 | put x1 326 | put x2 327 | put x3 328 | put x4 329 | RealNum x1 x2 x3 x4 -> do putWord8 1 330 | put x1 331 | put x2 332 | put x3 333 | put x4 334 | get 335 | = do i <- getWord8 336 | case i of 337 | 0 -> do x1 <- get 338 | x2 <- get 339 | x3 <- get 340 | x4 <- get 341 | return (IntNum x1 x2 x3 x4) 342 | 1 -> do x1 <- get 343 | x2 <- get 344 | x3 <- get 345 | x4 <- get 346 | return (RealNum x1 x2 x3 x4) 347 | _ -> error "Corrupted binary data for Number" 348 | 349 | 350 | instance Binary Base where 351 | put x 352 | = case x of 353 | BinBase -> putWord8 0 354 | OctBase -> putWord8 1 355 | DecBase -> putWord8 2 356 | HexBase -> putWord8 3 357 | get 358 | = do i <- getWord8 359 | case i of 360 | 0 -> return BinBase 361 | 1 -> return OctBase 362 | 2 -> return DecBase 363 | 3 -> return HexBase 364 | _ -> error "Corrupted binary data for Base" 365 | 366 | 367 | instance Binary UnaryOp where 368 | put x 369 | = case x of 370 | UPlus -> putWord8 0 371 | UMinus -> putWord8 1 372 | UBang -> putWord8 2 373 | UTilde -> putWord8 3 374 | UAnd -> putWord8 4 375 | UNand -> putWord8 5 376 | UOr -> putWord8 6 377 | UNor -> putWord8 7 378 | UXor -> putWord8 8 379 | UXnor -> putWord8 9 380 | get 381 | = do i <- getWord8 382 | case i of 383 | 0 -> return UPlus 384 | 1 -> return UMinus 385 | 2 -> return UBang 386 | 3 -> return UTilde 387 | 4 -> return UAnd 388 | 5 -> return UNand 389 | 6 -> return UOr 390 | 7 -> return UNor 391 | 8 -> return UXor 392 | 9 -> return UXnor 393 | _ -> error "Corrupted binary data for UnaryOp" 394 | 395 | 396 | instance Binary BinaryOp where 397 | put x 398 | = case x of 399 | Pow -> putWord8 0 400 | Plus -> putWord8 1 401 | Minus -> putWord8 2 402 | Times -> putWord8 3 403 | Divide -> putWord8 4 404 | Modulo -> putWord8 5 405 | Equals -> putWord8 6 406 | NotEquals -> putWord8 7 407 | CEquals -> putWord8 8 408 | CNotEquals -> putWord8 9 409 | LAnd -> putWord8 10 410 | LOr -> putWord8 11 411 | LessThan -> putWord8 12 412 | LessEqual -> putWord8 13 413 | GreaterThan -> putWord8 14 414 | GreaterEqual -> putWord8 15 415 | And -> putWord8 16 416 | Nand -> putWord8 17 417 | Or -> putWord8 18 418 | Nor -> putWord8 19 419 | Xor -> putWord8 20 420 | Xnor -> putWord8 21 421 | ShiftLeft -> putWord8 22 422 | ShiftRight -> putWord8 23 423 | get 424 | = do i <- getWord8 425 | case i of 426 | 0 -> return Pow 427 | 1 -> return Plus 428 | 2 -> return Minus 429 | 3 -> return Times 430 | 4 -> return Divide 431 | 5 -> return Modulo 432 | 6 -> return Equals 433 | 7 -> return NotEquals 434 | 8 -> return CEquals 435 | 9 -> return CNotEquals 436 | 10 -> return LAnd 437 | 11 -> return LOr 438 | 12 -> return LessThan 439 | 13 -> return LessEqual 440 | 14 -> return GreaterThan 441 | 15 -> return GreaterEqual 442 | 16 -> return And 443 | 17 -> return Nand 444 | 18 -> return Or 445 | 19 -> return Nor 446 | 20 -> return Xor 447 | 21 -> return Xnor 448 | 22 -> return ShiftLeft 449 | 23 -> return ShiftRight 450 | _ -> error "Corrupted binary data for BinaryOp" 451 | -- GENERATED STOP 452 | -------------------------------------------------------------------------------- /verilog/Language/Verilog/PrettyPrint.hs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | -- | 3 | -- Module : Language.Verilog.PrettyPrint 4 | -- Copyright : (c) Signali Corp. 2010 5 | -- License : All rights reserved 6 | -- 7 | -- Maintainer : pweaver@signalicorp.com 8 | -- Stability : experimental 9 | -- Portability : non-portable (DeriveDataTypeable) 10 | -- 11 | -- A pretty printer for the Verilog AST. 12 | -------------------------------------------------------------------------------- 13 | 14 | {-# OPTIONS_GHC -fno-warn-orphans #-} 15 | 16 | module Language.Verilog.PrettyPrint where 17 | 18 | import Data.Maybe ( fromMaybe ) 19 | import Text.PrettyPrint 20 | 21 | import Language.Verilog.Syntax 22 | 23 | -- ----------------------------------------------------------------------------- 24 | -- some utilities, which should go in a common module elsewhere 25 | 26 | commasep :: [Doc] -> Doc 27 | commasep = fsep . punctuate comma 28 | 29 | mb :: (x -> Doc) -> Maybe x -> Doc 30 | mb = maybe empty 31 | 32 | period :: Doc 33 | period = char '.' 34 | 35 | tick :: Doc 36 | tick = char '\'' 37 | 38 | -- ----------------------------------------------------------------------------- 39 | -- 1. Source Text 40 | 41 | ppVerilog :: Verilog -> Doc 42 | ppVerilog (Verilog ds) 43 | = vcat (map ppDescription ds) 44 | 45 | ppDescription :: Description -> Doc 46 | ppDescription (ModuleDescription m) = ppModule m 47 | ppDescription (UDPDescription udp) = ppUDP udp 48 | 49 | ppModule :: Module -> Doc 50 | ppModule (Module name ports body) 51 | = text "module" <+> ppIdent name <+> ppPorts ports <> semi $$ 52 | nest 2 (vcat (map ppItem body)) $$ 53 | text "endmodule" <> char '\n' 54 | 55 | ppPorts :: [Ident] -> Doc 56 | ppPorts [] = empty 57 | ppPorts xs = parens (ppIdents xs) 58 | 59 | ppItem :: Item -> Doc 60 | ppItem (ParamDeclItem x) = ppParamDecl x 61 | ppItem (InputDeclItem x) = ppInputDecl x 62 | ppItem (OutputDeclItem x) = ppOutputDecl x 63 | ppItem (InOutDeclItem x) = ppInOutDecl x 64 | ppItem (NetDeclItem x) = ppNetDecl x 65 | ppItem (RegDeclItem x) = ppRegDecl x 66 | ppItem (EventDeclItem x) = ppEventDecl x 67 | ppItem (PrimitiveInstItem x) = ppPrimitiveInst x 68 | ppItem (InstanceItem x) = ppInstance x 69 | ppItem (ParamOverrideItem xs) 70 | = text "defparam" <+> ppParamAssigns xs <> semi 71 | ppItem (AssignItem mb_strength mb_delay assignments) 72 | = text "assign" <+> 73 | mb ppDriveStrength mb_strength <+> 74 | mb ppDelay mb_delay <+> 75 | commasep (map ppAssignment assignments) <> semi 76 | ppItem (InitialItem (EventControlStmt ctrl stmt)) 77 | = fsep [ text "initial", ppEventControl ctrl, nest 2 (maybe semi ppStatement stmt) ] 78 | ppItem (InitialItem stmt) 79 | = fsep [ text "initial", nest 2 (ppStatement stmt) ] 80 | ppItem (AlwaysItem (EventControlStmt ctrl stmt)) 81 | = fsep [ text "always", ppEventControl ctrl, nest 2 (maybe semi ppStatement stmt) ] 82 | ppItem (AlwaysItem stmt) 83 | = fsep [ text "always", nest 2 (ppStatement stmt) ] 84 | 85 | ppItem (TaskItem name decls stmt) 86 | = text "task" <+> ppIdent name <> semi $$ 87 | nest 2 (vcat (map ppLocalDecl decls) $$ 88 | ppStatement stmt) $$ 89 | text "endtask" 90 | 91 | ppItem (FunctionItem t name decls stmt) 92 | = text "function" <+> mb ppFunctionType t <+> ppIdent name <> semi $$ 93 | nest 2 (vcat (map ppLocalDecl decls) $$ 94 | ppStatement stmt) $$ 95 | text "endfunction" 96 | 97 | -- (copied from andy's code in GenVHDL) 98 | -- TODO: get multline working 99 | ppItem (CommentItem msg) 100 | = vcat [ text "//" <+> text m | m <- lines msg ] 101 | 102 | ppUDP :: UDP -> Doc 103 | ppUDP (UDP name output_var input_vars decls maybe_initial table_definition) 104 | = text "primitive" <+> ppIdent name <+> 105 | parens (ppIdents (output_var : input_vars)) <> semi $$ 106 | nest 2 ( vcat (map ppUDPDecl decls) $$ 107 | maybe empty ppUDPInitialStatement maybe_initial $$ 108 | ppTableDefinition table_definition 109 | ) $$ 110 | text "endprimitive" 111 | 112 | ppUDPDecl :: UDPDecl -> Doc 113 | ppUDPDecl (UDPOutputDecl d) = ppOutputDecl d 114 | ppUDPDecl (UDPInputDecl d) = ppInputDecl d 115 | ppUDPDecl (UDPRegDecl x) = text "reg" <+> ppIdent x <> semi 116 | 117 | ppUDPInitialStatement :: UDPInitialStatement -> Doc 118 | ppUDPInitialStatement (UDPInitialStatement name value) 119 | = text "initial" <+> ppIdent name <+> equals <+> ppExpr value <> semi 120 | 121 | ppTableDefinition :: TableDefinition -> Doc 122 | ppTableDefinition table 123 | = text "table" $$ 124 | nest 2 (vcat xs) $$ 125 | text "endtable" 126 | where 127 | xs = case table of 128 | CombinationalTable entries -> map ppCombinationalEntry entries 129 | SequentialTable entries -> map ppSequentialEntry entries 130 | 131 | ppCombinationalEntry :: CombinationalEntry -> Doc 132 | ppCombinationalEntry (CombinationalEntry inputs output) 133 | = hsep (map ppLevelSymbol inputs) <+> colon <+> ppOutputSymbol output <> semi 134 | 135 | ppSequentialEntry :: SequentialEntry -> Doc 136 | ppSequentialEntry (SequentialEntry inputs state next_state) 137 | = hsep (map (either ppLevelSymbol ppEdge) inputs) <+> colon <+> 138 | ppLevelSymbol state <+> colon <+> ppNextState next_state <> semi 139 | 140 | ppEdge :: Edge -> Doc 141 | ppEdge (EdgeLevels x y) 142 | = parens (ppLevelSymbol x <+> ppLevelSymbol y) 143 | ppEdge (EdgeSymbol x) 144 | = ppEdgeSymbol x 145 | 146 | ppOutputSymbol :: OutputSymbol -> Doc 147 | ppOutputSymbol x 148 | | validOutputSymbol x = char x 149 | | otherwise = error ("ppOutputSymbol: invalid character: " ++ [x]) 150 | 151 | ppLevelSymbol :: LevelSymbol -> Doc 152 | ppLevelSymbol x 153 | | validLevelSymbol x = char x 154 | | otherwise = error ("ppLevelSymbol: invalid character: " ++ [x]) 155 | 156 | ppNextState :: NextState -> Doc 157 | ppNextState x 158 | | validNextState x = char x 159 | | otherwise = error ("ppNextState: invalid character: " ++ [x]) 160 | 161 | ppEdgeSymbol :: EdgeSymbol -> Doc 162 | ppEdgeSymbol x 163 | | validEdgeSymbol x = char x 164 | | otherwise = error ("ppEdgeSymbol: invalid character: " ++ [x]) 165 | 166 | -- ----------------------------------------------------------------------------- 167 | -- 2. Declarations 168 | 169 | ppFunctionType :: FunctionType -> Doc 170 | ppFunctionType (FunctionTypeRange r) = ppRange r 171 | ppFunctionType FunctionTypeInteger = text "integer" 172 | ppFunctionType FunctionTypeReal = text "real" 173 | 174 | ppLocalDecl :: LocalDecl -> Doc 175 | ppLocalDecl (LocalParamDecl x) = ppParamDecl x 176 | ppLocalDecl (LocalInputDecl x) = ppInputDecl x 177 | ppLocalDecl (LocalOutputDecl x) = ppOutputDecl x 178 | ppLocalDecl (LocalInOutDecl x) = ppInOutDecl x 179 | ppLocalDecl (LocalRegDecl x) = ppRegDecl x 180 | 181 | ppParamDecl :: ParamDecl -> Doc 182 | ppParamDecl (ParamDecl paramAssigns) 183 | = text "parameter" <+> ppParamAssigns paramAssigns <> semi 184 | 185 | ppInputDecl :: InputDecl -> Doc 186 | ppInputDecl (InputDecl mb_range vars) 187 | = text "input" <+> mb ppRange mb_range <+> ppIdents vars <> semi 188 | 189 | ppOutputDecl :: OutputDecl -> Doc 190 | ppOutputDecl (OutputDecl mb_range vars) 191 | = text "output" <+> mb ppRange mb_range <+> ppIdents vars <> semi 192 | 193 | ppInOutDecl :: InOutDecl -> Doc 194 | ppInOutDecl (InOutDecl mb_range vars) 195 | = text "inout" <+> mb ppRange mb_range <+> ppIdents vars <> semi 196 | 197 | ppNetDecl :: NetDecl -> Doc 198 | ppNetDecl (NetDecl t mb_range mb_delay vars) 199 | = text (show t) <+> 200 | mb ppExpandRange mb_range <+> 201 | mb ppDelay mb_delay <+> 202 | ppIdents vars <> semi 203 | ppNetDecl (NetDeclAssign t mb_strength mb_range mb_delay assignments) 204 | = text (show t) <+> 205 | mb ppDriveStrength mb_strength <+> 206 | mb ppExpandRange mb_range <+> 207 | mb ppDelay mb_delay <+> 208 | commasep [ ppIdent x <+> equals <+> ppExpr e 209 | | (x, e) <- assignments 210 | ] <> semi 211 | 212 | ppRegDecl :: RegDecl -> Doc 213 | ppRegDecl (RegDecl reg_type mb_range vars) 214 | = text (show reg_type) <+> mb ppRange mb_range <+> ppRegVars vars <> semi 215 | 216 | ppRegVar :: RegVar -> Doc 217 | ppRegVar (RegVar x Nothing) 218 | = ppIdent x 219 | ppRegVar (RegVar x (Just e)) 220 | = ppIdent x <+> equals <+> ppExpr e 221 | ppRegVar (MemVar x r) 222 | = ppIdent x <+> ppRange r 223 | 224 | ppRegVars :: [RegVar] -> Doc 225 | ppRegVars = commasep . map ppRegVar 226 | 227 | ppEventDecl :: EventDecl -> Doc 228 | ppEventDecl (EventDecl vars) 229 | = text "event" <+> ppIdents vars <> semi 230 | 231 | -- ----------------------------------------------------------------------------- 232 | -- 3. Primitive Instances 233 | 234 | ppPrimitiveInst :: PrimitiveInst -> Doc 235 | ppPrimitiveInst (PrimitiveInst prim_type strength delay insts) 236 | = text (show prim_type) <+> mb ppDriveStrength strength <+> 237 | mb ppDelay delay <+> commasep (map ppPrimInst insts) <> semi 238 | 239 | ppPrimInst :: PrimInst -> Doc 240 | ppPrimInst (PrimInst prim_name es) 241 | = mb ppPrimName prim_name <+> parens (commasep (map ppExpr es)) 242 | 243 | ppPrimName :: PrimInstName -> Doc 244 | ppPrimName (PrimInstName x r) 245 | = ppIdent x <> mb ppRange r 246 | 247 | -- ----------------------------------------------------------------------------- 248 | -- 4. Module Instantiations 249 | 250 | ppInstance :: Instance -> Doc 251 | ppInstance (Instance name delays_or_params insts) 252 | = ppIdent name <+> ppDelaysOrParams delays_or_params $$ 253 | nest 2 (ppInsts insts) <> semi 254 | 255 | ppDelaysOrParams :: Either [Expression] [Parameter] -> Doc 256 | ppDelaysOrParams (Left []) = empty 257 | ppDelaysOrParams (Right []) = empty 258 | ppDelaysOrParams (Left es) 259 | = char '#' <> parens (commasep (map ppExpr es)) 260 | ppDelaysOrParams (Right ps) 261 | = char '#' <> parens (commasep (map ppParameter ps)) 262 | 263 | ppParameter :: Parameter -> Doc 264 | ppParameter (Parameter x expr) 265 | = period <> ppIdent x <> parens (ppExpr expr) 266 | 267 | ppInsts :: [Inst] -> Doc 268 | ppInsts insts 269 | = vcat (punctuate comma (map ppInst insts)) 270 | 271 | ppInst :: Inst -> Doc 272 | ppInst (Inst x r cs) 273 | = ppIdent x <> mb ppRange r <> parens (commasep ppCs) 274 | where 275 | ppCs = case cs of 276 | Connections exprs -> map ppExpr exprs 277 | NamedConnections ncs -> map ppNamedConnection ncs 278 | 279 | -- this is used for both port connections and parameter assignments 280 | ppNamedConnection :: NamedConnection -> Doc 281 | ppNamedConnection (NamedConnection x expr) 282 | = period <> ppIdent x <> parens (ppExpr expr) 283 | 284 | -- ---------------------------------------------------------------------------- 285 | -- 5. Behavioral Statements 286 | 287 | ppStatement :: Statement -> Doc 288 | ppStatement (BlockingAssignment x ctrl expr) 289 | = ppLValue x <+> equals <+> mb ppAssignmentControl ctrl <+> ppExpr expr <> semi 290 | ppStatement (NonBlockingAssignment x ctrl expr) 291 | = ppLValue x <+> text "<=" <+> mb ppAssignmentControl ctrl <+> ppExpr expr <> semi 292 | 293 | -- we have to add a begin-end pair in order to avoid ambiguity, otherwise in the 294 | -- concrete syntax the else-branch (if2) will be associated with if1 instead of 295 | -- the outer if-statement. 296 | ppStatement (IfStmt expr (Just if1@IfStmt {}) (Just if2@IfStmt {})) 297 | = ppStatement (IfStmt expr (Just if1') (Just if2)) 298 | where 299 | if1' = SeqBlock Nothing [] [if1] 300 | ppStatement (IfStmt expr stmt1 stmt2) 301 | = (text "if" <+> parens (ppExpr expr)) `nestStmt` (maybe semi ppStatement stmt1) $$ 302 | case stmt2 of 303 | Just stmt -> ppElseBranch stmt 304 | Nothing -> empty 305 | where 306 | ppElseBranch (IfStmt e s1 s2) 307 | = (text "else if" <+> parens (ppExpr e)) `nestStmt` (maybe semi ppStatement s1) $$ 308 | case s2 of 309 | Just s -> ppElseBranch s 310 | Nothing -> empty 311 | ppElseBranch s 312 | = text "else" `nestStmt` ppStatement s 313 | 314 | ppStatement (CaseStmt case_type expr case_items) 315 | = text (show case_type) <+> parens (ppExpr expr) $$ 316 | nest 2 (vcat (map ppCaseItem case_items)) $$ 317 | text "endcase" 318 | ppStatement (ForeverStmt stmt) 319 | = text "forever" `nestStmt` ppStatement stmt 320 | ppStatement (RepeatStmt expr stmt) 321 | = (text "repeat" <+> parens (ppExpr expr)) `nestStmt` ppStatement stmt 322 | ppStatement (WhileStmt expr stmt) 323 | = (text "while" <+> parens (ppExpr expr)) `nestStmt` ppStatement stmt 324 | ppStatement (ForStmt init_assign expr_cond loop_assign stmt) 325 | = x `nestStmt` ppStatement stmt 326 | where 327 | x = text "for" <+> parens (ppAssignment init_assign <> semi <+> 328 | ppExpr expr_cond <> semi <+> 329 | ppAssignment loop_assign) 330 | ppStatement (DelayStmt delay mb_stmt) 331 | = ppDelay delay <+> maybe semi ppStatement mb_stmt 332 | ppStatement (EventControlStmt ctrl mb_stmt) 333 | = case mb_stmt of 334 | Just stmt -> ppEventControl ctrl `nestStmt` ppStatement stmt 335 | Nothing -> ppEventControl ctrl <> semi 336 | ppStatement (WaitStmt expr stmt) 337 | = (text "wait" <+> parens (ppExpr expr)) `nestStmt` maybe semi ppStatement stmt 338 | ppStatement (SeqBlock mb_name decls stmts) 339 | = text "begin" <+> x $$ 340 | nest 2 (vcat (map ppBlockDecl decls ++ map ppStatement stmts)) $$ 341 | text "end" 342 | where x = case mb_name of 343 | Just name -> colon <+> ppIdent name 344 | Nothing -> empty 345 | ppStatement (ParBlock mb_name decls stmts) 346 | = text "fork" <+> x $$ 347 | nest 2 (vcat (map ppBlockDecl decls ++ map ppStatement stmts)) $$ 348 | text "join" 349 | where x = case mb_name of 350 | Just name -> colon <+> ppIdent name 351 | Nothing -> empty 352 | ppStatement (TaskStmt x mb_es) 353 | = char '$' <> ppIdent x <> maybe empty (parens . commasep . map ppExpr) mb_es <> semi 354 | ppStatement (TaskEnableStmt name exprs) 355 | | null exprs = ppIdent name <> semi 356 | | otherwise = ppIdent name <+> parens (commasep (map ppExpr exprs)) 357 | {- 358 | ppStatement (SystemTaskEnableStmt name exprs) 359 | | null exprs = char '$' <> ppIdent name <> semi 360 | | otherwise = char '$' <> ppIdent name <+> parens (commasep (map ppExpr exprs)) 361 | -} 362 | ppStatement (DisableStmt name) 363 | = text "disable" <+> ppIdent name <> semi 364 | ppStatement (AssignStmt assignment) 365 | = text "assign" <+> ppAssignment assignment <> semi 366 | ppStatement (DeAssignStmt x) 367 | = text "deassign" <+> ppLValue x <> semi 368 | ppStatement (ForceStmt assignment) 369 | = text "force" <+> ppAssignment assignment <> semi 370 | ppStatement (ReleaseStmt x) 371 | = text "release" <+> ppLValue x <> semi 372 | 373 | -- a helper for pretty-printing statement. 'fsep' chooses whether to put the 374 | -- statement on the same line as 'x', or nest it on the next line if it doesn't 375 | -- fit on the same line. 376 | nestStmt :: Doc -> Doc -> Doc 377 | nestStmt x stmt 378 | = fsep [x, nest 2 stmt ] 379 | 380 | ppAssignment :: Assignment -> Doc 381 | ppAssignment (Assignment x expr) 382 | = ppLValue x <+> equals <+> ppExpr expr 383 | 384 | ppCaseItem :: CaseItem -> Doc 385 | ppCaseItem (CaseItem es mb_stmt) 386 | = fsep [ commasep (map ppExpr es) <+> colon, maybe semi ppStatement mb_stmt ] 387 | ppCaseItem (CaseDefault mb_stmt) 388 | = fsep [ text "default" <+> colon, maybe semi ppStatement mb_stmt ] 389 | 390 | ppBlockDecl :: BlockDecl -> Doc 391 | ppBlockDecl (ParamDeclBlock x) = ppParamDecl x 392 | ppBlockDecl (RegDeclBlock x) = ppRegDecl x 393 | ppBlockDecl (EventDeclBlock x) = ppEventDecl x 394 | 395 | -- ----------------------------------------------------------------------------- 396 | -- 7. Expressions 397 | 398 | ppLValue :: LValue -> Doc 399 | ppLValue = ppExpr 400 | 401 | ppExpr :: Expression -> Doc 402 | ppExpr = ppExpr' 0 403 | 404 | -- precedence-aware expression pretty printer - adds parens when it needs to 405 | ppExpr' :: Int -> Expression -> Doc 406 | ppExpr' _ (ExprNum x) 407 | = text (show x) 408 | 409 | ppExpr' _ (ExprVar x) 410 | = ppIdent x 411 | ppExpr' _ (ExprString x) 412 | = text (show x) 413 | ppExpr' _ (ExprIndex x expr) 414 | = ppIdent x <> brackets (ppExpr expr) 415 | ppExpr' _ (ExprSlice x e1 e2) 416 | = ppIdent x <> brackets (ppExpr e1 <> colon <> ppExpr e2) 417 | ppExpr' _ (ExprSlicePlus x e1 e2) 418 | = ppIdent x <> brackets (ppExpr e1 <> text "+:" <> ppExpr e2) 419 | ppExpr' _ (ExprSliceMinus x e1 e2) 420 | = ppIdent x <> brackets (ppExpr e1 <> text "-:" <> ppExpr e2) 421 | ppExpr' _ (ExprConcat es) 422 | = braces (commasep (map ppExpr es)) 423 | ppExpr' _ (ExprMultiConcat e es) 424 | = braces (ppExpr e <> braces (commasep (map ppExpr es))) 425 | ppExpr' prec (ExprUnary op expr) 426 | = if prec >= unary_prec then parens e else e 427 | where 428 | e = text x <> ppExpr' unary_prec expr 429 | x = lookupOp op unary_op_table 430 | ppExpr' prec (ExprBinary op expr1 expr2) 431 | = if prec > op_prec then parens e else e 432 | where 433 | e = fsep [ppExpr' op_prec expr1, text x, ppExpr' (op_prec + 1) expr2 ] 434 | (x, op_prec) = lookupOp op binary_op_table 435 | 436 | -- this adds unnecessary parens, but it makes the concrete syntax much easier to 437 | -- read 438 | {- 439 | ppExpr' prec (ExprCond e1 e2 e3) 440 | = if prec > cond_prec then parens x else x 441 | where 442 | x = fsep [ pp e1, char '?', pp e2, colon, pp e3 ] 443 | 444 | pp e 445 | | add_parens e = parens (ppExpr e) 446 | | otherwise = ppExpr e 447 | 448 | add_parens :: Expression -> Bool 449 | add_parens ExprCond{} = True 450 | add_parens _ = False 451 | -} 452 | 453 | ppExpr' prec (ExprCond e1 e2 e3) 454 | = if prec > cond_prec then parens e else e 455 | where 456 | e = fsep [ ppExpr e1, char '?', ppExpr e2, colon, ppExpr e3 ] 457 | 458 | ppExpr' _ (ExprFunCall x es) 459 | = ppIdent x <+> parens (commasep (map ppExpr es)) 460 | 461 | cond_prec, unary_prec :: Int 462 | cond_prec = 1 463 | unary_prec = 11 464 | 465 | lookupOp :: (Eq op, Show op) => op -> [(op, x)] -> x 466 | lookupOp op table 467 | = fromMaybe (error msg) (lookup op table) 468 | where msg = "showOp: cannot find operator: " ++ show op 469 | 470 | -- precedence tables, also for showing. 471 | -- these tables could also be used for parsing operators. 472 | unary_op_table :: [(UnaryOp, String)] 473 | unary_op_table 474 | = [ (UPlus, "+"), (UMinus, "-"), (UBang, "!"), (UTilde, "~") 475 | , (UAnd, "&"), (UNand, "~&"), (UOr, "|"), (UNor, "~|") 476 | , (UXor, "^"), (UXnor, "~^"), (UXnor, "^~") 477 | ] 478 | 479 | binary_op_table :: [(BinaryOp, (String, Int))] 480 | binary_op_table 481 | = [ (LOr, ("||", 2)) 482 | , (LAnd, ("&&", 3)) 483 | , (Or, ("|", 4)), (Nor, ("~|", 4)) 484 | , (And, ("&", 5)), (Nand, ("~&", 5)), (Xor, ("^", 5)), (Xnor, ("^~", 5)), (Xnor, ("~^", 5)) 485 | , (Equals, ("==", 6)), (NotEquals, ("!=", 6)), (CEquals, ("===", 6)), (CNotEquals, ("!==", 6)) 486 | , (LessThan, ("<", 7)), (LessEqual, ("<=", 7)), (GreaterThan, (">", 7)), (GreaterEqual, (">=", 7)) 487 | , (ShiftLeft, ("<<", 8)), (ShiftRight, (">>", 8)) 488 | , (Plus, ("+", 9)), (Minus, ("-", 9)) 489 | , (Times, ("*", 10)), (Divide, ("/", 10)), (Modulo, ("%", 10)) 490 | ] 491 | 492 | -- ----------------------------------------------------------------------------- 493 | -- Miscellaneous 494 | 495 | ppParamAssigns :: [ParamAssign] -> Doc 496 | ppParamAssigns paramAssigns 497 | = commasep (map ppParamAssign paramAssigns) 498 | 499 | ppParamAssign :: ParamAssign -> Doc 500 | ppParamAssign (ParamAssign ident expr) 501 | = ppIdent ident <+> equals <+> ppExpr expr 502 | 503 | ppExpandRange :: ExpandRange -> Doc 504 | ppExpandRange (SimpleRange r) 505 | = ppRange r 506 | ppExpandRange (ScalaredRange r) 507 | = text "scalared" <+> ppRange r 508 | ppExpandRange (VectoredRange r) 509 | = text "vectored" <+> ppRange r 510 | 511 | ppRange :: Range -> Doc 512 | ppRange (Range e1 e2) 513 | = brackets (ppExpr e1 <> colon <> ppExpr e2) 514 | 515 | ppAssignmentControl :: AssignmentControl -> Doc 516 | ppAssignmentControl (DelayControl delay) 517 | = ppDelay delay 518 | ppAssignmentControl (EventControl ctrl) 519 | = ppEventControl ctrl 520 | ppAssignmentControl (RepeatControl e ctrl) 521 | = text "repear" <> parens (ppExpr e) <+> ppEventControl ctrl 522 | 523 | ppDelayControl :: DelayControl -> Doc 524 | ppDelayControl = ppDelay 525 | 526 | ppEventControl :: EventControl -> Doc 527 | ppEventControl ctrl 528 | = char '@' <> 529 | case ctrl of 530 | EventControlIdent x -> ppIdent x 531 | EventControlExpr e -> parens (ppEventExpr e) 532 | EventControlWildCard -> char '*' 533 | 534 | ppDelay :: Delay -> Doc 535 | ppDelay x = char '#' <> ppExpr x 536 | 537 | ppEventExpr :: EventExpr -> Doc 538 | ppEventExpr (EventExpr expr) 539 | = ppExpr expr 540 | ppEventExpr (EventPosedge expr) 541 | = text "posedge" <+> ppExpr expr 542 | ppEventExpr (EventNegedge expr) 543 | = text "negedge" <+> ppExpr expr 544 | ppEventExpr (EventOr expr1 expr2) 545 | = ppEventExpr expr1 <+> text "or" <+> ppEventExpr expr2 546 | 547 | -- TODO: check if the string is a valid Verilog identifier. 548 | -- throw error, or convert it into a valid identifier. 549 | ppIdent :: Ident -> Doc 550 | ppIdent (Ident x) = text x 551 | 552 | ppIdents :: [Ident] -> Doc 553 | ppIdents = commasep . map ppIdent 554 | 555 | ppDriveStrength :: DriveStrength -> Doc 556 | ppDriveStrength (Strength01 s0 s1) 557 | = parens (ppStrength0 s0 <> comma <+> ppStrength1 s1) 558 | ppDriveStrength (Strength10 s1 s0) 559 | = parens (ppStrength1 s1 <> comma <+> ppStrength0 s0) 560 | 561 | ppStrength0 :: Strength0 -> Doc 562 | ppStrength0 = text . show 563 | 564 | ppStrength1 :: Strength1 -> Doc 565 | ppStrength1 = text . show 566 | 567 | -- ----------------------------------------------------------------------------- 568 | -------------------------------------------------------------------------------- /netlist/Language/Netlist/AST.hs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | -- | 3 | -- Module : Language.Netlist.AST 4 | -- Copyright : (c) Signali Corp. 2010 5 | -- License : All rights reserved 6 | -- 7 | -- Maintainer : pweaver@signalicorp.com 8 | -- Stability : experimental 9 | -- Portability : non-portable (DeriveDataTypeable) 10 | -- 11 | -- An abstract syntax tree (AST) for a generic netlist, kind of like a 12 | -- high-level subset of Verilog and VHDL that is compatible with both languages. 13 | -- 14 | -- There are no definitive semantics assigned to this AST. 15 | -- 16 | -- For example, the user may choose to treat the bindings as recursive, so that 17 | -- expressions can reference variables before their declaration, like in 18 | -- Haskell, which is not supported in Verilog and VHDL. in this case, the user 19 | -- must fix the bindings when converting to an HDL. 20 | -- 21 | -- Also, the user may treat module instantiations and processes as having an 22 | -- implict clock/reset, so that they are not explicitly named in those 23 | -- constructs in this AST. Then, the clock and reset can be inserted when 24 | -- generating HDL. 25 | -- 26 | -- When you instantiate a module but information about that module is missing 27 | -- (e.g. the clock/reset are implicit and you need to know what they are called 28 | -- in that module), you can use ExternDecl (TODO) to declare a module's 29 | -- interface so that you know how to instantiate it, or retrieve the interface 30 | -- from a user-maintained database or by parsing and extracting from an HDL 31 | -- file. 32 | -------------------------------------------------------------------------------- 33 | 34 | {-# LANGUAGE DeriveDataTypeable #-} 35 | {-# OPTIONS_GHC -Wall #-} 36 | {-# OPTIONS_DERIVE --append -d Binary #-} 37 | 38 | module Language.Netlist.AST where 39 | 40 | import Data.Binary ( Binary(..), putWord8, getWord8 ) 41 | import Data.Generics ( Data, Typeable ) 42 | 43 | -- ----------------------------------------------------------------------------- 44 | 45 | -- | A Module corresponds to a \"module\" in Verilog or an \"entity\" in VHDL. 46 | data Module = Module 47 | { module_name :: Ident 48 | , module_inputs :: [(Ident, Maybe Range)] 49 | , module_outputs :: [(Ident, Maybe Range)] 50 | , module_statics :: [(Ident, ConstExpr)] 51 | -- static parameters (VHDL "generic", Verilog "parameter") 52 | , module_decls :: [Decl] 53 | } 54 | deriving (Eq, Ord, Show, Data, Typeable) 55 | 56 | -- | An identifier name. 57 | type Ident = String 58 | 59 | -- | The size of a wire. 60 | type Size = Int 61 | 62 | -- | A declaration, analogous to an \"item\" in the Verilog formal syntax. 63 | data Decl 64 | -- | A net (@wire@ in Verilog) has a continuously assigned value. The net can 65 | -- be declared and assigned at the same time (@Just Expr@), or separately 66 | -- (@Nothing@) in a @NetAssign@. 67 | = NetDecl Ident (Maybe Range) (Maybe Expr) 68 | | NetAssign Ident Expr 69 | 70 | -- | A mem (@reg@ in Verilog) is stateful. It can be assigned by a 71 | -- non-blocking assignment (or blocking, but we don't support those yet) 72 | -- within a process. TODO: support optional initial value 73 | -- 74 | -- The first range is the most significant dimension. 75 | -- So, @MemDecl x (0, 31) (7, 0)@ corresponds to the following in Verilog: 76 | -- @reg [7:0] x [0:31]@ 77 | | MemDecl Ident (Maybe Range) (Maybe Range) 78 | 79 | -- | A module/entity instantiation. The arguments are the name of the module, 80 | -- the name of the instance, the parameter assignments, the input port 81 | -- connections, and the output port connections. 82 | | InstDecl Ident -- name of the module 83 | Ident -- name of the instance 84 | [(Ident, Expr)] -- parameter assignments 85 | [(Ident, Expr)] -- input port connections 86 | [(Ident, Expr)] -- output port connections 87 | 88 | -- declare an external module entity 89 | -- TODO: ExternDecl ExternLang 90 | 91 | -- | A sequential process with clock and (optional) asynchronous reset. 92 | | ProcessDecl Event (Maybe (Event, Stmt)) Stmt 93 | 94 | -- | A statement that executes once at the beginning of simulation. 95 | -- Equivalent to Verilog \"initial\" statement. 96 | | InitProcessDecl Stmt 97 | 98 | -- | A basic comment (typically is placed above a decl of interest). 99 | -- Newlines are allowed, and generate new single line comments. 100 | | CommentDecl String 101 | 102 | deriving (Eq, Ord, Show, Data, Typeable) 103 | 104 | -- | A 'Range' tells us the type of a bit vector. It can count up or down. 105 | data Range 106 | = Range ConstExpr ConstExpr 107 | deriving (Eq, Ord, Show, Data, Typeable) 108 | 109 | -- | A constant expression is simply an expression that must be a constant 110 | -- (i.e. the only free variables are static parameters). This restriction is 111 | -- not made in the AST. 112 | type ConstExpr = Expr 113 | 114 | data Event 115 | = Event Expr Edge 116 | deriving (Eq, Ord, Show, Data, Typeable) 117 | 118 | -- | An event can be triggered by the rising edge ('PosEdge') or falling edge 119 | -- ('NegEdge') of a signal. 120 | data Edge 121 | = PosEdge 122 | | NegEdge 123 | deriving (Eq, Ord, Show, Data, Typeable) 124 | 125 | -- | Expr is a combination of VHDL and Verilog expressions. 126 | -- 127 | -- In VHDL, concatenation is a binary operator, but in Verilog it takes any 128 | -- number of arguments. In this AST, we define it like the Verilog operator. 129 | -- If we translate to VHDL, we have to convert it to the VHDL binary operator. 130 | -- 131 | -- There are some HDL operators that we don't represent here. For example, in 132 | -- Verilog there is a multiple concatenation (a.k.a. replication) operator, 133 | -- which we don't bother to support. 134 | 135 | data Expr 136 | = ExprLit (Maybe Size) ExprLit -- ^ a sized or unsized literal 137 | | ExprVar Ident -- ^ a variable ference 138 | | ExprString String -- ^ a quoted string (useful for parameters) 139 | 140 | | ExprIndex Ident Expr -- ^ @x[e]@ 141 | | ExprSlice Ident Expr Expr -- ^ @x[e1 : e2]@ 142 | | ExprSliceOff Ident Expr Int -- ^ @x[e : e+i]@, where @i@ can be negative 143 | | ExprCase Expr [([ConstExpr], Expr)] (Maybe Expr) 144 | -- ^ case expression. supports multiple matches 145 | -- per result value, and an optional default value 146 | | ExprConcat [Expr] -- ^ concatenation 147 | | ExprCond Expr Expr Expr -- ^ conditional expression 148 | | ExprUnary UnaryOp Expr -- ^ application of a unary operator 149 | | ExprBinary BinaryOp Expr Expr -- ^ application of a binary operator 150 | | ExprFunCall Ident [Expr] -- ^ a function application 151 | deriving (Eq, Ord, Show, Data, Typeable) 152 | 153 | data ExprLit 154 | = ExprNum Integer -- ^ a number 155 | | ExprBit Bit -- ^ a single bit. in vhdl, bits are different than 1-bit bitvectors 156 | | ExprBitVector [Bit] 157 | deriving (Eq, Ord, Show, Data, Typeable) 158 | 159 | data Bit 160 | = T | F | U | Z 161 | deriving (Eq, Ord, Show, Data, Typeable) 162 | 163 | -- | Behavioral sequential statement 164 | data Stmt 165 | = Assign LValue Expr -- ^ non-blocking assignment 166 | | If Expr Stmt (Maybe Stmt) -- ^ @if@ statement 167 | | Case Expr [([Expr], Stmt)] (Maybe Stmt) 168 | -- ^ case statement, with optional default case 169 | | Seq [Stmt] -- ^ multiple statements in sequence 170 | | FunCallStmt Ident [Expr] -- ^ a function call that can appear as a statement, 171 | -- useful for calling Verilog tasks (e.g. $readmem). 172 | deriving (Eq, Ord, Show, Data, Typeable) 173 | 174 | -- | An 'LValue' is something that can appear on the left-hand side of an 175 | -- assignment. We're lazy and do not enforce any restriction, and define this 176 | -- simply to be 'Expr'. 177 | type LValue = Expr 178 | 179 | -- | Unary operators 180 | -- 181 | -- 'LNeg' is logical negation, 'Neg' is bitwise negation. 'UAnd', 'UNand', 182 | -- 'UOr', 'UNor', 'UXor', and 'UXnor' are sometimes called \"reduction 183 | -- operators\". 184 | 185 | data UnaryOp 186 | = UPlus | UMinus | LNeg | Neg | UAnd | UNand | UOr | UNor | UXor | UXnor 187 | deriving (Eq, Ord, Show, Data, Typeable) 188 | 189 | -- | Binary operators. 190 | -- 191 | -- These operators include almost all VHDL and Verilog operators. 192 | -- 193 | -- * precedence and pretty-printing are language specific, and defined elsewhere. 194 | -- 195 | -- * exponentation operators were introduced in Verilog-2001. 196 | -- 197 | -- * some operators are not prefix/infix, such as verilog concatenation and the 198 | -- conditional (@x ? y : z@) operator. those operators are defined in 199 | -- 'Expr'. 200 | -- 201 | -- * VHDL has both \"logical\" and \"barithmetic\" shift operators, which we 202 | -- don't yet distinguish between here. 203 | -- 204 | -- * VHDL has both a @mod@ and a @rem@ operator, but so far we only define 205 | -- 'Modulo'. 206 | -- 207 | -- * VHDL has a concat operator (@&@) that isn't yet supported here. Use 208 | -- 'ExprConcat' instead. 209 | -- 210 | -- * VHDL has an @abs@ operator that isn't yet supported here. 211 | 212 | data BinaryOp 213 | = Pow | Plus | Minus | Times | Divide | Modulo -- arithmetic 214 | | Equals | NotEquals -- logical equality 215 | | CEquals | CNotEquals -- case equality 216 | | LAnd | LOr -- logical and/or 217 | | LessThan | LessEqual | GreaterThan | GreaterEqual -- relational 218 | | And | Nand | Or | Nor | Xor | Xnor -- bitwise 219 | | ShiftLeft | ShiftRight | RotateLeft | RotateRight -- shift/rotate 220 | deriving (Eq, Ord, Show, Data, Typeable) 221 | 222 | -- ----------------------------------------------------------------------------- 223 | -- GENERATED START 224 | 225 | 226 | instance Binary Module where 227 | put (Module x1 x2 x3 x4 x5) 228 | = do put x1 229 | put x2 230 | put x3 231 | put x4 232 | put x5 233 | get 234 | = do x1 <- get 235 | x2 <- get 236 | x3 <- get 237 | x4 <- get 238 | x5 <- get 239 | return (Module x1 x2 x3 x4 x5) 240 | 241 | 242 | instance Binary Decl where 243 | put x 244 | = case x of 245 | NetDecl x1 x2 x3 -> do putWord8 0 246 | put x1 247 | put x2 248 | put x3 249 | NetAssign x1 x2 -> do putWord8 1 250 | put x1 251 | put x2 252 | MemDecl x1 x2 x3 -> do putWord8 2 253 | put x1 254 | put x2 255 | put x3 256 | InstDecl x1 x2 x3 x4 x5 -> do putWord8 3 257 | put x1 258 | put x2 259 | put x3 260 | put x4 261 | put x5 262 | ProcessDecl x1 x2 x3 -> do putWord8 4 263 | put x1 264 | put x2 265 | put x3 266 | InitProcessDecl x1 -> do putWord8 5 267 | put x1 268 | CommentDecl x1 -> do putWord8 6 269 | put x1 270 | get 271 | = do i <- getWord8 272 | case i of 273 | 0 -> do x1 <- get 274 | x2 <- get 275 | x3 <- get 276 | return (NetDecl x1 x2 x3) 277 | 1 -> do x1 <- get 278 | x2 <- get 279 | return (NetAssign x1 x2) 280 | 2 -> do x1 <- get 281 | x2 <- get 282 | x3 <- get 283 | return (MemDecl x1 x2 x3) 284 | 3 -> do x1 <- get 285 | x2 <- get 286 | x3 <- get 287 | x4 <- get 288 | x5 <- get 289 | return (InstDecl x1 x2 x3 x4 x5) 290 | 4 -> do x1 <- get 291 | x2 <- get 292 | x3 <- get 293 | return (ProcessDecl x1 x2 x3) 294 | 5 -> do x1 <- get 295 | return (InitProcessDecl x1) 296 | 6 -> do x1 <- get 297 | return (CommentDecl x1) 298 | _ -> error "Corrupted binary data for Decl" 299 | 300 | 301 | instance Binary Range where 302 | put (Range x1 x2) 303 | = do put x1 304 | put x2 305 | get 306 | = do x1 <- get 307 | x2 <- get 308 | return (Range x1 x2) 309 | 310 | 311 | instance Binary Event where 312 | put (Event x1 x2) 313 | = do put x1 314 | put x2 315 | get 316 | = do x1 <- get 317 | x2 <- get 318 | return (Event x1 x2) 319 | 320 | 321 | instance Binary Edge where 322 | put x 323 | = case x of 324 | PosEdge -> putWord8 0 325 | NegEdge -> putWord8 1 326 | get 327 | = do i <- getWord8 328 | case i of 329 | 0 -> return PosEdge 330 | 1 -> return NegEdge 331 | _ -> error "Corrupted binary data for Edge" 332 | 333 | 334 | instance Binary Expr where 335 | put x 336 | = case x of 337 | ExprLit x1 x2 -> do putWord8 0 338 | put x1 339 | put x2 340 | ExprVar x1 -> do putWord8 1 341 | put x1 342 | ExprString x1 -> do putWord8 2 343 | put x1 344 | ExprIndex x1 x2 -> do putWord8 3 345 | put x1 346 | put x2 347 | ExprSlice x1 x2 x3 -> do putWord8 4 348 | put x1 349 | put x2 350 | put x3 351 | ExprSliceOff x1 x2 x3 -> do putWord8 5 352 | put x1 353 | put x2 354 | put x3 355 | ExprCase x1 x2 x3 -> do putWord8 6 356 | put x1 357 | put x2 358 | put x3 359 | ExprConcat x1 -> do putWord8 7 360 | put x1 361 | ExprCond x1 x2 x3 -> do putWord8 8 362 | put x1 363 | put x2 364 | put x3 365 | ExprUnary x1 x2 -> do putWord8 9 366 | put x1 367 | put x2 368 | ExprBinary x1 x2 x3 -> do putWord8 10 369 | put x1 370 | put x2 371 | put x3 372 | ExprFunCall x1 x2 -> do putWord8 11 373 | put x1 374 | put x2 375 | get 376 | = do i <- getWord8 377 | case i of 378 | 0 -> do x1 <- get 379 | x2 <- get 380 | return (ExprLit x1 x2) 381 | 1 -> do x1 <- get 382 | return (ExprVar x1) 383 | 2 -> do x1 <- get 384 | return (ExprString x1) 385 | 3 -> do x1 <- get 386 | x2 <- get 387 | return (ExprIndex x1 x2) 388 | 4 -> do x1 <- get 389 | x2 <- get 390 | x3 <- get 391 | return (ExprSlice x1 x2 x3) 392 | 5 -> do x1 <- get 393 | x2 <- get 394 | x3 <- get 395 | return (ExprSliceOff x1 x2 x3) 396 | 6 -> do x1 <- get 397 | x2 <- get 398 | x3 <- get 399 | return (ExprCase x1 x2 x3) 400 | 7 -> do x1 <- get 401 | return (ExprConcat x1) 402 | 8 -> do x1 <- get 403 | x2 <- get 404 | x3 <- get 405 | return (ExprCond x1 x2 x3) 406 | 9 -> do x1 <- get 407 | x2 <- get 408 | return (ExprUnary x1 x2) 409 | 10 -> do x1 <- get 410 | x2 <- get 411 | x3 <- get 412 | return (ExprBinary x1 x2 x3) 413 | 11 -> do x1 <- get 414 | x2 <- get 415 | return (ExprFunCall x1 x2) 416 | _ -> error "Corrupted binary data for Expr" 417 | 418 | 419 | instance Binary ExprLit where 420 | put x 421 | = case x of 422 | ExprNum x1 -> do putWord8 0 423 | put x1 424 | ExprBit x1 -> do putWord8 1 425 | put x1 426 | ExprBitVector x1 -> do putWord8 2 427 | put x1 428 | get 429 | = do i <- getWord8 430 | case i of 431 | 0 -> do x1 <- get 432 | return (ExprNum x1) 433 | 1 -> do x1 <- get 434 | return (ExprBit x1) 435 | 2 -> do x1 <- get 436 | return (ExprBitVector x1) 437 | _ -> error "Corrupted binary data for ExprLit" 438 | 439 | 440 | instance Binary Bit where 441 | put x 442 | = case x of 443 | T -> putWord8 0 444 | F -> putWord8 1 445 | U -> putWord8 2 446 | Z -> putWord8 3 447 | get 448 | = do i <- getWord8 449 | case i of 450 | 0 -> return T 451 | 1 -> return F 452 | 2 -> return U 453 | 3 -> return Z 454 | _ -> error "Corrupted binary data for Bit" 455 | 456 | 457 | instance Binary Stmt where 458 | put x 459 | = case x of 460 | Assign x1 x2 -> do putWord8 0 461 | put x1 462 | put x2 463 | If x1 x2 x3 -> do putWord8 1 464 | put x1 465 | put x2 466 | put x3 467 | Case x1 x2 x3 -> do putWord8 2 468 | put x1 469 | put x2 470 | put x3 471 | Seq x1 -> do putWord8 3 472 | put x1 473 | FunCallStmt x1 x2 -> do putWord8 4 474 | put x1 475 | put x2 476 | get 477 | = do i <- getWord8 478 | case i of 479 | 0 -> do x1 <- get 480 | x2 <- get 481 | return (Assign x1 x2) 482 | 1 -> do x1 <- get 483 | x2 <- get 484 | x3 <- get 485 | return (If x1 x2 x3) 486 | 2 -> do x1 <- get 487 | x2 <- get 488 | x3 <- get 489 | return (Case x1 x2 x3) 490 | 3 -> do x1 <- get 491 | return (Seq x1) 492 | 4 -> do x1 <- get 493 | x2 <- get 494 | return (FunCallStmt x1 x2) 495 | _ -> error "Corrupted binary data for Stmt" 496 | 497 | 498 | instance Binary UnaryOp where 499 | put x 500 | = case x of 501 | UPlus -> putWord8 0 502 | UMinus -> putWord8 1 503 | LNeg -> putWord8 2 504 | Neg -> putWord8 3 505 | UAnd -> putWord8 4 506 | UNand -> putWord8 5 507 | UOr -> putWord8 6 508 | UNor -> putWord8 7 509 | UXor -> putWord8 8 510 | UXnor -> putWord8 9 511 | get 512 | = do i <- getWord8 513 | case i of 514 | 0 -> return UPlus 515 | 1 -> return UMinus 516 | 2 -> return LNeg 517 | 3 -> return Neg 518 | 4 -> return UAnd 519 | 5 -> return UNand 520 | 6 -> return UOr 521 | 7 -> return UNor 522 | 8 -> return UXor 523 | 9 -> return UXnor 524 | _ -> error "Corrupted binary data for UnaryOp" 525 | 526 | 527 | instance Binary BinaryOp where 528 | put x 529 | = case x of 530 | Pow -> putWord8 0 531 | Plus -> putWord8 1 532 | Minus -> putWord8 2 533 | Times -> putWord8 3 534 | Divide -> putWord8 4 535 | Modulo -> putWord8 5 536 | Equals -> putWord8 6 537 | NotEquals -> putWord8 7 538 | CEquals -> putWord8 8 539 | CNotEquals -> putWord8 9 540 | LAnd -> putWord8 10 541 | LOr -> putWord8 11 542 | LessThan -> putWord8 12 543 | LessEqual -> putWord8 13 544 | GreaterThan -> putWord8 14 545 | GreaterEqual -> putWord8 15 546 | And -> putWord8 16 547 | Nand -> putWord8 17 548 | Or -> putWord8 18 549 | Nor -> putWord8 19 550 | Xor -> putWord8 20 551 | Xnor -> putWord8 21 552 | ShiftLeft -> putWord8 22 553 | ShiftRight -> putWord8 23 554 | RotateLeft -> putWord8 24 555 | RotateRight -> putWord8 25 556 | get 557 | = do i <- getWord8 558 | case i of 559 | 0 -> return Pow 560 | 1 -> return Plus 561 | 2 -> return Minus 562 | 3 -> return Times 563 | 4 -> return Divide 564 | 5 -> return Modulo 565 | 6 -> return Equals 566 | 7 -> return NotEquals 567 | 8 -> return CEquals 568 | 9 -> return CNotEquals 569 | 10 -> return LAnd 570 | 11 -> return LOr 571 | 12 -> return LessThan 572 | 13 -> return LessEqual 573 | 14 -> return GreaterThan 574 | 15 -> return GreaterEqual 575 | 16 -> return And 576 | 17 -> return Nand 577 | 18 -> return Or 578 | 19 -> return Nor 579 | 20 -> return Xor 580 | 21 -> return Xnor 581 | 22 -> return ShiftLeft 582 | 23 -> return ShiftRight 583 | 24 -> return RotateLeft 584 | 25 -> return RotateRight 585 | _ -> error "Corrupted binary data for BinaryOp" 586 | -- GENERATED STOP 587 | --------------------------------------------------------------------------------