From 5520d6d7165d7edb54d9533b59f8ad373bd79fad Mon Sep 17 00:00:00 2001 From: Iurii Tatishchev Date: Tue, 1 Oct 2024 10:39:56 -0700 Subject: [PATCH] initial commit --- .gitignore | 29 +++ DOC/proj_02_guideline.pdf | Bin 0 -> 110304 bytes GOLDEN/AND32_2x1_TB.out.golden | 8 + GOLDEN/INV32_1x1_TB.out.golden | 8 + GOLDEN/NOR32_2x1_TB.out.golden | 8 + GOLDEN/OR32_2x1_TB.out.golden | 8 + GOLDEN/alu_tb.out.golden | 147 ++++++++++++ GOLDEN/barret_shifter_tb.out.golden | 67 ++++++ GOLDEN/d_ff_tb.out.golden | 10 + GOLDEN/d_latch_tb.out.golden | 11 + GOLDEN/d_reg1_tb.out.golden | 10 + GOLDEN/d_reg32_tb.out.golden | 11 + GOLDEN/decoder_5x32_tb.out.golden | 35 +++ GOLDEN/full_adder.out.golden | 11 + GOLDEN/half_adder.out.golden | 7 + GOLDEN/mult32_tb.out.golden | 11 + GOLDEN/mult32_u_tb.out.golden | 8 + GOLDEN/mux32_16x1_tb.out.golden | 19 ++ GOLDEN/mux32_2x1_tb.out.golden | 5 + GOLDEN/mux32_32x1_tb.out.golden | 35 +++ GOLDEN/rc_add_sub_32.out.golden | 8 + GOLDEN/rf_tb.out.golden | 67 ++++++ GOLDEN/sr_latch_tb.out.golden | 17 ++ GOLDEN/twoscomp32_tb.out.golden | 5 + GOLDEN/twoscomp64_tb.out.golden | 5 + TESTBENCH/alu_tb.v | 85 +++++++ TESTBENCH/barrel_shifter_tb.v | 80 +++++++ TESTBENCH/da_vinci_tb.v | 137 +++++++++++ TESTBENCH/full_adder_tb.v | 40 ++++ TESTBENCH/half_adder_tb.v | 41 ++++ TESTBENCH/logic_32_bit_tb.v | 144 ++++++++++++ TESTBENCH/logic_tb.v | 343 ++++++++++++++++++++++++++++ TESTBENCH/mem_64MB_tb.v | 111 +++++++++ TESTBENCH/mult_tb.v | 86 +++++++ TESTBENCH/mux_tb.v | 109 +++++++++ TESTBENCH/rc_add_sub_32_tb.v | 46 ++++ TESTBENCH/register_file_tb.v | 102 +++++++++ alu.v | 37 +++ barrel_shifter.v | 64 ++++++ clk_gen.v | 32 +++ control_unit.v | 61 +++++ da_vinci.v | 44 ++++ data_path.v | 34 +++ full_adder.v | 28 +++ half_adder.v | 27 +++ logic.v | 146 ++++++++++++ logic_32_bit.v | 62 +++++ memory.v | 99 ++++++++ mult.v | 44 ++++ mux.v | 118 ++++++++++ prj_definition.v | 44 ++++ processor.v | 47 ++++ rc_add_sub_32.v | 48 ++++ register_file.v | 46 ++++ 54 files changed, 2855 insertions(+) create mode 100644 .gitignore create mode 100644 DOC/proj_02_guideline.pdf create mode 100644 GOLDEN/AND32_2x1_TB.out.golden create mode 100644 GOLDEN/INV32_1x1_TB.out.golden create mode 100644 GOLDEN/NOR32_2x1_TB.out.golden create mode 100644 GOLDEN/OR32_2x1_TB.out.golden create mode 100644 GOLDEN/alu_tb.out.golden create mode 100644 GOLDEN/barret_shifter_tb.out.golden create mode 100644 GOLDEN/d_ff_tb.out.golden create mode 100644 GOLDEN/d_latch_tb.out.golden create mode 100644 GOLDEN/d_reg1_tb.out.golden create mode 100644 GOLDEN/d_reg32_tb.out.golden create mode 100644 GOLDEN/decoder_5x32_tb.out.golden create mode 100644 GOLDEN/full_adder.out.golden create mode 100644 GOLDEN/half_adder.out.golden create mode 100644 GOLDEN/mult32_tb.out.golden create mode 100644 GOLDEN/mult32_u_tb.out.golden create mode 100644 GOLDEN/mux32_16x1_tb.out.golden create mode 100644 GOLDEN/mux32_2x1_tb.out.golden create mode 100644 GOLDEN/mux32_32x1_tb.out.golden create mode 100644 GOLDEN/rc_add_sub_32.out.golden create mode 100644 GOLDEN/rf_tb.out.golden create mode 100644 GOLDEN/sr_latch_tb.out.golden create mode 100644 GOLDEN/twoscomp32_tb.out.golden create mode 100644 GOLDEN/twoscomp64_tb.out.golden create mode 100644 TESTBENCH/alu_tb.v create mode 100644 TESTBENCH/barrel_shifter_tb.v create mode 100644 TESTBENCH/da_vinci_tb.v create mode 100644 TESTBENCH/full_adder_tb.v create mode 100644 TESTBENCH/half_adder_tb.v create mode 100644 TESTBENCH/logic_32_bit_tb.v create mode 100644 TESTBENCH/logic_tb.v create mode 100644 TESTBENCH/mem_64MB_tb.v create mode 100644 TESTBENCH/mult_tb.v create mode 100644 TESTBENCH/mux_tb.v create mode 100644 TESTBENCH/rc_add_sub_32_tb.v create mode 100644 TESTBENCH/register_file_tb.v create mode 100644 alu.v create mode 100644 barrel_shifter.v create mode 100644 clk_gen.v create mode 100644 control_unit.v create mode 100644 da_vinci.v create mode 100644 data_path.v create mode 100644 full_adder.v create mode 100644 half_adder.v create mode 100644 logic.v create mode 100644 logic_32_bit.v create mode 100644 memory.v create mode 100644 mult.v create mode 100644 mux.v create mode 100644 prj_definition.v create mode 100644 processor.v create mode 100644 rc_add_sub_32.v create mode 100644 register_file.v diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..92f4c49 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# Created by https://www.toptal.com/developers/gitignore/api/modelsim +# Edit at https://www.toptal.com/developers/gitignore?templates=modelsim + +### ModelSim ### +# ignore ModelSim generated files and directories (temp files and so on) +[_@]* + +# ignore compilation output of ModelSim +*.mti +*.dat +*.dbs +*.psm +*.bak +*.cmp +*.jpg +*.html +*.bsf + +# ignore simulation output of ModelSim +wlf* +*.wlf +*.vstf +*.ucdb +cov*/ +transcript* +sc_dpiheader.h +vsim.dbg + +# End of https://www.toptal.com/developers/gitignore/api/modelsim diff --git a/DOC/proj_02_guideline.pdf b/DOC/proj_02_guideline.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f2e94f146e213c1e20a05c3f8a31b7087c77c92d GIT binary patch literal 110304 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∈RHRsgt;0`S85oFNwSzwACcm=%t$^*(BwQ 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

YJ0!J~zoc}C+5aVJxjNxPAlbLTb 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 z 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 V2Zsrel-5W_#5nh#oy=N*L==>u2FX@ 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� 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 QC}4boA?M{)ysSk2UlPT1LI3~& literal 0 HcmV?d00001 diff --git a/GOLDEN/AND32_2x1_TB.out.golden b/GOLDEN/AND32_2x1_TB.out.golden new file mode 100644 index 0000000..dcf7ea5 --- /dev/null +++ b/GOLDEN/AND32_2x1_TB.out.golden @@ -0,0 +1,8 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/AND32_2x1_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000000 +00000000 +ffff0000 +0000ffff diff --git a/GOLDEN/INV32_1x1_TB.out.golden b/GOLDEN/INV32_1x1_TB.out.golden new file mode 100644 index 0000000..776b89d --- /dev/null +++ b/GOLDEN/INV32_1x1_TB.out.golden @@ -0,0 +1,8 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/INV32_1x1_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +0000ffff +ffffffff +5a5a5a5a +0000ffff +ffff0000 diff --git a/GOLDEN/NOR32_2x1_TB.out.golden b/GOLDEN/NOR32_2x1_TB.out.golden new file mode 100644 index 0000000..a7f6b39 --- /dev/null +++ b/GOLDEN/NOR32_2x1_TB.out.golden @@ -0,0 +1,8 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/NOR32_2x1_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +ffffffff +00000000 +0000ffff +ffff0000 diff --git a/GOLDEN/OR32_2x1_TB.out.golden b/GOLDEN/OR32_2x1_TB.out.golden new file mode 100644 index 0000000..50bd555 --- /dev/null +++ b/GOLDEN/OR32_2x1_TB.out.golden @@ -0,0 +1,8 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/OR32_2x1_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +ffffffff +00000000 +ffffffff +ffff0000 +0000ffff diff --git a/GOLDEN/alu_tb.out.golden b/GOLDEN/alu_tb.out.golden new file mode 100644 index 0000000..f44ff0e --- /dev/null +++ b/GOLDEN/alu_tb.out.golden @@ -0,0 +1,147 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/ALU_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000014 +00000000 +00000000 +00000001 +00000064 +00000000 +00000000 +00000001 +00002800 +00000000 +0000000a +00000000 +0000000a +00000000 +fffffff5 +00000000 +00000000 +00000001 +00000000 +00000001 +ffffffe2 +00000000 +ffffff1f +00000000 +0001ffff +00000000 +fff88000 +00000000 +00000001 +00000000 +ffffffff +00000000 +00000000 +00000001 +00000001 +00000000 +00000000 +00000001 +00000032 +00000000 +fffffd8f +00000000 +00000000 +00000001 +00000000 +00000001 +00000001 +00000000 +ffffffff +00000000 +00000000 +00000001 +00000000 +00000001 +ffffffc4 +00000000 +00000000 +00000001 +00000384 +00000000 +00000000 +00000001 +00000000 +00000001 +ffffffe2 +00000000 +ffffffe2 +00000000 +0000001d +00000000 +00000000 +00000001 +00000000 +00000001 +00000000 +00000001 +00000000 +00000001 +00000000 +00000001 +00000000 +00000001 +00000000 +00000001 +00000000 +00000001 +ffffffff +00000000 +00000000 +00000001 +0000001b +00000000 +ffffffc7 +00000000 +fffffd8a +00000000 +00000000 +00000001 +00000000 +00000001 +00000020 +00000000 +fffffffb +00000000 +00000004 +00000000 +00000001 +00000000 +00000017 +00000000 +00000017 +00000000 +00000000 +00000001 +00000017 +00000000 +00000017 +00000000 +00000000 +00000001 +00000017 +00000000 +ffffffe8 +00000000 +00000000 +00000001 +00000046 +00000000 +ffffffba +00000000 +00000000 +00000001 +00000000 +00000001 +00000000 +00000001 +00000000 +00000001 +00000046 +00000000 +ffffffb9 +00000000 +00000001 +00000000 diff --git a/GOLDEN/barret_shifter_tb.out.golden b/GOLDEN/barret_shifter_tb.out.golden new file mode 100644 index 0000000..95c0948 --- /dev/null +++ b/GOLDEN/barret_shifter_tb.out.golden @@ -0,0 +1,67 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/BARREL_SHIFTER32_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +4b4b4b4a +96969694 +2d2d2d28 +5a5a5a50 +b4b4b4a0 +69696940 +d2d2d280 +a5a5a500 +4b4b4a00 +96969400 +2d2d2800 +5a5a5000 +b4b4a000 +69694000 +d2d28000 +a5a50000 +4b4a0000 +96940000 +2d280000 +5a500000 +b4a00000 +69400000 +d2800000 +a5000000 +4a000000 +94000000 +28000000 +50000000 +a0000000 +40000000 +80000000 +00000000 +52d2d2d2 +29696969 +14b4b4b4 +0a5a5a5a +052d2d2d +02969696 +014b4b4b +00a5a5a5 +0052d2d2 +00296969 +0014b4b4 +000a5a5a +00052d2d +00029696 +00014b4b +0000a5a5 +000052d2 +00002969 +000014b4 +00000a5a +0000052d +00000296 +0000014b +000000a5 +00000052 +00000029 +00000014 +0000000a +00000005 +00000002 +00000001 +00000000 diff --git a/GOLDEN/d_ff_tb.out.golden b/GOLDEN/d_ff_tb.out.golden new file mode 100644 index 0000000..74f90af --- /dev/null +++ b/GOLDEN/d_ff_tb.out.golden @@ -0,0 +1,10 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/D_FF_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000012 +00000013 +0000000b +00000017 +0000000d +0000000f +00000017 diff --git a/GOLDEN/d_latch_tb.out.golden b/GOLDEN/d_latch_tb.out.golden new file mode 100644 index 0000000..2ba4e87 --- /dev/null +++ b/GOLDEN/d_latch_tb.out.golden @@ -0,0 +1,11 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/D_LATCH_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000022 +00000023 +00000027 +00000011 +00000013 +00000017 +0000002f +0000001b diff --git a/GOLDEN/d_reg1_tb.out.golden b/GOLDEN/d_reg1_tb.out.golden new file mode 100644 index 0000000..7a825ba --- /dev/null +++ b/GOLDEN/d_reg1_tb.out.golden @@ -0,0 +1,10 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/REG1_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000022 +00000023 +0000000b +0000002f +0000001d +0000001f +00000023 diff --git a/GOLDEN/d_reg32_tb.out.golden b/GOLDEN/d_reg32_tb.out.golden new file mode 100644 index 0000000..85f380e --- /dev/null +++ b/GOLDEN/d_reg32_tb.out.golden @@ -0,0 +1,11 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/REG32_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000000 +a5a5a5a5 +ffff0000 +00000000 +00000000 +0000ffff +0000ffff diff --git a/GOLDEN/decoder_5x32_tb.out.golden b/GOLDEN/decoder_5x32_tb.out.golden new file mode 100644 index 0000000..b944b99 --- /dev/null +++ b/GOLDEN/decoder_5x32_tb.out.golden @@ -0,0 +1,35 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/DECODER_5x32_TB/result +// format=bin addressradix=h dataradix=b version=1.0 wordsperline=1 noaddress +00000000000000000000000000000001 +00000000000000000000000000000010 +00000000000000000000000000000100 +00000000000000000000000000001000 +00000000000000000000000000010000 +00000000000000000000000000100000 +00000000000000000000000001000000 +00000000000000000000000010000000 +00000000000000000000000100000000 +00000000000000000000001000000000 +00000000000000000000010000000000 +00000000000000000000100000000000 +00000000000000000001000000000000 +00000000000000000010000000000000 +00000000000000000100000000000000 +00000000000000001000000000000000 +00000000000000010000000000000000 +00000000000000100000000000000000 +00000000000001000000000000000000 +00000000000010000000000000000000 +00000000000100000000000000000000 +00000000001000000000000000000000 +00000000010000000000000000000000 +00000000100000000000000000000000 +00000001000000000000000000000000 +00000010000000000000000000000000 +00000100000000000000000000000000 +00001000000000000000000000000000 +00010000000000000000000000000000 +00100000000000000000000000000000 +01000000000000000000000000000000 +10000000000000000000000000000000 diff --git a/GOLDEN/full_adder.out.golden b/GOLDEN/full_adder.out.golden new file mode 100644 index 0000000..6c019d4 --- /dev/null +++ b/GOLDEN/full_adder.out.golden @@ -0,0 +1,11 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/FULL_ADDER_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000001 +00000001 +00000002 +00000001 +00000002 +00000002 +00000003 diff --git a/GOLDEN/half_adder.out.golden b/GOLDEN/half_adder.out.golden new file mode 100644 index 0000000..7649f00 --- /dev/null +++ b/GOLDEN/half_adder.out.golden @@ -0,0 +1,7 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/HALF_ADDER_TB/results +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000001 +00000001 +00000002 diff --git a/GOLDEN/mult32_tb.out.golden b/GOLDEN/mult32_tb.out.golden new file mode 100644 index 0000000..510e496 --- /dev/null +++ b/GOLDEN/mult32_tb.out.golden @@ -0,0 +1,11 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/MULT_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000000000c8 +000000000000002d +ffffffffffffff90 +ffffffffffffff42 +3100000000000000 +cf00000000000000 +cf00000000000000 +3100000000000000 diff --git a/GOLDEN/mult32_u_tb.out.golden b/GOLDEN/mult32_u_tb.out.golden new file mode 100644 index 0000000..0635f2e --- /dev/null +++ b/GOLDEN/mult32_u_tb.out.golden @@ -0,0 +1,8 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/MULT_U_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000000000c8 +000000000000002d +0000000000000070 +00000000000000be +3100000000000000 diff --git a/GOLDEN/mux32_16x1_tb.out.golden b/GOLDEN/mux32_16x1_tb.out.golden new file mode 100644 index 0000000..3c916bd --- /dev/null +++ b/GOLDEN/mux32_16x1_tb.out.golden @@ -0,0 +1,19 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/MUX32_16x1_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000001 +00000002 +00000003 +00000004 +00000005 +00000006 +00000007 +00000008 +00000009 +0000000a +0000000b +0000000c +0000000d +0000000e +0000000f diff --git a/GOLDEN/mux32_2x1_tb.out.golden b/GOLDEN/mux32_2x1_tb.out.golden new file mode 100644 index 0000000..e39c575 --- /dev/null +++ b/GOLDEN/mux32_2x1_tb.out.golden @@ -0,0 +1,5 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/MUX32_2x1_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +a5a5a5a5 +5a5a5a5a diff --git a/GOLDEN/mux32_32x1_tb.out.golden b/GOLDEN/mux32_32x1_tb.out.golden new file mode 100644 index 0000000..a7a230c --- /dev/null +++ b/GOLDEN/mux32_32x1_tb.out.golden @@ -0,0 +1,35 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/MUX32_32x1_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000001 +00000002 +00000003 +00000004 +00000005 +00000006 +00000007 +00000008 +00000009 +0000000a +0000000b +0000000c +0000000d +0000000e +0000000f +00000010 +00000011 +00000012 +00000013 +00000014 +00000015 +00000016 +00000017 +00000018 +00000019 +0000001a +0000001b +0000001c +0000001d +0000001e +0000001f diff --git a/GOLDEN/rc_add_sub_32.out.golden b/GOLDEN/rc_add_sub_32.out.golden new file mode 100644 index 0000000..4a19897 --- /dev/null +++ b/GOLDEN/rc_add_sub_32.out.golden @@ -0,0 +1,8 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/RC_ADD_SUB_32_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +0000001e +fffffff6 +00000003 +00000004 +00005555 diff --git a/GOLDEN/rf_tb.out.golden b/GOLDEN/rf_tb.out.golden new file mode 100644 index 0000000..325b21f --- /dev/null +++ b/GOLDEN/rf_tb.out.golden @@ -0,0 +1,67 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/RF_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000000 +00000000 +00000001 +00000001 +00000002 +00000002 +00000003 +00000003 +00000004 +00000004 +00000005 +00000005 +00000006 +00000006 +00000007 +00000007 +00000008 +00000008 +00000009 +00000009 +0000000a +0000000a +0000000b +0000000b +0000000c +0000000c +0000000d +0000000d +0000000e +0000000e +0000000f +0000000f +00000010 +00000010 +00000011 +00000011 +00000012 +00000012 +00000013 +00000013 +00000014 +00000014 +00000015 +00000015 +00000016 +00000016 +00000017 +00000017 +00000018 +00000018 +00000019 +00000019 +0000001a +0000001a +0000001b +0000001b +0000001c +0000001c +0000001d +0000001d +0000001e +0000001e +0000001f +0000001f diff --git a/GOLDEN/sr_latch_tb.out.golden b/GOLDEN/sr_latch_tb.out.golden new file mode 100644 index 0000000..e0379d2 --- /dev/null +++ b/GOLDEN/sr_latch_tb.out.golden @@ -0,0 +1,17 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/SR_LATCH_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +00000042 +00000043 +00000047 +0000004b +0000004f +00000021 +00000023 +00000027 +0000002b +0000002f +0000005b +00000053 +00000037 +00000033 diff --git a/GOLDEN/twoscomp32_tb.out.golden b/GOLDEN/twoscomp32_tb.out.golden new file mode 100644 index 0000000..5e28566 --- /dev/null +++ b/GOLDEN/twoscomp32_tb.out.golden @@ -0,0 +1,5 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/TWOSCOMP32_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +fffffff6 +00000005 diff --git a/GOLDEN/twoscomp64_tb.out.golden b/GOLDEN/twoscomp64_tb.out.golden new file mode 100644 index 0000000..b344911 --- /dev/null +++ b/GOLDEN/twoscomp64_tb.out.golden @@ -0,0 +1,5 @@ +// memory data file (do not edit the following line - required for mem load use) +// instance=/TWOSCOMP64_TB/result +// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress +fffffffffffffff6 +0000000000000005 diff --git a/TESTBENCH/alu_tb.v b/TESTBENCH/alu_tb.v new file mode 100644 index 0000000..6bfd389 --- /dev/null +++ b/TESTBENCH/alu_tb.v @@ -0,0 +1,85 @@ +// Name: alu_tb.v +// Module: ALU_TB +// +// Notes: - Testbench for ALU +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "../prj_definition.v" + +module ALU_TB; +// reg list +reg [`DATA_INDEX_LIMIT:0] OP1; // operand 1 +reg [`DATA_INDEX_LIMIT:0] OP2; // operand 2 +reg [`ALU_OPRN_INDEX_LIMIT:0] OPRN; // operation code + +// output list +wire [`DATA_INDEX_LIMIT:0] OUT; // result of the operation. +wire ZERO; + +// results +integer ridx; +reg [`DATA_INDEX_LIMIT:0] result[199:0]; + +// Testcases +integer oprnd_idx, oprn_idx; +integer NumSet01[0:7]; +integer NumSet02[0:7]; +integer OpCode[0:8]; + +ALU alu_inst(.OUT(OUT), .ZERO(ZERO), .OP1(OP1), .OP2(OP2), .OPRN(OPRN)); + +initial +begin +// Initialize number sets +NumSet01[0] = 10; NumSet01[1] = -15; NumSet01[2] = 25; NumSet01[3] = -30; NumSet01[4] = 0; NumSet01[5] = -15; NumSet01[6] = 23; NumSet01[7] = 0; +NumSet02[0] = 10; NumSet02[1] = 15; NumSet02[2] = -25; NumSet02[3] = -30; NumSet02[4] = 0; NumSet02[5] = 42; NumSet02[6] = 0; NumSet02[7] = 70; +ridx = 0; + +// Set of operation +OpCode[0] = 1; // add +OpCode[1] = 2; // sub +OpCode[2] = 3; // mult +OpCode[3] = 4; // shiftR +OpCode[4] = 5; // shiftL +OpCode[5] = 6; // and +OpCode[6] = 7; // or +OpCode[7] = 8; // nor +OpCode[8] = 9; // slt + +// Loop through operands and operation +for(oprnd_idx=0; oprnd_idx<8; oprnd_idx=oprnd_idx+1) +begin + for(oprn_idx=0; oprn_idx<9; oprn_idx=oprn_idx+1) + begin + #1 OP1=NumSet01[oprnd_idx]; OP2=NumSet02[oprnd_idx]; OPRN=OpCode[oprn_idx]; + #1 + $write("===> %0d ",$signed(OP1)); + case(OPRN) + 1: $write("+"); + 2: $write("-"); + 3: $write("*"); + 4: $write(">>"); + 5: $write("<<"); + 6: $write("&"); + 7: $write("|"); + 8: $write("|~"); + 9: $write("slt"); + endcase + $write(" %0d = %0d [%d]\n", $signed(OP2), $signed(OUT), ZERO); + result[ridx] = OUT; ridx = ridx + 1; + result[ridx] = ZERO; ridx = ridx + 1; + end +end + +#1 +$writememh("./OUTPUT/alu_tb.out", result, 0, (ridx-1)); +$stop; + +end + +endmodule diff --git a/TESTBENCH/barrel_shifter_tb.v b/TESTBENCH/barrel_shifter_tb.v new file mode 100644 index 0000000..1121999 --- /dev/null +++ b/TESTBENCH/barrel_shifter_tb.v @@ -0,0 +1,80 @@ +// Name: barrel_shifter_tb.v +// Module: BARREL_SHIFTER32_TB +// +// Notes: - Testbench for shift module +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "../prj_definition.v" + +module BARREL_SHIFTER32_TB; +reg [31:0] D; +reg [31:0] S; +reg LnR; +wire [31:0] Y; + +integer reg_idx; +reg [`DATA_INDEX_LIMIT:0] result[0:63]; + +integer i, e; +integer no_of_test=0; +integer no_of_pass=0; + +SHIFT32 shift_inst(.Y(Y), .D(D), .S(S), .LnR(LnR)); + +initial +begin +reg_idx=0; +D=32'ha5a5a5a5; +S=32'h00000000; +LnR=1'b1; // left shift + +for(i=1; i<33; i=i+1) +begin +#5 +no_of_test = no_of_test + 1; +S=i; +e = D << S; +#5 +if (e !== Y) +begin + $write("[TEST %2d] (%8x << %8x) = %8x, got %8x ... FAILED\n", no_of_test, D, S, e, Y); +end +else + no_of_pass = no_of_pass + 1; +result[reg_idx] = Y; reg_idx=reg_idx+1; +end + +#5 LnR=1'b0; // right shift + +for(i=1; i<33; i=i+1) +begin +#5 +no_of_test = no_of_test + 1; +S=i; +e = D >> S; +#5 +if (e !== Y) +begin + $write("[TEST %2d] (%8x >> %8x) = %8x, got %8x ... FAILED\n", no_of_test, D, S, e, Y); +end +else + no_of_pass = no_of_pass + 1; +result[reg_idx] = Y; reg_idx=reg_idx+1; +end + +$write("\n"); +$write("\tTotal number of tests %d\n", no_of_test); +$write("\tTotal number of pass %d\n", no_of_pass); +$write("\n"); + +$writememh("./OUTPUT/barret_shifter_tb.out",result); + +$stop; +end + +endmodule diff --git a/TESTBENCH/da_vinci_tb.v b/TESTBENCH/da_vinci_tb.v new file mode 100644 index 0000000..49b534b --- /dev/null +++ b/TESTBENCH/da_vinci_tb.v @@ -0,0 +1,137 @@ +// Name: da_vinci_tb.v +// Module: DA_VINCI_TB +// +// Outputs are for testbench observations only +// +// Monitors: DATA : Data to be written at address ADDR +// ADDR : Address of the memory location to be accessed +// READ : Read signal +// WRITE: Write signal +// +// Input: DATA : Data read out in the read operation +// CLK : Clock signal +// RST : Reset signal +// +// Notes: - Testbench for DA_VINCI system +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "../prj_definition.v" +module DA_VINCI_TB; +// output list +wire [`ADDRESS_INDEX_LIMIT:0] ADDR; +wire READ, WRITE, CLK; +// inout list +wire [`DATA_INDEX_LIMIT:0] MEM_DATA_OUT, MEM_DATA_IN; + +// reset +reg RST; +integer t1=1, t2=1, t3=1, t4=1, t5=1; + +// Clock generator instance +CLK_GENERATOR clk_gen_inst(.CLK(CLK)); + +// DA_VINCI v1.0 instance +defparam da_vinci_inst.mem_init_file = "./TESTPROGRAM/fibonacci.dat"; +//defparam da_vinci_inst.mem_init_file = "RevFib.dat"; +DA_VINCI da_vinci_inst(.MEM_DATA_OUT(MEM_DATA_OUT), + .MEM_DATA_IN(MEM_DATA_IN), + .ADDR(ADDR), .READ(READ), + .WRITE(WRITE), .CLK(CLK), .RST(RST)); + +initial +begin + + + + RST=1'b1; + +if (t1 === 1) +begin +/* START : test 1*/ +#5 RST=1'b0; +#5 RST=1'b1; + $write("\n"); + $write("===> Simulating fibonacci.dat\n", ""); + $write("\n"); + $readmemh("./TESTPROGRAM/fibonacci.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m); +#5000 $write("\n"); + $write("===> Done simulating fibonacci.dat\n", ""); + $write("\n"); + $writememh("./OUTPUT/fibonacci_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h01000000, 'h0100000f); +/* END : test 1*/ +end + +if (t2 === 1) +begin +/* START : test 2*/ +#5 RST=1'b0; +#5 RST=1'b1; + $write("\n"); + $write("===> Simulating RevFib.dat\n", ""); + $write("\n"); + $readmemh("./TESTPROGRAM/RevFib.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m); +#5000 $write("\n"); + $write("===> Done simulating RevFib.dat\n", ""); + $write("\n"); + $writememh("./OUTPUT/RevFib_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h03fffff0, 'h03ffffff); +/* END : test 2*/ +end + +if (t3 === 1) +begin +/* START : test 3*/ +#5 RST=1'b0; +#5 RST=1'b1; + $write("\n"); + $write("===> Simulating CS147_SP17_HW01_02.dat\n", ""); + $write("\n"); + $readmemh("./TESTPROGRAM/CS147_SP17_HW01_02.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m); +#5000 $write("\n"); + $write("===> Done simulating CS147_SP17_HW01_02.dat\n", ""); + $write("\n"); + $writememh("./OUTPUT/CS147_SP17_HW01_02_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h01008000, 'h0100800A); +/* END : test 3*/ +end + +if (t4 === 1) +begin +/* START : test 4*/ +#5 RST=1'b0; +#5 RST=1'b1; + $write("\n"); + $write("===> Simulating CS147_FL15_HW01_02.dat\n", ""); + $write("\n"); + $readmemh("./TESTPROGRAM/CS147_FL15_HW01_02.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m); +#6000 $write("\n"); + $write("===> Done simulating CS147_FL15_HW01_02.dat\n", ""); + $write("\n"); + $writememh("./OUTPUT/CS147_FL15_HW01_02_mem_dump.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h03fffff6, 'h03ffffff); +/* END : test 4*/ +end + +if (t5 === 1) +begin +/* START : test 5*/ +#5 RST=1'b0; +#5 RST=1'b1; + $write("\n"); + $write("===> Simulating CS147_SP15_HW01_02.dat\n", ""); + $write("\n"); + $readmemh("./TESTPROGRAM/CS147_SP15_HW01_02.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m); +#5000 $write("\n"); + $write("===> Done simulating CS147_SP15_HW01_02.dat\n", ""); + $write("\n"); + $writememh("./OUTPUT/CS147_SP15_HW01_02_mem_dump_01.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h01008000, 'h01008005); + $writememh("./OUTPUT/CS147_SP15_HW01_02_mem_dump_02.dat", da_vinci_inst.memory_inst.memory_inst.sram_32x64m, 'h03fffffA, 'h03ffffff); +/* END : test 5*/ +end + $stop; + +end +endmodule; + diff --git a/TESTBENCH/full_adder_tb.v b/TESTBENCH/full_adder_tb.v new file mode 100644 index 0000000..7d7e786 --- /dev/null +++ b/TESTBENCH/full_adder_tb.v @@ -0,0 +1,40 @@ +// Name: full_adder_tb.v +// Module: FULL_ADDER_TB +// +// Notes: - Testbench for full adder +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "../prj_definition.v" + +module FULL_ADDER_TB; +reg A, B, CI; +wire S, CO; + +reg [`DATA_INDEX_LIMIT:0] result[0:7]; + +integer i; + +FULL_ADDER fa_inst(.S(S), .CO(CO), .A(A), .B(B), .CI(CI)); + +initial +begin +A=0; B=0; CI=0; +#1 result[0] = 32'h00000000 | {CO,S}; + +for(i=1; i<8; i=i+1) +begin +#1 CI=i[2]; A=i[1]; B=i[0]; +#1 result[i] = 32'h00000000 | {CO,S}; +end + +#1 +$writememh("./OUTPUT/full_adder.out",result); +$stop; + +end +endmodule diff --git a/TESTBENCH/half_adder_tb.v b/TESTBENCH/half_adder_tb.v new file mode 100644 index 0000000..629d517 --- /dev/null +++ b/TESTBENCH/half_adder_tb.v @@ -0,0 +1,41 @@ +// Name: half_adder_tb.v +// Module: HALF_ADDER_TB +// +// Notes: - Testbench for half adder +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "../prj_definition.v" + +module HALF_ADDER_TB; +reg A, B; +wire Y, C; + +reg [`DATA_INDEX_LIMIT:0] results[0:3]; + +HALF_ADDER ha_inst(.Y(Y), .C(C), .A(A), .B(B)); + +initial +begin +A=1'b0; B=1'b0; +#1 results[0] = 32'h00000000 | {C,Y}; + +#1 A=1'b0; B=1'b1; +#1 results[1] = 32'h00000000 | {C,Y}; + +#1 A=1'b1; B=1'b0; +#1 results[2] = 32'h00000000 | {C,Y}; + +#1 A=1'b1; B=1'b1; +#1 results[3] = 32'h00000000 | {C,Y}; + +#5 +$writememh("./OUTPUT/half_adder.out",results,0,3); +$stop; +end + +endmodule diff --git a/TESTBENCH/logic_32_bit_tb.v b/TESTBENCH/logic_32_bit_tb.v new file mode 100644 index 0000000..934fb37 --- /dev/null +++ b/TESTBENCH/logic_32_bit_tb.v @@ -0,0 +1,144 @@ +// Name: logic_32_bit_tb.v +// Module: NOR32_2x1_TB +// AND32_2x1_TB +// INV32_1x1_TB +// OR32_2x1_TB +// +// Notes: - Testbench for shift module +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "../prj_definition.v" + +module NOR32_2x1_TB; +//Driver +reg [31:0] A, B; +// Obsrver +wire [31:0] Y; + +// result +integer i; +reg [31:0] result [0:4]; + +NOR32_2x1 nor32_2x1_inst(.Y(Y), .A(A), .B(B)); + +initial +begin +i=0; +A=32'hFFFF0000; B=32'h0000FFFF; // Y = 32'h00000000 +#1 result[i] = Y; i=i+1; +#1 A=32'h00000000; B=32'h00000000; // Y=32'hFFFFFFFF +#1 result[i] = Y; i=i+1; +#1 A=32'hA5A5A5A5; B=32'h5A5A5A5A; // Y = 32'h00000000 +#1 result[i] = Y; i=i+1; +#1 A=32'hFFFF0000; B=32'hFFFF0000; // Y = 32'h0000FFFF +#1 result[i] = Y; i=i+1; +#1 A=32'h0000FFFF; B=32'h0000FFFF; // Y = 32'hFFFF0000 +#1 result[i] = Y; i=i+1; +#1 +$writememh("./OUTPUT/NOR32_2x1_TB.out",result); +$stop; +end + +endmodule + +module AND32_2x1_TB; +//Driver +reg [31:0] A, B; +// Obsrver +wire [31:0] Y; + +// result +integer i; +reg [31:0] result [0:4]; + +AND32_2x1 and32_2x1_inst(.Y(Y), .A(A), .B(B)); + +initial +begin +i=0; +A=32'hFFFF0000; B=32'h0000FFFF; // Y = 32'h00000000 +#1 result[i] = Y; i=i+1; +#1 A=32'h00000000; B=32'h00000000; // Y=32'h00000000 +#1 result[i] = Y; i=i+1; +#1 A=32'hA5A5A5A5; B=32'h5A5A5A5A; // Y = 32'h00000000 +#1 result[i] = Y; i=i+1; +#1 A=32'hFFFF0000; B=32'hFFFF0000; // Y = 32'hFFFF0000 +#1 result[i] = Y; i=i+1; +#1 A=32'h0000FFFF; B=32'h0000FFFF; // Y = 32'h0000FFFF +#1 result[i] = Y; i=i+1; +#1 +$writememh("./OUTPUT/AND32_2x1_TB.out",result); +$stop; +end + +endmodule + +module INV32_1x1_TB; + +//Driver +reg [31:0] A; +// Obsrver +wire [31:0] Y; + +// result +integer i; +reg [31:0] result [0:4]; + +INV32_1x1 inv32_1x1_inst(.Y(Y), .A(A)); + +initial +begin +i=0; +A=32'hFFFF0000; // Y = 32'h0000FFFF +#1 result[i] = Y; i=i+1; +#1 A=32'h00000000; // Y=32'hFFFFFFFF +#1 result[i] = Y; i=i+1; +#1 A=32'hA5A5A5A5; // Y = 32'h5A5A5A5A +#1 result[i] = Y; i=i+1; +#1 A=32'hFFFF0000; // Y = 32'h0000FFFF +#1 result[i] = Y; i=i+1; +#1 A=32'h0000FFFF; // Y = 32'hFFFF0000 +#1 result[i] = Y; i=i+1; +#1 +$writememh("./OUTPUT/INV32_1x1_TB.out",result); +$stop; +end + +endmodule + +module OR32_2x1_TB; +//Driver +reg [31:0] A, B; +// Obsrver +wire [31:0] Y; + +// result +integer i; +reg [31:0] result [0:4]; + +OR32_2x1 or32_2x1_inst(.Y(Y), .A(A), .B(B)); + +initial +begin +i=0; +A=32'hFFFF0000; B=32'h0000FFFF; // Y = 32'hFFFFFFFF +#1 result[i] = Y; i=i+1; +#1 A=32'h00000000; B=32'h00000000; // Y=32'h00000000 +#1 result[i] = Y; i=i+1; +#1 A=32'hA5A5A5A5; B=32'h5A5A5A5A; // Y = 32'hFFFFFFFF +#1 result[i] = Y; i=i+1; +#1 A=32'hFFFF0000; B=32'hFFFF0000; // Y = 32'hFFFF0000 +#1 result[i] = Y; i=i+1; +#1 A=32'h0000FFFF; B=32'h0000FFFF; // Y = 32'h0000FFFF +#1 result[i] = Y; i=i+1; +#1 +$writememh("./OUTPUT/OR32_2x1_TB.out",result); +$stop; +end + +endmodule \ No newline at end of file diff --git a/TESTBENCH/logic_tb.v b/TESTBENCH/logic_tb.v new file mode 100644 index 0000000..8b41da6 --- /dev/null +++ b/TESTBENCH/logic_tb.v @@ -0,0 +1,343 @@ +// Name: logic_tb.v +// Module: TWOSCOMP32_TB, +// TWOSCOMP64_TB, +// SR_LATCH_TB, +// D_LATCH_TB, +// D_FF_PE_TB, +// REG1_TB, +// REG32_TB, +// DECODER_5x32_TB +// +// Notes: - Testbench for multiplier +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "../prj_definition.v" + +module DECODER_5x32_TB; +// observer +wire [31:0] D; +// driver +reg [4:0] I; + +// result +integer i, idx; +reg [31:0] result[0:31]; + +DECODER_5x32 decoder_5x32_inst0(.D(D),.I(I)); + +initial +begin +i=0; + +for(idx=0; idx<32; idx = idx + 1) +begin +#1 I=idx; +#1 result[i] = D; i=i+1; +end + +#1 +$writememb("./OUTPUT/decoder_5x32_tb.out",result); +$stop; + +end + +endmodule + +module REG32_TB; +//driver +reg [`DATA_INDEX_LIMIT:0] D; +reg LOAD, RESET; +// oberver +wire [`DATA_INDEX_LIMIT:0] Q; +// clock +wire clk; + +// Result +integer i; +reg [`DATA_INDEX_LIMIT:0] result[0:7]; + +CLK_GENERATOR clk_gen_inst(.CLK(clk)); +REG32 reg32_inst(.Q(Q), .CLK(clk), .LOAD(LOAD), .D(D), .RESET(RESET)); + +initial +begin +i=0; RESET=1; D=32'ha5a5a5a5; LOAD=0; +// Reset +#1 D=32'ha5a5a5a5; LOAD=0; RESET=0; +#1 result[i] = Q; i=i+1; +// Hold +#1 D=32'ha5a5a5a5; LOAD=0; RESET=1; +#1 result[i] = Q; i=i+1; +// Normal operation +#6 D=32'ha5a5a5a5; LOAD=1; RESET=1; +#5 result[i] = Q; i=i+1; +#5 D=32'hffff0000; LOAD=1; RESET=1; +#5 result[i] = Q; i=i+1; +// Reset +#1 D=32'h0000ffff; LOAD=1; RESET=0; +#1 result[i] = Q; i=i+1; +// Normal operation +#9 D=32'h0000ffff; LOAD=1; RESET=1; +#1 result[i] = Q; i=i+1; +#10 result[i] = Q; i=i+1; +#10 D=32'h5a5a5a5a; LOAD=0; RESET=1; + +#10 +result[i] = Q; i=i+1; +$writememh("./OUTPUT/d_reg32_tb.out",result); +$stop; +end + +endmodule + +module REG1_TB; +//driver +reg D, L, nP, nR; +// oberver +wire Q,Qbar; +// clock +wire clk; + +// Result +integer i; +reg [`DATA_INDEX_LIMIT:0] result[0:6]; + +CLK_GENERATOR clk_gen_inst(.CLK(clk)); +REG1 reg1_inst(.Q(Q), .Qbar(Qbar), .C(clk), + .L(L), .D(D), .nP(nP), .nR(nR)); +initial +begin +i=0; nP=1; nR=1; D=0; L=0; +// Preset +#1 D=0; L=0; nP=0; nR=1; +#1 result[i] = {Q,Qbar,D,L,nR,nP}; i=i+1; +// Hold +#1 D=0; L=0; nP=1; nR=1; +#1 result[i] = {Q,Qbar,D,L,nR,nP}; i=i+1; +// Normal operation +#6 D=0; L=1; nP=1; nR=1; +#5 result[i] = {Q,Qbar,D,nR,nP}; i=i+1; +#5 D=1; L=1; nP=1; nR=1; +#5 result[i] = {Q,Qbar,D,L,nR,nP}; i=i+1; +// Reset +#1 D=1; L=1; nP=1; nR=0; +#1 result[i] = {Q,Qbar,D,L,nR,nP}; i=i+1; +// Normal operation +#9 D=1; L=1; nP=1; nR=1; +#1 result[i] = {Q,Qbar,D,L,nR,nP}; i=i+1; +#10 D=0; L=0; nP=1; nR=1; + +#10 +result[i] = {Q,Qbar,D,L,nR,nP}; i=i+1; +$writememh("./OUTPUT/d_reg1_tb.out",result); +$stop; +end + +endmodule + +module D_FF_TB; +//driver +reg D, nP, nR; +// oberver +wire Q,Qbar; +// clock +wire clk; + +// Result +integer i; +reg [`DATA_INDEX_LIMIT:0] result[0:6]; + +CLK_GENERATOR clk_gen_inst(.CLK(clk)); +D_FF d_ff_inst(.Q(Q), .Qbar(Qbar), .C(clk), + .D(D), .nP(nP), .nR(nR)); +initial +begin +i=0; nP=1; nR=1; D=0; +// Preset +#1 D=0; nP=0; nR=1; +#1 result[i] = {Q,Qbar,D,nR,nP}; i=i+1; +// Hold +#1 D=0; nP=1; nR=1; +#1 result[i] = {Q,Qbar,D,nR,nP}; i=i+1; +// Normal operation +#6 D=0; nP=1; nR=1; +#5 result[i] = {Q,Qbar,D,nR,nP}; i=i+1; +#5 D=1; nP=1; nR=1; +#5 result[i] = {Q,Qbar,D,nR,nP}; i=i+1; +// Reset +#1 D=1; nP=1; nR=0; +#1 result[i] = {Q,Qbar,D,nR,nP}; i=i+1; +// Normal operation +#9 D=1; nP=1; nR=1; +#1 result[i] = {Q,Qbar,D,nR,nP}; i=i+1; + +#10 +result[i] = {Q,Qbar,D,nR,nP}; i=i+1; +$writememh("./OUTPUT/d_ff_tb.out",result); +$stop; +end + +endmodule + +module D_LATCH_TB; +// driver +reg D, C, nP, nR; +// oberver +wire Q,Qbar; + +// Result +integer i; +reg [`DATA_INDEX_LIMIT:0] result[0:7]; + +D_LATCH d_latch_inst(.Q(Q), .Qbar(Qbar), .D(D), + .C(C), .nP(nP), .nR(nR)); + +initial +begin +i=0; +// Normal preset +#1 C=0; D=0; nR=1; nP=0; // Q=1 +#1 result[i] = {Q,Qbar,C,D,nR,nP}; i=i+1; +// Hold 1 on C=0 +#1 C=0; D=0; nR=1; nP=1; // Q=1 +#1 result[i] = {Q,Qbar,C,D,nR,nP}; i=i+1; +#1 C=0; D=1; nR=1; nP=1; // Q=1 +#1 result[i] = {Q,Qbar,C,D,nR,nP}; i=i+1; +// Normal reset +#1 C=0; D=0; nR=0; nP=1; // Q=0 +#1 result[i] = {Q,Qbar,C,D,nR,nP}; i=i+1; +// Hold 0 on C=0 +#1 C=0; D=0; nR=1; nP=1; // Q=0 +#1 result[i] = {Q,Qbar,C,D,nR,nP}; i=i+1; +#1 C=0; D=1; nR=1; nP=1; // Q=0 +#1 result[i] = {Q,Qbar,C,D,nR,nP}; i=i+1; +// Set on clock +#1 C=1; D=1; nR=1; nP=1; // Q=1 +#1 result[i] = {Q,Qbar,C,D,nR,nP}; i=i+1; +// Reset on clock +#1 C=1; D=0; nR=1; nP=1; // Q=0 +#1 result[i] = {Q,Qbar,C,D,nR,nP}; i=i+1; + +#1 +$writememh("./OUTPUT/d_latch_tb.out",result); +$stop; +end + +endmodule + +module SR_LATCH_TB; +// driver +reg S, R, C, nP, nR; +// oberver +wire Q,Qbar; + +// Result +integer i; +reg [`DATA_INDEX_LIMIT:0] result[0:13]; + +SR_LATCH sr_latch_inst(.Q(Q), .Qbar(Qbar), .S(S), + .R(R), .C(C), .nP(nP), .nR(nR)); + +initial +begin +i=0; +// Normal reset preset +#1 C=0; S=0; R=0; nR=1; nP=0; // Q=1 +#1 result[i] = {Q,Qbar,C,S,R,nR,nP}; i=i+1; +// Hold 1 on C=0 +#1 C=0; S=0; R=0; nR=1; nP=1; // Q=1 +#1 result[i] = {Q,Qbar,C,S,R,nR,nP}; i=i+1; +#1 C=0; S=0; R=1; nR=1; nP=1; // Q=1 +#1 result[i] = {Q,Qbar,C,S,R,nR,nP}; i=i+1; +#1 C=0; S=1; R=0; nR=1; nP=1; // Q=1 +#1 result[i] = {Q,Qbar,C,S,R,nR,nP}; i=i+1; +#1 C=0; S=1; R=1; nR=1; nP=1; // Q=1 +#1 result[i] = {Q,Qbar,C,S,R,nR,nP}; i=i+1; +// Normal reset +#1 C=0; S=0; R=0; nR=0; nP=1; // Q=0 +#1 result[i] = {Q,Qbar,C,S,R,nR,nP}; i=i+1; +// Hold 0 on C=0 +#1 C=0; S=0; R=0; nR=1; nP=1; // Q=0 +#1 result[i] = {Q,Qbar,C,S,R,nR,nP}; i=i+1; +#1 C=0; S=0; R=1; nR=1; nP=1; // Q=0 +#1 result[i] = {Q,Qbar,C,S,R,nR,nP}; i=i+1; +#1 C=0; S=1; R=0; nR=1; nP=1; // Q=0 +#1 result[i] = {Q,Qbar,C,S,R,nR,nP}; i=i+1; +#1 C=0; S=1; R=1; nR=1; nP=1; // Q=0 +#1 result[i] = {Q,Qbar,C,S,R,nR,nP}; i=i+1; +// Set on clock +#1 C=1; S=1; R=0; nR=1; nP=1; // Q=1 +#1 result[i] = {Q,Qbar,C,S,R,nR,nP}; i=i+1; +// Hold +#1 C=1; S=0; R=0; nR=1; nP=1; // Q=1 +#1 result[i] = {Q,Qbar,C,S,R,nR,nP}; i=i+1; +// Reset on clock +#1 C=1; S=0; R=1; nR=1; nP=1; // Q=0 +#1 result[i] = {Q,Qbar,C,S,R,nR,nP}; i=i+1; +// Hold +#1 C=1; S=0; R=0; nR=1; nP=1; // Q=0 +#1 result[i] = {Q,Qbar,C,S,R,nR,nP}; i=i+1; + +#1 +$writememh("./OUTPUT/sr_latch_tb.out",result); +$stop; +end + +endmodule + +module TWOSCOMP32_TB; +// driver +reg [`DATA_INDEX_LIMIT:0] A; +// wire +wire [`DATA_INDEX_LIMIT:0] Y; + +// result +integer i; +reg [`DATA_INDEX_LIMIT:0] result[0:1]; + +TWOSCOMP32 inst_2scomp_01(.Y(Y), .A(A)); + +initial +begin +i=0; +A = 10; +#1 result[i] = Y; i = i + 1; +#1 A=-5; +#1 result[i] = Y; i = i + 1; +#1 +$writememh("./OUTPUT/twoscomp32_tb.out",result); +$stop; +end + +endmodule + +module TWOSCOMP64_TB; +// driver +reg [`DOUBLE_DATA_INDEX_LIMIT:0] A; +// wire +wire [`DOUBLE_DATA_INDEX_LIMIT:0] Y; + +// result +integer i; +reg [`DOUBLE_DATA_INDEX_LIMIT:0] result[0:1]; + +TWOSCOMP64 inst_2scomp_01(.Y(Y), .A(A)); + +initial +begin +i=0; +A = 10; +#1 result[i] = Y; i = i + 1; +#1 A=-5; +#1 result[i] = Y; i = i + 1; +#1 +$writememh("./OUTPUT/twoscomp64_tb.out",result); +$stop; +end + +endmodule \ No newline at end of file diff --git a/TESTBENCH/mem_64MB_tb.v b/TESTBENCH/mem_64MB_tb.v new file mode 100644 index 0000000..4bddccb --- /dev/null +++ b/TESTBENCH/mem_64MB_tb.v @@ -0,0 +1,111 @@ +// Name: proj_2_tb.v +// Module: DA_VINCI_TB +// +// +// Monitors: DATA : Data to be written at address ADDR +// ADDR : Address of the memory location to be accessed +// READ : Read signal +// WRITE: Write signal +// +// Input: DATA : Data read out in the read operation +// CLK : Clock signal +// RST : Reset signal +// +// Notes: - Testbench for MEMORY_64MB memory system +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "../prj_definition.v" +module MEM_64MB_TB; +// Storage list +reg [`ADDRESS_INDEX_LIMIT:0] ADDR; +// reset +reg READ, WRITE, RST; +// data register +reg [`DATA_INDEX_LIMIT:0] DATA_REG; +integer i; // index for memory operation +integer no_of_test, no_of_pass; +integer load_data; + +// wire lists +wire CLK; +wire [`DATA_INDEX_LIMIT:0] DATA; + +assign DATA = ((READ===1'b0)&&(WRITE===1'b1))?DATA_REG:{`DATA_WIDTH{1'bz} }; + +// Clock generator instance +CLK_GENERATOR clk_gen_inst(.CLK(CLK)); + +// 64MB memory instance +defparam mem_inst.mem_init_file = "mem_content_01.dat"; +MEMORY_64MB mem_inst(.DATA(DATA), .ADDR(ADDR), .READ(READ), + .WRITE(WRITE), .CLK(CLK), .RST(RST)); + +initial +begin +RST=1'b1; +READ=1'b0; +WRITE=1'b0; +DATA_REG = {`DATA_WIDTH{1'b0} }; +no_of_test = 0; +no_of_pass = 0; +load_data = 'h00414020; + +// Start the operation +#10 RST=1'b0; +#10 RST=1'b1; +// Write cycle +for(i=1;i<10; i = i + 1) +begin +#10 DATA_REG=i; READ=1'b0; WRITE=1'b1; ADDR = i; +end + +// Read Cycle +#10 READ=1'b0; WRITE=1'b0; +#5 no_of_test = no_of_test + 1; + if (DATA !== {`DATA_WIDTH{1'bz}}) + $write("[TEST] Read %1b, Write %1b, expecting 32'hzzzzzzzz, got %8h [FAILED]\n", READ, WRITE, DATA); + else + no_of_pass = no_of_pass + 1; + +// test of write data +for(i=0;i<10; i = i + 1) +begin +#5 READ=1'b1; WRITE=1'b0; ADDR = i; +#5 no_of_test = no_of_test + 1; + if (DATA !== i) + $write("[TEST] Read %1b, Write %1b, expecting %8h, got %8h [FAILED]\n", READ, WRITE, i, DATA); + else + no_of_pass = no_of_pass + 1; + +end + +// test for the initialize data +for(i='h001000; i<'h001010; i = i + 1) +begin +#5 READ=1'b1; WRITE=1'b0; ADDR = i; +#5 no_of_test = no_of_test + 1; + if (DATA !== load_data) + $write("[TEST] Read %1b, Write %1b, Addr %7h, expecting %8h, got %8h [FAILED]\n", + READ, WRITE, ADDR, load_data, DATA); + else + no_of_pass = no_of_pass + 1; + load_data = load_data + 1; +end +#10 READ=1'b0; WRITE=1'b0; // No op + +#10 $write("\n"); + $write("\tTotal number of tests %d\n", no_of_test); + $write("\tTotal number of pass %d\n", no_of_pass); + $write("\n"); + $writememh("./OUTPUT/mem_dump_01.dat", mem_inst.sram_32x64m, 'h0000000, 'h000000f); + $writememh("./OUTPUT/mem_dump_02.dat", mem_inst.sram_32x64m, 'h0001000, 'h000100f); + $stop; + +end +endmodule; + diff --git a/TESTBENCH/mult_tb.v b/TESTBENCH/mult_tb.v new file mode 100644 index 0000000..3111ef0 --- /dev/null +++ b/TESTBENCH/mult_tb.v @@ -0,0 +1,86 @@ +// Name: mult_tb.v +// Module: MULT_U_TB, MULT_TB +// +// Notes: - Testbench for multiplier +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "../prj_definition.v" + +module MULT_U_TB; +// driver +reg [`DATA_INDEX_LIMIT:0] A; +reg [`DATA_INDEX_LIMIT:0] B; + +// outputs to observe +wire [`DATA_INDEX_LIMIT:0] HI, LO; + +// result registers +integer i; +reg [`DOUBLE_DATA_INDEX_LIMIT:0] result[0:4]; + +MULT32_U mult32_u_inst_0(.HI(HI), .LO(LO), .A(A), .B(B)); + +initial +begin +i=0; +A=10; B=20; // Y = 10 * 20 = 200 +#1 result[i] = {HI,LO}; i=i+1; +#1 A=3; B=15; // Y = 3 * 15 = 45 +#1 result[i] = {HI,LO}; i=i+1; +#1 A=16; B=7; // Y = 16 * 7 = 112 +#1 result[i] = {HI,LO}; i=i+1; +#1 A=10; B=19; // Y = 10 * 19 = 190 +#1 result[i] = {HI,LO}; i=i+1; +#1 A=32'h70000000; B=32'h70000000; +#1 result[i] = {HI,LO}; i=i+1; +#1 +$writememh("./OUTPUT/mult32_u_tb.out", result); +$stop; +end + +endmodule + +module MULT_TB; +// driver +reg [`DATA_INDEX_LIMIT:0] A; +reg [`DATA_INDEX_LIMIT:0] B; + +// outputs to observe +wire [`DATA_INDEX_LIMIT:0] HI, LO; + +// result registers +integer i; +reg [`DOUBLE_DATA_INDEX_LIMIT:0] result[0:7]; + +MULT32 mult32_inst_0(.HI(HI), .LO(LO), .A(A), .B(B)); + +initial +begin +i=0; +A=10; B=20; // Y = 10 * 20 = 200 +#1 result[i] = {HI,LO}; i=i+1; +#1 A=-3; B=-15; // Y = 3 * 15 = 45 +#1 result[i] = {HI,LO}; i=i+1; +#1 A=-16; B=7; // Y = 16 * 7 = -112 +#1 result[i] = {HI,LO}; i=i+1; +#1 A=10; B=-19; // Y = 10 * 19 = -190 +#1 result[i] = {HI,LO}; i=i+1; +#1 A=32'h70000000; B=32'h70000000; +#1 result[i] = {HI,LO}; i=i+1; +#1 A=32'h90000000; B=32'h70000000; +#1 result[i] = {HI,LO}; i=i+1; +#1 A=32'h70000000; B=32'h90000000; +#1 result[i] = {HI,LO}; i=i+1; +#1 A=32'h90000000; B=32'h90000000; +#1 result[i] = {HI,LO}; i=i+1; +#1 +$writememh("./OUTPUT/mult32_tb.out", result); +$stop; +end + +endmodule diff --git a/TESTBENCH/mux_tb.v b/TESTBENCH/mux_tb.v new file mode 100644 index 0000000..e5a485f --- /dev/null +++ b/TESTBENCH/mux_tb.v @@ -0,0 +1,109 @@ +// Name: mux32_tb.v +// Module: MUX32_2x1_TB +// MUX32_16x1_TB +// MUX32_32x1_TB +// +// Notes: - Testbench for different multiplexer +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "../prj_definition.v" + +module MUX32_32x1_TB; + +reg [31:0] I [0:31]; +reg [4:0] S; +wire [31:0] Y; + +integer i; +reg [31:0] result [0:31]; + +MUX32_32x1 mux_inst_01(.Y(Y), + .I0(I[0]), .I1(I[1]), .I2(I[2]), .I3(I[3]), + .I4(I[4]), .I5(I[5]), .I6(I[6]), .I7(I[7]), + .I8(I[8]), .I9(I[9]), .I10(I[10]), .I11(I[11]), + .I12(I[12]), .I13(I[13]), .I14(I[14]), .I15(I[15]), + .I16(I[16]), .I17(I[17]), .I18(I[18]), .I19(I[19]), + .I20(I[20]), .I21(I[21]), .I22(I[22]), .I23(I[23]), + .I24(I[24]), .I25(I[25]), .I26(I[26]), .I27(I[27]), + .I28(I[28]), .I29(I[29]), .I30(I[30]), .I31(I[31]), + .S(S)); + +initial +begin +for(i=0;i<32;i=i+1) + I[i]=i; + +for(i=0;i<32;i=i+1) +begin +#1 S = i; +#1 result[i]=Y; +end + +#1 +$writememh("./OUTPUT/mux32_32x1_tb.out", result); +$stop; +end + +endmodule + +module MUX32_16x1_TB; + +reg [31:0] I [0:15]; +reg [3:0] S; +wire [31:0] Y; + +integer i; +reg [31:0] result [0:15]; + +MUX32_16x1 mux_inst_01(.Y(Y), + .I0(I[0]), .I1(I[1]), .I2(I[2]), .I3(I[3]), + .I4(I[4]), .I5(I[5]), .I6(I[6]), .I7(I[7]), + .I8(I[8]), .I9(I[9]), .I10(I[10]), .I11(I[11]), + .I12(I[12]), .I13(I[13]), .I14(I[14]), .I15(I[15]), + .S(S)); + +initial +begin +for(i=0;i<16;i=i+1) + I[i]=i; + +for(i=0;i<16;i=i+1) +begin +#1 S = i; +#1 result[i]=Y; +end + +#1 +$writememh("./OUTPUT/mux32_16x1_tb.out", result); +$stop; +end + +endmodule + +module MUX32_2x1_TB; + +reg [31:0] I0, I1; +reg S; +wire [31:0] Y; + +reg [31:0] result [0:1]; + +MUX32_2x1 mux_inst_01(.Y(Y), .I0(I0), .I1(I1), .S(S)); + +initial +begin +I0 = 32'hA5A5A5A5; I1 = 32'h5A5A5A5A; S=1'b0; +#1 result[0] = Y; +#1 S=1'b1; +#1 result[1] = Y; +#1 +$writememh("./OUTPUT/mux32_2x1_tb.out", result); +$stop; +end + +endmodule diff --git a/TESTBENCH/rc_add_sub_32_tb.v b/TESTBENCH/rc_add_sub_32_tb.v new file mode 100644 index 0000000..2739ae4 --- /dev/null +++ b/TESTBENCH/rc_add_sub_32_tb.v @@ -0,0 +1,46 @@ +// Name: rc_add_sub_32_tb.v +// Module: RC_ADD_SUB_32_TB +// +// Notes: - Testbench for RC adder/asubtractor +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "../prj_definition.v" + +module RC_ADD_SUB_32_TB; +// driver +reg [`DATA_INDEX_LIMIT:0] A; +reg [`DATA_INDEX_LIMIT:0] B; +reg SnA; +// outputs to observe +wire CO; +wire [`DATA_INDEX_LIMIT:0] Y; + +integer i; +reg [`DATA_INDEX_LIMIT:0] result[0:4]; + +RC_ADD_SUB_32 rc_add_sub_inst(.Y(Y), .CO(CO), .A(A), .B(B), .SnA(SnA)); + +initial +begin +i=0; +A=10; B=20; SnA=1'b0; // Y = 10 + 20 = 30 +#1 result[i] = Y; i=i+1; +#1 A=10; B=20; SnA=1'b1; // Y = 10 - 20 = -10 +#1 result[i] = Y; i=i+1; +#1 A=15; B=12; SnA=1'b1; // Y = 15 - 12 = 3 +#1 result[i] = Y; i=i+1; +#1 A=0; B=4; SnA=1'b0; // Y = 0 + 4 = 4 +#1 result[i] = Y; i=i+1; +#1 A=32'h80001234; B=32'h80004321; SnA=1'b0; +#1 result[i] = Y; i=i+1; +#1 +$writememh("./OUTPUT/rc_add_sub_32.out",result); +$stop; +end + +endmodule diff --git a/TESTBENCH/register_file_tb.v b/TESTBENCH/register_file_tb.v new file mode 100644 index 0000000..89056ae --- /dev/null +++ b/TESTBENCH/register_file_tb.v @@ -0,0 +1,102 @@ +// Name: proj_2_tb.v +// Module: RF_TB +// +// +// Monitors: DATA : Data to be written at address ADDR +// ADDR : Address of the memory location to be accessed +// READ : Read signal +// WRITE: Write signal +// +// Input: DATA : Data read out in the read operation +// CLK : Clock signal +// RST : Reset signal +// +// Notes: - Testbench for MEMORY_64MB memory system +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "../prj_definition.v" +module RF_TB; +// Storage list +reg [`REG_ADDR_INDEX_LIMIT:0] ADDR_W; +reg [`REG_ADDR_INDEX_LIMIT:0] ADDR_R1; +reg [`REG_ADDR_INDEX_LIMIT:0] ADDR_R2; +// reset +reg READ, WRITE, RST; +// data register +reg [`DATA_INDEX_LIMIT:0] DATA_REG; +integer i; // index for memory operation +integer no_of_test, no_of_pass; +integer load_data; + +// wire lists +wire CLK; +wire [`DATA_INDEX_LIMIT:0] DATA_R1; +wire [`DATA_INDEX_LIMIT:0] DATA_R2; + +// result +integer ridx; +reg [`DATA_INDEX_LIMIT:0] result [0:63]; + +// Clock generator instance +CLK_GENERATOR clk_gen_inst(.CLK(CLK)); + +// 64MB memory instance +REGISTER_FILE_32x32 ref_32x32_inst(.DATA_R1(DATA_R1), .DATA_R2(DATA_R2), .ADDR_R1(ADDR_R1), + .ADDR_R2(ADDR_R2), .DATA_W(DATA_REG), .ADDR_W(ADDR_W), + .READ(READ), .WRITE(WRITE), .CLK(CLK), .RST(RST)); + +initial +begin +ridx=0; +RST=1'b1; +READ=1'b0; +WRITE=1'b0; +DATA_REG = {`DATA_WIDTH{1'b0} }; +ADDR_R1 = {`DATA_WIDTH{1'b0} }; +ADDR_R2 = {`DATA_WIDTH{1'b0} }; +no_of_test = 0; +no_of_pass = 0; + +// Start the operation +#10 RST=1'b0; +#10 RST=1'b1; +// Write cycle +for(i=0;i<32; i = i + 1) +begin +#10 DATA_REG=i; READ=1'b0; WRITE=1'b1; ADDR_W = i; +end + +#5 READ=1'b0; WRITE=1'b0; +// test of write data +for(i=0;i<32; i = i + 1) +begin +#5 READ=1'b1; WRITE=1'b0; ADDR_R1 = i; ADDR_R2 = i; +#5 no_of_test = no_of_test + 1; + if (DATA_R1 !== i) + $write("[TEST @ %0dns] Read %1b, Write %1b, expecting %8h, got %8h [FAILED]\n", $time, READ, WRITE, i, DATA_R1); + else + no_of_pass = no_of_pass + 1; + result[ridx] = DATA_R1; ridx=ridx+1; + result[ridx] = DATA_R1; ridx=ridx+1; + +end + + +#5 READ=1'b0; WRITE=1'b0; // No op + +#10 $write("\n"); + $write("\tTotal number of tests %d\n", no_of_test); + $write("\tTotal number of pass %d\n", no_of_pass); + $write("\n"); + + $writememh("./OUTPUT/rf_tb.out",result); + $stop; + +end +endmodule + diff --git a/alu.v b/alu.v new file mode 100644 index 0000000..4262d9c --- /dev/null +++ b/alu.v @@ -0,0 +1,37 @@ +// Name: alu.v +// Module: ALU +// Input: OP1[32] - operand 1 +// OP2[32] - operand 2 +// OPRN[6] - operation code +// Output: OUT[32] - output result for the operation +// +// Notes: 32 bit combinatorial ALU +// +// Supports the following functions +// - Integer add (0x1), sub(0x2), mul(0x3) +// - Integer shift_rigth (0x4), shift_left (0x5) +// - Bitwise and (0x6), or (0x7), nor (0x8) +// - set less than (0x9) +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +// +`include "prj_definition.v" +module ALU(OUT, ZERO, OP1, OP2, OPRN); +// input list +input [`DATA_INDEX_LIMIT:0] OP1; // operand 1 +input [`DATA_INDEX_LIMIT:0] OP2; // operand 2 +input [`ALU_OPRN_INDEX_LIMIT:0] OPRN; // operation code + +// output list +output [`DATA_INDEX_LIMIT:0] OUT; // result of the operation. +output ZERO; + +// TBD + + +endmodule diff --git a/barrel_shifter.v b/barrel_shifter.v new file mode 100644 index 0000000..39e1b5f --- /dev/null +++ b/barrel_shifter.v @@ -0,0 +1,64 @@ +// Name: barrel_shifter.v +// Module: SHIFT32_L , SHIFT32_R, SHIFT32 +// +// Notes: 32-bit barrel shifter +// +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "prj_definition.v" + +// 32-bit shift amount shifter +module SHIFT32(Y,D,S, LnR); +// output list +output [31:0] Y; +// input list +input [31:0] D; +input [31:0] S; +input LnR; + +// TBD + +endmodule + +// Shift with control L or R shift +module BARREL_SHIFTER32(Y,D,S, LnR); +// output list +output [31:0] Y; +// input list +input [31:0] D; +input [4:0] S; +input LnR; + +// TBD + +endmodule + +// Right shifter +module SHIFT32_R(Y,D,S); +// output list +output [31:0] Y; +// input list +input [31:0] D; +input [4:0] S; + +// TBD + +endmodule + +// Left shifter +module SHIFT32_L(Y,D,S); +// output list +output [31:0] Y; +// input list +input [31:0] D; +input [4:0] S; + +// TBD + +endmodule + diff --git a/clk_gen.v b/clk_gen.v new file mode 100644 index 0000000..de91b0f --- /dev/null +++ b/clk_gen.v @@ -0,0 +1,32 @@ +// Name: clk_gen.v +// Module: CLK_GENERATOR +// +// Output: CLK - output clock with period `SYS_CLK_FREQ +// +// Notes: Clock generator. The clock frequency is defined in the project definition file. +// +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "prj_definition.v" +module CLK_GENERATOR(CLK); +// output list; +output CLK; + +// storage for clock value +reg CLK; + +initial +begin +CLK = 1'b1; +end +// For ever perform the following task. +always +begin +#`SYS_CLK_HALF_PERIOD CLK <= ~CLK; +end +endmodule; diff --git a/control_unit.v b/control_unit.v new file mode 100644 index 0000000..b2bda1c --- /dev/null +++ b/control_unit.v @@ -0,0 +1,61 @@ +// Name: control_unit.v +// Module: CONTROL_UNIT +// Output: CTRL : Control signal for data path +// READ : Memory read signal +// WRITE : Memory Write signal +// +// Input: ZERO : Zero status from ALU +// CLK : Clock signal +// RST : Reset Signal +// +// Notes: - Control unit synchronize operations of a processor +// Assign each bit of control signal to control one part of data path +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "prj_definition.v" +module CONTROL_UNIT(CTRL, READ, WRITE, ZERO, INSTRUCTION, CLK, RST); +// Output signals +output [`CTRL_WIDTH_INDEX_LIMIT:0] CTRL; +output READ, WRITE; + +// input signals +input ZERO, CLK, RST; +input [`DATA_INDEX_LIMIT:0] INSTRUCTION; + +// TBD - take action on each +ve edge of clock + +endmodule + + +//------------------------------------------------------------------------------------------ +// Module: PROC_SM +// Output: STATE : State of the processor +// +// Input: CLK : Clock signal +// RST : Reset signal +// +// INOUT: MEM_DATA : Data to be read in from or write to the memory +// +// Notes: - Processor continuously cycle witnin fetch, decode, execute, +// memory, write back state. State values are in the prj_definition.v +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +module PROC_SM(STATE,CLK,RST); +// list of inputs +input CLK, RST; +// list of outputs +output [2:0] STATE; + +// TBD - take action on each +ve edge of clock + +endmodule \ No newline at end of file diff --git a/da_vinci.v b/da_vinci.v new file mode 100644 index 0000000..fe37f4f --- /dev/null +++ b/da_vinci.v @@ -0,0 +1,44 @@ +// Name: da_vinci.v +// Module: DA_VINCI +// +// Outputs are for testbench observations only +// +// Output: DATA : Data to be written at address ADDR +// ADDR : Address of the memory location to be accessed +// READ : Read signal +// WRITE: Write signal +// +// Input: DATA : Data read out in the read operation +// CLK : Clock signal +// RST : Reset signal +// +// Notes: - 32 bit bareminimum computer system DA_VINCI_v1.0 implementing cs147sec05 instruction set +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "prj_definition.v" +module DA_VINCI (MEM_DATA_OUT, MEM_DATA_IN, ADDR, READ, WRITE, CLK, RST); +// Parameter for the memory initialization file name +parameter mem_init_file = "mem_content_01.dat"; +// output list +output [`ADDRESS_INDEX_LIMIT:0] ADDR; +output [`DATA_INDEX_LIMIT:0] MEM_DATA_OUT, MEM_DATA_IN; +output READ, WRITE; +// input list +input CLK, RST; + +// Instance section +// Processor instanceIN +PROC_CS147_SEC05 processor_inst(.DATA_IN(MEM_DATA_OUT), .DATA_OUT(MEM_DATA_IN), + .ADDR(ADDR), .READ(READ), + .WRITE(WRITE), .CLK(CLK), .RST(RST)); +// memory instance +defparam memory_inst.mem_init_file = mem_init_file; +MEMORY_WRAPPER memory_inst(.DATA_OUT(MEM_DATA_OUT), .DATA_IN(MEM_DATA_IN), + .READ(READ), .WRITE(WRITE), + .ADDR(ADDR), .CLK(CLK), .RST(RST)); +endmodule; \ No newline at end of file diff --git a/data_path.v b/data_path.v new file mode 100644 index 0000000..1a03fd3 --- /dev/null +++ b/data_path.v @@ -0,0 +1,34 @@ +// Name: data_path.v +// Module: DATA_PATH +// Output: DATA : Data to be written at address ADDR +// ADDR : Address of the memory location to be accessed +// +// Input: DATA : Data read out in the read operation +// CLK : Clock signal +// RST : Reset signal +// +// Notes: - 32 bit processor implementing cs147sec05 instruction set +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +// +`include "prj_definition.v" +module DATA_PATH(DATA_OUT, ADDR, ZERO, INSTRUCTION, DATA_IN, CTRL, CLK, RST); + +// output list +output [`ADDRESS_INDEX_LIMIT:0] ADDR; +output ZERO; +output [`DATA_INDEX_LIMIT:0] DATA_OUT, INSTRUCTION; + +// input list +input [`CTRL_WIDTH_INDEX_LIMIT:0] CTRL; +input CLK, RST; +input [`DATA_INDEX_LIMIT:0] DATA_IN; + +// TBD + +endmodule diff --git a/full_adder.v b/full_adder.v new file mode 100644 index 0000000..f1f1f83 --- /dev/null +++ b/full_adder.v @@ -0,0 +1,28 @@ +// Name: full_adder.v +// Module: FULL_ADDER +// +// Output: S : Sum +// CO : Carry Out +// +// Input: A : Bit 1 +// B : Bit 2 +// CI : Carry In +// +// Notes: 1-bit full adder implementaiton. +// +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "prj_definition.v" + +module FULL_ADDER(S,CO,A,B, CI); +output S,CO; +input A,B, CI; + +//TBD + +endmodule; diff --git a/half_adder.v b/half_adder.v new file mode 100644 index 0000000..13cc43c --- /dev/null +++ b/half_adder.v @@ -0,0 +1,27 @@ +// Name: half_adder.v +// Module: HALF_ADDER +// +// Output: Y : Sum +// C : Carry +// +// Input: A : Bit 1 +// B : Bit 2 +// +// Notes: 1-bit half adder implementaiton. +// +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "prj_definition.v" + +module HALF_ADDER(Y,C,A,B); +output Y,C; +input A,B; + +// TBD + +endmodule; \ No newline at end of file diff --git a/logic.v b/logic.v new file mode 100644 index 0000000..96583f5 --- /dev/null +++ b/logic.v @@ -0,0 +1,146 @@ +// Name: logic.v +// Module: +// Input: +// Output: +// +// Notes: Common definitions +// +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 02, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +// +// 64-bit two's complement +module TWOSCOMP64(Y,A); +//output list +output [63:0] Y; +//input list +input [63:0] A; + +// TBD + +endmodule + +// 32-bit two's complement +module TWOSCOMP32(Y,A); +//output list +output [31:0] Y; +//input list +input [31:0] A; + +// TBD + +endmodule + +// 32-bit registere +ve edge, Reset on RESET=0 +module REG32(Q, D, LOAD, CLK, RESET); +output [31:0] Q; + +input CLK, LOAD; +input [31:0] D; +input RESET; + +// TBD + +endmodule + +// 1 bit register +ve edge, +// Preset on nP=0, nR=1, reset on nP=1, nR=0; +// Undefined nP=0, nR=0 +// normal operation nP=1, nR=1 +module REG1(Q, Qbar, D, L, C, nP, nR); +input D, C, L; +input nP, nR; +output Q,Qbar; + +// TBD + +endmodule + +// 1 bit flipflop +ve edge, +// Preset on nP=0, nR=1, reset on nP=1, nR=0; +// Undefined nP=0, nR=0 +// normal operation nP=1, nR=1 +module D_FF(Q, Qbar, D, C, nP, nR); +input D, C; +input nP, nR; +output Q,Qbar; + +// TBD + +endmodule + +// 1 bit D latch +// Preset on nP=0, nR=1, reset on nP=1, nR=0; +// Undefined nP=0, nR=0 +// normal operation nP=1, nR=1 +module D_LATCH(Q, Qbar, D, C, nP, nR); +input D, C; +input nP, nR; +output Q,Qbar; + +// TBD + +endmodule + +// 1 bit SR latch +// Preset on nP=0, nR=1, reset on nP=1, nR=0; +// Undefined nP=0, nR=0 +// normal operation nP=1, nR=1 +module SR_LATCH(Q,Qbar, S, R, C, nP, nR); +input S, R, C; +input nP, nR; +output Q,Qbar; + +// TBD + +endmodule + +// 5x32 Line decoder +module DECODER_5x32(D,I); +// output +output [31:0] D; +// input +input [4:0] I; + +// TBD + +endmodule + +// 4x16 Line decoder +module DECODER_4x16(D,I); +// output +output [15:0] D; +// input +input [3:0] I; + +// TBD + + +endmodule + +// 3x8 Line decoder +module DECODER_3x8(D,I); +// output +output [7:0] D; +// input +input [2:0] I; + +//TBD + + +endmodule + +// 2x4 Line decoder +module DECODER_2x4(D,I); +// output +output [3:0] D; +// input +input [1:0] I; + +// TBD + +endmodule \ No newline at end of file diff --git a/logic_32_bit.v b/logic_32_bit.v new file mode 100644 index 0000000..e3d87b5 --- /dev/null +++ b/logic_32_bit.v @@ -0,0 +1,62 @@ +// Name: logic_32_bit.v +// Module: +// Input: +// Output: +// +// Notes: Common definitions +// +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 02, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +// + +// 32-bit NOR +module NOR32_2x1(Y,A,B); +//output +output [31:0] Y; +//input +input [31:0] A; +input [31:0] B; + +// TBD + +endmodule + +// 32-bit AND +module AND32_2x1(Y,A,B); +//output +output [31:0] Y; +//input +input [31:0] A; +input [31:0] B; + +// TBD + +endmodule + +// 32-bit inverter +module INV32_1x1(Y,A); +//output +output [31:0] Y; +//input +input [31:0] A; + +// TBD + +endmodule + +// 32-bit OR +module OR32_2x1(Y,A,B); +//output +output [31:0] Y; +//input +input [31:0] A; +input [31:0] B; + +// TBD + +endmodule diff --git a/memory.v b/memory.v new file mode 100644 index 0000000..95e66f3 --- /dev/null +++ b/memory.v @@ -0,0 +1,99 @@ +// Name: memory.v +// Module: MEMORY_64MB +// Input: DATA : Data to be written at address ADDR +// ADDR : Address of the memory location to be accessed +// READ : Read signal +// WRITE: Write signal +// CLK : Clock signal +// RST : Reset signal +// Output: DATA : Data read out in the read operation +// +// Notes: - 32 bit word accessible 64MB memory. +// - Reset is done at -ve edge of the RST signal +// - Rest of the operation is done at the +ve edge of the CLK signal +// - Read operation is done if READ=1 and WRITE=0 +// - Write operation is done if WRITE=1 and READ=0 +// - X is the value at DATA if both READ and WRITE are 0 or 1 +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +// +`include "prj_definition.v" +module MEMORY_WRAPPER(DATA_OUT, DATA_IN, READ, WRITE, ADDR, CLK, RST); +// parameter file +// Parameter for the memory initialization file name +parameter mem_init_file = "mem_content_01.dat"; +// output list +output [`DATA_INDEX_LIMIT:0] DATA_OUT; +//input list +input [`DATA_INDEX_LIMIT:0] DATA_IN; +input READ, WRITE, CLK, RST; +input [`ADDRESS_INDEX_LIMIT:0] ADDR; + +reg [`DATA_INDEX_LIMIT:0] DATA_OUT; +wire [`DATA_INDEX_LIMIT:0] DATA; + +assign DATA = ((READ===1'b0)&&(WRITE===1'b1))?DATA_IN:{`DATA_WIDTH{1'bz} }; + +defparam memory_inst.mem_init_file = mem_init_file; +MEMORY_64MB memory_inst(.DATA(DATA), .READ(READ), .WRITE(WRITE), + .ADDR(ADDR), .CLK(CLK), .RST(RST)); + +initial +begin +DATA_OUT = 32'h00000000; +end + +always @(negedge RST) +begin +if (RST === 1'b0) + DATA_OUT = 32'h00000000; +end + + +always @(DATA) +begin +if ((READ===1'b1)&&(WRITE===1'b0)) + DATA_OUT=DATA; +end + +endmodule + +module MEMORY_64MB(DATA, READ, WRITE, ADDR, CLK, RST); +// Parameter for the memory initialization file name +parameter mem_init_file = "mem_content_01.dat"; +// input ports +input READ, WRITE, CLK, RST; +input [`ADDRESS_INDEX_LIMIT:0] ADDR; +// inout ports +inout [`DATA_INDEX_LIMIT:0] DATA; + +// memory bank +reg [`DATA_INDEX_LIMIT:0] sram_32x64m [0:`MEM_INDEX_LIMIT]; // memory storage +integer i; // index for reset operation + +reg [`DATA_INDEX_LIMIT:0] data_ret; // return data register + +assign DATA = ((READ===1'b1)&&(WRITE===1'b0))?data_ret:{`DATA_WIDTH{1'bz} }; + +always @ (negedge RST or posedge CLK) +begin +if (RST === 1'b0) +begin +for(i=0;i<=`MEM_INDEX_LIMIT; i = i +1) + sram_32x64m[i] = { `DATA_WIDTH{1'b0} }; +$readmemh(mem_init_file, sram_32x64m); +end +else +begin + if ((READ===1'b1)&&(WRITE===1'b0)) // read operation + data_ret = sram_32x64m[ADDR]; + else if ((READ===1'b0)&&(WRITE===1'b1)) // write operation + sram_32x64m[ADDR] = DATA; +end +end +endmodule diff --git a/mult.v b/mult.v new file mode 100644 index 0000000..ddb65d8 --- /dev/null +++ b/mult.v @@ -0,0 +1,44 @@ +// Name: mult.v +// Module: MULT32 , MULT32_U +// +// Output: HI: 32 higher bits +// LO: 32 lower bits +// +// +// Input: A : 32-bit input +// B : 32-bit input +// +// Notes: 32-bit multiplication +// +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "prj_definition.v" + +module MULT32(HI, LO, A, B); +// output list +output [31:0] HI; +output [31:0] LO; +// input list +input [31:0] A; +input [31:0] B; + +// TBD + +endmodule + +module MULT32_U(HI, LO, A, B); +// output list +output [31:0] HI; +output [31:0] LO; +// input list +input [31:0] A; +input [31:0] B; + +// TBD + +endmodule diff --git a/mux.v b/mux.v new file mode 100644 index 0000000..b2af14d --- /dev/null +++ b/mux.v @@ -0,0 +1,118 @@ +// Name: mux.v +// Module: +// Input: +// Output: +// +// Notes: Common definitions +// +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 02, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +// +// 32-bit mux +module MUX32_32x1(Y, I0, I1, I2, I3, I4, I5, I6, I7, + I8, I9, I10, I11, I12, I13, I14, I15, + I16, I17, I18, I19, I20, I21, I22, I23, + I24, I25, I26, I27, I28, I29, I30, I31, S); +// output list +output [31:0] Y; +//input list +input [31:0] I0, I1, I2, I3, I4, I5, I6, I7; +input [31:0] I8, I9, I10, I11, I12, I13, I14, I15; +input [31:0] I16, I17, I18, I19, I20, I21, I22, I23; +input [31:0] I24, I25, I26, I27, I28, I29, I30, I31; +input [4:0] S; + +// TBD + +endmodule + +// 32-bit 16x1 mux +module MUX32_16x1(Y, I0, I1, I2, I3, I4, I5, I6, I7, + I8, I9, I10, I11, I12, I13, I14, I15, S); +// output list +output [31:0] Y; +//input list +input [31:0] I0; +input [31:0] I1; +input [31:0] I2; +input [31:0] I3; +input [31:0] I4; +input [31:0] I5; +input [31:0] I6; +input [31:0] I7; +input [31:0] I8; +input [31:0] I9; +input [31:0] I10; +input [31:0] I11; +input [31:0] I12; +input [31:0] I13; +input [31:0] I14; +input [31:0] I15; +input [3:0] S; + +// TBD + +endmodule + +// 32-bit 8x1 mux +module MUX32_8x1(Y, I0, I1, I2, I3, I4, I5, I6, I7, S); +// output list +output [31:0] Y; +//input list +input [31:0] I0; +input [31:0] I1; +input [31:0] I2; +input [31:0] I3; +input [31:0] I4; +input [31:0] I5; +input [31:0] I6; +input [31:0] I7; +input [2:0] S; + +// TBD + +endmodule + +// 32-bit 4x1 mux +module MUX32_4x1(Y, I0, I1, I2, I3, S); +// output list +output [31:0] Y; +//input list +input [31:0] I0; +input [31:0] I1; +input [31:0] I2; +input [31:0] I3; +input [1:0] S; + +// TBD + +endmodule + +// 32-bit mux +module MUX32_2x1(Y, I0, I1, S); +// output list +output [31:0] Y; +//input list +input [31:0] I0; +input [31:0] I1; +input S; + +// TBD + +endmodule + +// 1-bit mux +module MUX1_2x1(Y,I0, I1, S); +//output list +output Y; +//input list +input I0, I1, S; + +// TBD + +endmodule diff --git a/prj_definition.v b/prj_definition.v new file mode 100644 index 0000000..540b1c6 --- /dev/null +++ b/prj_definition.v @@ -0,0 +1,44 @@ +// Name: prj_definition.v +// Module: +// Input: +// Output: +// +// Notes: Common definitions +// +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 02, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +// +`timescale 1ns/10ps + +`define SYS_CLK_PERIOD 10 +`define SYS_CLK_HALF_PERIOD (`SYS_CLK_PERIOD/2) +`define DATA_WIDTH 32 +`define DATA_INDEX_LIMIT (`DATA_WIDTH -1) +`define ALU_OPRN_WIDTH 6 +`define ALU_OPRN_INDEX_LIMIT (`ALU_OPRN_WIDTH -1) +`define ADDRESS_WIDTH 26 +`define ADDRESS_INDEX_LIMIT (`ADDRESS_WIDTH -1) +`define MEM_SIZE (2 ** `ADDRESS_WIDTH) +`define MEM_INDEX_LIMIT (`MEM_SIZE - 1) +`define NUM_OF_REG 32 +`define REG_INDEX_LIMIT (`NUM_OF_REG -1) +`define REG_ADDR_INDEX_LIMIT 4 +`define CTRL_WIDTH 32 +`define CTRL_WIDTH_INDEX_LIMIT (`CTRL_WIDTH - 1) +`define DOUBLE_DATA_WIDTH 64 +`define DOUBLE_DATA_INDEX_LIMIT (`DOUBLE_DATA_WIDTH - 1) +// definition for processor state +`define PROC_FETCH 3'h0 +`define PROC_DECODE 3'h1 +`define PROC_EXE 3'h2 +`define PROC_MEM 3'h3 +`define PROC_WB 3'h4 + +// define ISA parameters +`define INST_START_ADDR 32'h00001000 +`define INIT_STACK_POINTER 32'h03ffffff diff --git a/processor.v b/processor.v new file mode 100644 index 0000000..9514424 --- /dev/null +++ b/processor.v @@ -0,0 +1,47 @@ +// Name: processor.v +// Module: PROC_CS147_SEC05 +// Output: DATA : Data to be written at address ADDR +// ADDR : Address of the memory location to be accessed +// READ : Read signal +// WRITE: Write signal +// +// Input: DATA : Data read out in the read operation +// CLK : Clock signal +// RST : Reset signal +// +// Notes: - 32 bit processor implementing cs147sec05 instruction set +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +// 1.1 Oct 19, 2014 Kaushik Patra kpatra@sjsu.edu Fixed the RF connection +//------------------------------------------------------------------------------------------ +// +`include "prj_definition.v" +module PROC_CS147_SEC05(DATA_OUT, ADDR, DATA_IN, READ, WRITE, CLK, RST); +// output list +output [`ADDRESS_INDEX_LIMIT:0] ADDR; +output [`DATA_INDEX_LIMIT:0] DATA_OUT; +output READ, WRITE; +// input list +input CLK, RST; +input [`DATA_INDEX_LIMIT:0] DATA_IN; + +// net section +wire zero; +wire [`CTRL_WIDTH_INDEX_LIMIT:0] ctrl; +wire [`DATA_INDEX_LIMIT:0] INSTRUCTION; + +// instantiation section +// Control unit +CONTROL_UNIT cu_inst (.CTRL(ctrl), .READ(READ), .WRITE(WRITE), + .ZERO(zero), .INSTRUCTION(INSTRUCTION), + .CLK(CLK), .RST(RST)); + +// data path +DATA_PATH data_path_inst (.DATA_OUT(DATA_OUT), .INSTRUCTION(INSTRUCTION), .DATA_IN(DATA_IN), .ADDR(ADDR), .ZERO(zero), + .CTRL(ctrl), .CLK(CLK), .RST(RST)); + +endmodule; \ No newline at end of file diff --git a/rc_add_sub_32.v b/rc_add_sub_32.v new file mode 100644 index 0000000..d1a4f08 --- /dev/null +++ b/rc_add_sub_32.v @@ -0,0 +1,48 @@ +// Name: rc_add_sub_32.v +// Module: RC_ADD_SUB_32 +// +// Output: Y : Output 32-bit +// CO : Carry Out +// +// +// Input: A : 32-bit input +// B : 32-bit input +// SnA : if SnA=0 it is add, subtraction otherwise +// +// Notes: 32-bit adder / subtractor implementaiton. +// +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +`include "prj_definition.v" + +module RC_ADD_SUB_64(Y, CO, A, B, SnA); +// output list +output [63:0] Y; +output CO; +// input list +input [63:0] A; +input [63:0] B; +input SnA; + +// TBD + +endmodule + +module RC_ADD_SUB_32(Y, CO, A, B, SnA); +// output list +output [`DATA_INDEX_LIMIT:0] Y; +output CO; +// input list +input [`DATA_INDEX_LIMIT:0] A; +input [`DATA_INDEX_LIMIT:0] B; +input SnA; + +// TBD + +endmodule + diff --git a/register_file.v b/register_file.v new file mode 100644 index 0000000..cb430ba --- /dev/null +++ b/register_file.v @@ -0,0 +1,46 @@ +// Name: register_file.v +// Module: REGISTER_FILE_32x32 +// Input: DATA_W : Data to be written at address ADDR_W +// ADDR_W : Address of the memory location to be written +// ADDR_R1 : Address of the memory location to be read for DATA_R1 +// ADDR_R2 : Address of the memory location to be read for DATA_R2 +// READ : Read signal +// WRITE : Write signal +// CLK : Clock signal +// RST : Reset signal +// Output: DATA_R1 : Data at ADDR_R1 address +// DATA_R2 : Data at ADDR_R1 address +// +// Notes: - 32 bit word accessible dual read register file having 32 regsisters. +// - Reset is done at -ve edge of the RST signal +// - Rest of the operation is done at the +ve edge of the CLK signal +// - Read operation is done if READ=1 and WRITE=0 +// - Write operation is done if WRITE=1 and READ=0 +// - X is the value at DATA_R* if both READ and WRITE are 0 or 1 +// +// Revision History: +// +// Version Date Who email note +//------------------------------------------------------------------------------------------ +// 1.0 Sep 10, 2014 Kaushik Patra kpatra@sjsu.edu Initial creation +//------------------------------------------------------------------------------------------ +// +`include "prj_definition.v" + +// This is going to be +ve edge clock triggered register file. +// Reset on RST=0 +module REGISTER_FILE_32x32(DATA_R1, DATA_R2, ADDR_R1, ADDR_R2, + DATA_W, ADDR_W, READ, WRITE, CLK, RST); + +// input list +input READ, WRITE, CLK, RST; +input [`DATA_INDEX_LIMIT:0] DATA_W; +input [`REG_ADDR_INDEX_LIMIT:0] ADDR_R1, ADDR_R2, ADDR_W; + +// output list +output [`DATA_INDEX_LIMIT:0] DATA_R1; +output [`DATA_INDEX_LIMIT:0] DATA_R2; + +// TBD + +endmodule