// 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