Well, nowadays, most of that is handled by the VHDL tools using libraries
of existing functionality.
//
// Add two BCD digits plus the carry_in, producing sum and carry_out
//
module bcd_adder(a,b,carry_in,sum,carry_out);
input [3:0] a,b;
input carry_in;
output [3:0] sum;
output carry_out;
reg [4:0] sum_temp;
reg [3:0] sum;
reg carry_out;
always @(a,b,carry_in)
begin
sum_temp = a+b+carry_in; //add all the inputs
if(sum_temp > 9) begin
sum_temp = sum_temp+6; //add 6, if result is more than 9.
carry_out = 1; //set the carry output
sum = sum_temp[3:0];
end
else begin
carry_out = 0;
sum = sum_temp[3:0];
end
end
endmodule
This gets compiled into the actual logic (gates & flops) during PD,
and is simply cascaded (carry_out -> carry_in) to do multiple digit
additions.
And here is a decoder that decodes a 4-digit index into
16 signals.
// 4x16 decoder
module decoder4x16(select_in, select_out, enable);
input[3:0] select_in;
intput enable;
output[15:0] select_out;
assign select_out[0]= (~select_in[3]) & (~select_in[2]) &(~select_in[1]) & (~select_in[0]) & (enable) ;
assign select_out[1]= (~select_in[3]) & (~select_in[2]) &(~select_in[1]) & (select_in[0]) & (enable) ;
assign select_out[2]= (~select_in[3]) & (~select_in[2]) &(select_in[1]) & (~select_in[0]) & (enable) ;
assign select_out[3]= (~select_in[3]) & (~select_in[2]) &(select_in[1]) & (select_in[0]) & (enable) ;
assign select_out[4]= (~select_in[3]) & (select_in[2]) &(~select_in[1]) & (~select_in[0]) & (enable) ;
assign select_out[5]= (~select_in[3]) & (select_in[2]) &(~select_in[1]) & (select_in[0]) & (enable) ;
assign select_out[6]= (~select_in[3]) & (select_in[2]) &(select_in[1]) & (~select_in[0]) & (enable) ;
assign select_out[7]= (~select_in[3]) & (select_in[2]) &(select_in[1]) & (select_in[0]) & (enable) ;
assign select_out[8]= (select_in[3]) & (~select_in[2]) &(~select_in[1]) & (~select_in[0]) & (enable) ;
assign select_out[9]= (select_in[3]) & (~select_in[2]) &(~select_in[1]) & (select_in[0]) & (enable) ;
assign select_out[10]= (select_in[3]) & (~select_in[2]) &(select_in[1]) & (~select_in[0]) & (enable) ;
assign select_out[11]= (select_in[3]) & (~select_in[2]) &(select_in[1]) & (select_in[0]) & (enable) ;
assign select_out[12]= (select_in[3]) & (select_in[2]) &(~select_in[1]) & (~select_in[0]) & (enable) ;
assign select_out[13]= (select_in[3]) & (select_in[2]) &(~select_in[1]) & (select_in[0]) & (enable) ;
assign select_out[14]= (select_in[3]) & (select_in[2]) &(select_in[1]) & (~select_in[0]) & (enable) ;
assign select_out[15]= (select_in[3]) & (select_in[2]) &(select_in[1]) & (select_in[0]) & (enable) ;
endmodule;
/ V500 Operand Fetch PMUX
//
// Permutes the digits in a 10 digit BCD operand in various ways.
// sellect value originates in CREG[46:43].
//
// Reference: V500 Fetch Module 6.2.1.4 (pp 72) Document # 1993 5212.
//
module pmux(clock, sellect, datain, pmuxerr, pmuxout);
input clock;
input[3:0] sellect;
input[39:0] datain;
output pmuxerr;
output[39:0] pmuxout;
reg[39:0] pmuxout;
reg pmuxerr;
//always @(selprty or sellect or datain)
always @(posedge clock)
begin
pmuxerr <= 1'b0; // Spec is not clear on this
case (sellect[3:0])
4'b0000 : begin // Left Rotate by 1 digit
pmuxout[39:36] <= datain[35:32]; // D9 <= D8
pmuxout[35:32] <= datain[31:28]; // D8 <= D7
pmuxout[31:28] <= datain[27:24]; // D7 <= D6
pmuxout[27:24] <= datain[23:20]; // D6 <= D5
pmuxout[23:20] <= datain[19:16]; // D5 <= D4
pmuxout[19:16] <= datain[15:12]; // D4 <= D3
pmuxout[15:12] <= datain[11: 8]; // D3 <= D2
pmuxout[11: 8] <= datain[ 7: 4]; // D2 <= D1
pmuxout[ 7: 4] <= datain[ 3: 0]; // D1 <= D0
pmuxout[ 3: 0] <= datain[39:36]; // D0 <= D9
end
4'b0001, 4'b0010 : pmuxout <= datain; // Pass Data without permutation
4'b0011 : begin // Left Rotate by 3 digits
pmuxout[39:36] <= datain[27:24]; // D9 <= D6
pmuxout[35:32] <= datain[23:20]; // D8 <= D5
pmuxout[31:28] <= datain[19:16]; // D7 <= D4
pmuxout[27:24] <= datain[15:12]; // D6 <= D3
pmuxout[23:20] <= datain[11: 8]; // D5 <= D2
pmuxout[19:16] <= datain[ 7: 4]; // D4 <= D1
pmuxout[15:12] <= datain[ 3: 0]; // D3 <= D0
pmuxout[11: 8] <= datain[39:36]; // D2 <= D9
pmuxout[ 7: 4] <= datain[35:32]; // D1 <= D8
pmuxout[ 3: 0] <= datain[31:28]; // D0 <= D7
end
4'b0100 : begin // Left Rotate by 4 digits
pmuxout[39:36] <= datain[23:20]; // D9 <= D5
pmuxout[35:32] <= datain[19:16]; // D8 <= D4
pmuxout[31:28] <= datain[15:12]; // D7 <= D3
pmuxout[27:24] <= datain[11: 8]; // D6 <= D2
pmuxout[23:20] <= datain[ 7: 4]; // D5 <= D1
pmuxout[19:16] <= datain[ 3: 0]; // D4 <= D0
pmuxout[15:12] <= datain[39:36]; // D3 <= D9
pmuxout[11: 8] <= datain[35:32]; // D2 <= D8
pmuxout[ 7: 4] <= datain[31:28]; // D1 <= D7
pmuxout[ 3: 0] <= datain[27:24]; // D0 <= D6
end
4'b0101 : begin // Left Rotate by 5 digits
pmuxout[39:36] <= datain[19:16]; // D9 <= D4
pmuxout[35:32] <= datain[15:12]; // D8 <= D3
pmuxout[31:28] <= datain[11: 8]; // D7 <= D2
pmuxout[27:24] <= datain[ 7: 4]; // D6 <= D1
pmuxout[23:20] <= datain[ 3: 0]; // D5 <= D0
pmuxout[19:16] <= datain[39:36]; // D4 <= D9
pmuxout[15:12] <= datain[35:32]; // D3 <= D8
pmuxout[11: 8] <= datain[31:28]; // D2 <= D7
pmuxout[ 7: 4] <= datain[27:24]; // D1 <= D6
pmuxout[ 3: 0] <= datain[23:20]; // D0 <= D5
end
4'b0110 : begin // Left Rotate by 6 digits
pmuxout[39:36] <= datain[15:12]; // D9 <= D3
pmuxout[35:32] <= datain[11: 8]; // D8 <= D2
pmuxout[31:28] <= datain[ 7: 4]; // D7 <= D1
pmuxout[27:24] <= datain[ 3: 0]; // D6 <= D0
pmuxout[23:20] <= datain[39:36]; // D5 <= D9
pmuxout[19:16] <= datain[35:32]; // D4 <= D8
pmuxout[15:12] <= datain[31:28]; // D3 <= D7
pmuxout[11: 8] <= datain[27:24]; // D2 <= D6
pmuxout[ 7: 4] <= datain[23:20]; // D1 <= D5
pmuxout[ 3: 0] <= datain[19:16]; // D0 <= D4
end
4'b0111 : begin // Left Rotate by 7 digits
pmuxout[39:36] <= datain[11: 8]; // D9 <= D2
pmuxout[35:32] <= datain[ 7: 4]; // D8 <= D1
pmuxout[31:28] <= datain[ 3: 0]; // D7 <= D0
pmuxout[27:24] <= datain[39:36]; // D6 <= D9
pmuxout[23:20] <= datain[35:32]; // D5 <= D8
pmuxout[19:16] <= datain[31:28]; // D4 <= D7
pmuxout[15:12] <= datain[27:24]; // D3 <= D6
pmuxout[11: 8] <= datain[23:20]; // D2 <= D5
pmuxout[ 7: 4] <= datain[19:16]; // D1 <= D4
pmuxout[ 3: 0] <= datain[15:12]; // D0 <= D3
end
4'b1000 : begin // Left Rotate by 8 digits
pmuxout[39:36] <= datain[ 7: 4]; // D9 <= D1
pmuxout[35:32] <= datain[ 3: 0]; // D8 <= D0
pmuxout[31:28] <= datain[39:36]; // D7 <= D9
pmuxout[27:24] <= datain[35:32]; // D6 <= D8
pmuxout[23:20] <= datain[31:28]; // D5 <= D7
pmuxout[19:16] <= datain[27:24]; // D4 <= D6
pmuxout[15:12] <= datain[23:20]; // D3 <= D5
pmuxout[11: 8] <= datain[19:16]; // D2 <= D4
pmuxout[ 7: 4] <= datain[15:12]; // D1 <= D3
pmuxout[ 3: 0] <= datain[11: 8]; // D0 <= D2
end
4'b1001 : begin // Left Rotate by 9 digits
pmuxout[39:36] <= datain[ 3: 0]; // D9 <= D0
pmuxout[35:32] <= datain[39:36]; // D8 <= D9
pmuxout[31:28] <= datain[35:32]; // D7 <= D8
pmuxout[27:24] <= datain[31:28]; // D6 <= D7
pmuxout[23:20] <= datain[27:24]; // D5 <= D6
pmuxout[19:16] <= datain[23:20]; // D4 <= D5
pmuxout[15:12] <= datain[19:16]; // D3 <= D4
pmuxout[11: 8] <= datain[15:12]; // D2 <= D3
pmuxout[ 7: 4] <= datain[11: 8]; // D1 <= D2
pmuxout[ 3: 0] <= datain[ 7: 4]; // D0 <= D1
end
4'b1010 : begin // Non-Branch IA syllable
pmuxout[39: 20] = 20'b00000000000000000000;
pmuxout[19:16] <= datain[35:32]; // D4 <= D8
pmuxout[15:12] <= datain[31:28]; // D3 <= D7
pmuxout[11: 8] <= datain[27:24]; // D2 <= D6
pmuxout[ 7: 4] <= datain[23:20]; // D1 <= D5
pmuxout[ 3: 0] <= datain[19:16]; // D0 <= D4
end
4'b1011 : begin // Extended IA syllable justify
pmuxout[39:24] = 16'b0000000000000000;
pmuxout[23:20] <= datain[31:28]; // D5 <= D7
pmuxout[19:16] <= datain[27:24]; // D4 <= D6
pmuxout[15:12] <= datain[23:20]; // D3 <= D5
pmuxout[11: 8] <= datain[19:16]; // D2 <= D4
pmuxout[ 7: 4] <= datain[15:12]; // D1 <= D3
pmuxout[ 3: 0] <= datain[11: 8]; // D0 <= D2
end
4'b1100 : begin // Branch IA syllable justify (non-extended)
pmuxout[39:22] = 18'b000000000000000000;
pmuxout[21:20] <= datain[37:36]; // D9 <= D9[1:0]
pmuxout[19:16] <= datain[35:32]; // D4 <= D8
pmuxout[15:12] <= datain[31:28]; // D3 <= D7
pmuxout[11: 8] <= datain[27:24]; // D2 <= D6
pmuxout[ 7: 4] <= datain[23:20]; // D1 <= D5
pmuxout[ 3: 0] <= datain[19:16]; // D0 <= D4
end
4'b1101 : begin // Strip Zone
pmuxout[39:36] <= datain[35:32]; // D9 <= D8
pmuxout[35:32] <= datain[27:24]; // D8 <= D6
pmuxout[31:28] <= datain[19:16]; // D7 <= D4
pmuxout[27:24] <= datain[11: 8]; // D6 <= D2
pmuxout[23:20] <= datain[ 3: 0]; // D5 <= D0
pmuxout[19: 0] = 20'b00000000000000000000;
end
4'b1110 : begin // IX Rotate
pmuxout[39:36] <= datain[35:32]; // D9 <= D8
pmuxout[35:32] = 4'b0000; // D8 <= 0
pmuxout[31:28] <= datain[39:36]; // D7 <= D9
pmuxout[27:24] = 4'b0000; // D6 <= 0
pmuxout[23:20] <= datain[31:28]; // D5 <= D7
pmuxout[19:16] <= datain[27:24]; // D4 <= D6
pmuxout[15:12] <= datain[23:20]; // D3 <= D5
pmuxout[11: 8] <= datain[19:16]; // D2 <= D4
pmuxout[ 7: 4] <= datain[15:12]; // D1 <= D3
pmuxout[ 3: 0] <= datain[11: 8]; // D0 <= D2
end
4'b1111 : begin // Left rotate by 2
pmuxout[39:36] <= datain[31:28]; // D9 <= D7
pmuxout[35:32] <= datain[27:24]; // D8 <= D6
pmuxout[31:28] <= datain[23:20]; // D7 <= D5
pmuxout[27:24] <= datain[19:16]; // D6 <= D4
pmuxout[23:20] <= datain[15:12]; // D5 <= D3
pmuxout[19:16] <= datain[11: 8]; // D4 <= D2
pmuxout[15:12] <= datain[ 7: 4]; // D3 <= D1
pmuxout[11: 8] <= datain[ 3: 0]; // D2 <= D0
pmuxout[ 7: 4] <= datain[39:36]; // D1 <= D9
pmuxout[ 3: 0] <= datain[35:32]; // D0 <= D8
end
endcase
end
endmodule
4'b1010 : begin // Non-Branch IA syllable
pmuxout[39: 20] = 20'b00000000000000000000;
pmuxout[19:16] <= datain[35:32]; // D4 <= D8
pmuxout[15:12] <= datain[31:28]; // D3 <= D7
pmuxout[11: 8] <= datain[27:24]; // D2 <= D6
pmuxout[ 7: 4] <= datain[23:20]; // D1 <= D5
pmuxout[ 3: 0] <= datain[19:16]; // D0 <= D4
end
4'b1011 : begin // Extended IA syllable justify
pmuxout[39:24] = 16'b0000000000000000;
pmuxout[23:20] <= datain[31:28]; // D5 <= D7
pmuxout[19:16] <= datain[27:24]; // D4 <= D6
pmuxout[15:12] <= datain[23:20]; // D3 <= D5
pmuxout[11: 8] <= datain[19:16]; // D2 <= D4
pmuxout[ 7: 4] <= datain[15:12]; // D1 <= D3
pmuxout[ 3: 0] <= datain[11: 8]; // D0 <= D2
end
4'b1100 : begin // Branch IA syllable justify (non-extended)
pmuxout[39:22] = 18'b000000000000000000;
pmuxout[21:20] <= datain[37:36]; // D9 <= D9[1:0]
pmuxout[19:16] <= datain[35:32]; // D4 <= D8
pmuxout[15:12] <= datain[31:28]; // D3 <= D7
pmuxout[11: 8] <= datain[27:24]; // D2 <= D6
pmuxout[ 7: 4] <= datain[23:20]; // D1 <= D5
pmuxout[ 3: 0] <= datain[19:16]; // D0 <= D4
end
4'b1101 : begin // Strip Zone
pmuxout[39:36] <= datain[35:32]; // D9 <= D8
pmuxout[35:32] <= datain[27:24]; // D8 <= D6
pmuxout[31:28] <= datain[19:16]; // D7 <= D4
pmuxout[27:24] <= datain[11: 8]; // D6 <= D2
pmuxout[23:20] <= datain[ 3: 0]; // D5 <= D0
pmuxout[19: 0] = 20'b00000000000000000000;
end
4'b1110 : begin // IX Rotate
pmuxout[39:36] <= datain[35:32]; // D9 <= D8
pmuxout[35:32] = 4'b0000; // D8 <= 0
pmuxout[31:28] <= datain[39:36]; // D7 <= D9
pmuxout[27:24] = 4'b0000; // D6 <= 0
pmuxout[23:20] <= datain[31:28]; // D5 <= D7
pmuxout[19:16] <= datain[27:24]; // D4 <= D6
pmuxout[15:12] <= datain[23:20]; // D3 <= D5
pmuxout[11: 8] <= datain[19:16]; // D2 <= D4
pmuxout[ 7: 4] <= datain[15:12]; // D1 <= D3
pmuxout[ 3: 0] <= datain[11: 8]; // D0 <= D2
end
4'b1111 : begin // Left rotate by 2
pmuxout[39:36] <= datain[31:28]; // D9 <= D7
pmuxout[35:32] <= datain[27:24]; // D8 <= D6
pmuxout[31:28] <= datain[23:20]; // D7 <= D5
pmuxout[27:24] <= datain[19:16]; // D6 <= D4
pmuxout[23:20] <= datain[15:12]; // D5 <= D3
pmuxout[19:16] <= datain[11: 8]; // D4 <= D2
pmuxout[15:12] <= datain[ 7: 4]; // D3 <= D1
pmuxout[11: 8] <= datain[ 3: 0]; // D2 <= D0
pmuxout[ 7: 4] <= datain[39:36]; // D1 <= D9
pmuxout[ 3: 0] <= datain[35:32]; // D0 <= D8
end
endcase
end
endmodule
>