@@ -941,3 +941,118 @@ module MULTADDSUB36X36 #(
941
941
.Z (Z )
942
942
);
943
943
endmodule
944
+
945
+ module MULTADDSUB9X9WIDE #(
946
+ parameter REGINPUTAB0 = "REGISTER" ,
947
+ parameter REGINPUTAB1 = "REGISTER" ,
948
+ parameter REGINPUTAB2 = "REGISTER" ,
949
+ parameter REGINPUTAB3 = "REGISTER" ,
950
+ parameter REGINPUTC = "REGISTER" ,
951
+ parameter REGADDSUB = "REGISTER" ,
952
+ parameter REGLOADC = "REGISTER" ,
953
+ parameter REGLOADC2 = "REGISTER" ,
954
+ parameter REGPIPELINE = "REGISTER" ,
955
+ parameter REGOUTPUT = "REGISTER" ,
956
+ parameter GSR = "ENABLED" ,
957
+ parameter RESETMODE = "SYNC"
958
+ ) (
959
+ input [8 :0 ] A0, B0, A1, B1, A2, B2, A3, B3,
960
+ input [53 :0 ] C,
961
+ input CLK,
962
+ input CEA0A1, CEA2A3,
963
+ input RSTA0A1, RSTA2A3,
964
+ input CEB0B1, CEB2B3,
965
+ input RSTB0B1, RSTB2B3,
966
+ input CEC, RSTC,
967
+ input CECTRL, RSTCTRL,
968
+ input SIGNED,
969
+ input RSTPIPE, CEPIPE,
970
+ input RSTOUT, CEOUT,
971
+ input LOADC,
972
+ input [3 :0 ] ADDSUB,
973
+ output [53 :0 ] Z
974
+ );
975
+ wire [17 :0 ] m0, m1, m2, m3;
976
+
977
+ localparam M_WIDTH = 18 ;
978
+ localparam Z_WIDTH = 54 ;
979
+
980
+ MULT9X9 #(
981
+ .REGINPUTA(REGINPUTAB0), .REGINPUTB(REGINPUTAB0), .REGOUTPUT(REGPIPELINE), .GSR(GSR), .RESETMODE(RESETMODE)
982
+ ) m9_0 (
983
+ .A(A0), .B(B0), .SIGNEDA(SIGNED), .SIGNEDB(SIGNED),
984
+ .CLK(CLK),
985
+ .CEA(CEA0A1), .RSTA(RSTA0A1),
986
+ .CEB(CEB0B1), .RSTB(RSTB0B1),
987
+ .CEOUT(CEPIPE), .RSTOUT(RSTPIPE),
988
+ .Z (m0)
989
+ );
990
+ MULT9X9 #(
991
+ .REGINPUTA(REGINPUTAB1), .REGINPUTB(REGINPUTAB1), .REGOUTPUT(REGPIPELINE), .GSR(GSR), .RESETMODE(RESETMODE)
992
+ ) m9_1 (
993
+ .A(A1), .B(B1), .SIGNEDA(SIGNED), .SIGNEDB(SIGNED),
994
+ .CLK(CLK),
995
+ .CEA(CEA0A1), .RSTA(RSTA0A1),
996
+ .CEB(CEB0B1), .RSTB(RSTB0B1),
997
+ .CEOUT(CEPIPE), .RSTOUT(RSTPIPE),
998
+ .Z (m1)
999
+ );
1000
+ MULT9X9 #(
1001
+ .REGINPUTA(REGINPUTAB2), .REGINPUTB(REGINPUTAB2), .REGOUTPUT(REGPIPELINE), .GSR(GSR), .RESETMODE(RESETMODE)
1002
+ ) m9_2 (
1003
+ .A(A2), .B(B2), .SIGNEDA(SIGNED), .SIGNEDB(SIGNED),
1004
+ .CLK(CLK),
1005
+ .CEA(CEA2A3), .RSTA(RSTA2A3),
1006
+ .CEB(CEB2B3), .RSTB(RSTB2B3),
1007
+ .CEOUT(CEPIPE), .RSTOUT(RSTPIPE),
1008
+ .Z (m2)
1009
+ );
1010
+ MULT9X9 #(
1011
+ .REGINPUTA(REGINPUTAB3), .REGINPUTB(REGINPUTAB3), .REGOUTPUT(REGPIPELINE), .GSR(GSR), .RESETMODE(RESETMODE)
1012
+ ) m9_3 (
1013
+ .A(A3), .B(B3), .SIGNEDA(SIGNED), .SIGNEDB(SIGNED),
1014
+ .CLK(CLK),
1015
+ .CEA(CEA2A3), .RSTA(RSTA2A3),
1016
+ .CEB(CEB2B3), .RSTB(RSTB2B3),
1017
+ .CEOUT(CEPIPE), .RSTOUT(RSTPIPE),
1018
+ .Z (m3)
1019
+ );
1020
+
1021
+ wire [53 :0 ] c_r, c_r2;
1022
+ wire [3 :0 ] addsub_r, addsub_r2;
1023
+ wire sgd_r, sgd_r2, csgd_r, csgd_r2;
1024
+ wire loadc_r, loadc_r2;
1025
+
1026
+ OXIDE_DSP_REG #(5 , REGADDSUB, RESETMODE) addsub_reg (CLK, CECTRL, RSTCTRL, {SIGNED, ADDSUB}, {sgd_r, addsub_r});
1027
+ OXIDE_DSP_REG #(5 , REGADDSUB, RESETMODE) addsub2_reg (CLK, CECTRL, RSTCTRL, {sgd_r, addsub_r}, {sgd_r2, addsub_r2});
1028
+
1029
+ OXIDE_DSP_REG #(1 , REGLOADC, RESETMODE) loadc_reg (CLK, CECTRL, RSTCTRL, LOADC, loadc_r);
1030
+ OXIDE_DSP_REG #(1 , REGLOADC2, RESETMODE) loadc2_reg (CLK, CECTRL, RSTCTRL, loadc_r, loadc_r2);
1031
+
1032
+ OXIDE_DSP_REG #(55 , REGINPUTC, RESETMODE) c_reg (CLK, CEC, RSTC, {SIGNED, C}, {csgd_r, c_r});
1033
+ OXIDE_DSP_REG #(55 , REGPIPELINE, RESETMODE) c2_reg (CLK, CEC, RSTC, {csgd_r, c_r}, {csgd_r2, c_r2});
1034
+
1035
+
1036
+ wire [18 :0 ] m0_ext, m1_ext, m2_ext, m3_ext;
1037
+
1038
+ assign m0_ext = {sgd_r2 ? m0[M_WIDTH- 1 ] : 1'b0 , m0};
1039
+ assign m1_ext = {sgd_r2 ? m1[M_WIDTH- 1 ] : 1'b0 , m1};
1040
+ assign m2_ext = {sgd_r2 ? m2[M_WIDTH- 1 ] : 1'b0 , m2};
1041
+ assign m3_ext = {sgd_r2 ? m3[M_WIDTH- 1 ] : 1'b0 , m3};
1042
+
1043
+ wire [18 :0 ] s0 = addsub_r2[2 ] ? (m0_ext - m1_ext) : (m0_ext + m1_ext);
1044
+ wire [18 :0 ] s1 = addsub_r2[3 ] ? (m2_ext - m3_ext) : (m2_ext + m3_ext);
1045
+
1046
+ wire [53 :0 ] s0_ext = {{(54 - 19 ){sgd_r2 ? s0[18 ] : 1'b0 }}, s0};
1047
+ wire [53 :0 ] s1_ext = {{(54 - 19 ){sgd_r2 ? s1[18 ] : 1'b0 }}, s1};
1048
+
1049
+ wire [53 :0 ] c_op = loadc_r2 ? c_r2 : Z ;
1050
+
1051
+ // The diagram in the docs is wrong! It is not two cascaded 2-input add/subs as shown,
1052
+ // but a three-input unit with negation controls on two inputs (i.e. addsub_r2[0]
1053
+ // negates s1 not (s1 +/- s0))
1054
+ wire [53 :0 ] z_d = c_op + (addsub_r2[0 ] ? - s1_ext : s1_ext) + (addsub_r2[1 ] ? - s0_ext : s0_ext);
1055
+
1056
+ OXIDE_DSP_REG #(Z_WIDTH, REGOUTPUT, RESETMODE) z_reg (CLK, CEOUT, RSTOUT, z_d, Z );
1057
+
1058
+ endmodule
0 commit comments