// Code for reading and writing any byte in a 32-bit word.
// Using in LSU EE 4702-1 Spring 2000
// Modules named part_select read the BYTE of WORD specified by PART.
// Modules named part_write write the BYTE of WORD specified by PART on CLK.
// All of the modules work, the number of gates synthesized by Leonardo
// is given in the comments. They are organized from best to worst.
// If anyone can do better, please let me know.
//`define S
`define Cl
//
// Read a byte.
//
`ifdef S
// Optimize area: Number of gates : 205
module part_select(byte,part,word);
input part, word;
output byte;
wire [1:0] part;
wire [31:0] word;
wire [7:0] byte;
assign byte = word >> {part,3'b0};
endmodule // part_select
`endif
`ifdef Sb
// Optimize area: Number of gates : 205
module part_select(byte,part,word);
input part, word;
output byte;
wire [1:0] part;
wire [31:0] word;
wire [7:0] byte;
assign byte = { word[{part,3'd7}], word[{part,3'd6}],
word[{part,3'd5}], word[{part,3'd4}],
word[{part,3'd3}], word[{part,3'd2}],
word[{part,3'd1}], word[{part,3'd0}]};
endmodule // part_select
`endif
`ifdef C
// Optimize area: Number of gates : 205
module part_select(byte,part,word);
input part, word;
output byte;
wire [1:0] part;
wire [31:0] word;
reg [7:0] byte;
always @( part or word )
case( part )
0: byte = word[7:0];
1: byte = word[15:8];
2: byte = word[23:16];
3: byte = word[31:24];
endcase // case( head_word )
endmodule // part_select
`endif // ifdef C
//
// Write a byte.
//
`ifdef Cl
// Optimize area: Number of gates : 312, 910 MHz
module part_write(byte,part,word,clk);
input part, byte, clk;
output word;
wire [1:0] part;
reg [31:0] word;
wire [7:0] byte;
// exemplar translate_off
initial word = 0;
// exemplar translate_on
// Note: Since hardware should not be synthesized for i it would be
// good style to declare it an integer, however Leonardo doesn't
// allow bit selects on integers.
reg [6:0] i;
always @( posedge clk )
for(i=0; i<31; i=i+1) if( i[4:3] === part ) word[i] = byte[i[2:0]];
endmodule // part_select
`endif
`ifdef Cw
// Optimize area: Number of gates : 316, 910 MHz
module part_write(byte,part,word,clk);
input part, byte, clk;
output word;
wire [1:0] part;
reg [31:0] word;
wire [7:0] byte;
// exemplar translate_off
initial word = 0;
// exemplar translate_on
always @( posedge clk )
case( part )
0: word[7:0] = byte;
1: word[15:8] = byte;
2: word[23:16] = byte;
3: word[31:24] = byte;
endcase // case( part )
endmodule
`endif
`ifdef Sw
// Optimize Area: Number of gates : 477, 710.6 MHz
module part_write(byte,part,word,clk);
input part, byte, clk;
output word;
wire [1:0] part;
reg [31:0] word;
wire [7:0] byte;
// exemplar translate_off
initial word = 0;
// exemplar translate_on
always @( posedge clk )
word = ( word & ~( 8'hff << {part,3'b0} ) ) | (byte << {part,3'b0});
endmodule
`endif
`ifdef Wb
// Optimize Area: Number of gates : 552, 513.1 MHz
module part_write(byte,part,word,clk);
input part, byte, clk;
output word;
wire [1:0] part;
reg [31:0] word;
wire [7:0] byte;
always @( posedge clk )
{ word[{part,3'd7}], word[{part,3'd6}],
word[{part,3'd5}], word[{part,3'd4}],
word[{part,3'd3}], word[{part,3'd2}],
word[{part,3'd1}], word[{part,3'd0}] } = byte;
endmodule
`endif
`ifdef Cb
// Optimize area: Number of gates : 751, 407 MHz
module part_write(byte,part,word,clk);
input part, byte, clk;
output word;
wire [1:0] part;
reg [31:0] word;
wire [7:0] byte;
// exemplar translate_off
initial word = 0;
// exemplar translate_on
// reg [31:-32] bigword; // Leo can't handle negative indices
reg [63:0] bigword;
always @( byte or part or word )
begin
bigword = {word,32'd0} >> { part, 3'b0 };
bigword[39:32] = byte;
bigword = bigword << { part, 3'b0 };
end
always @( posedge clk ) word = bigword[63:32];
endmodule
`endif
// exemplar translate_off
module test_ps();
reg [1:0] p,p2;
reg [31:0] w;
wire [31:0] w2;
wire [7:0] n;
reg [7:0] n2;
reg clk;
part_select ps(n,p,w);
part_write pw(n2,p2,w2,clk);
integer i;
initial begin
w = 0;
n2 = 0;
p2 = 0; clk = 0;
for(i=0;i<4;i=i+1) begin
w=w>>8;w[31:24] = i;
n2 = i; p2 = i; #1; clk = 1; #1; clk = 0;
end
if( w2 !== w ) begin $display("Unexpected output."); $stop; end
p = 0;
begin:F forever begin
#1;
if( n != p ) begin $display("Unexpected output."); $stop; end
#1;
p = p + 1;
if( !p ) disable F;
end end
end
endmodule // test_ps
// exemplar translate_on