Wednesday, October 24, 2007

7bit UART TX Transmitter

module uart_tx (output sd, output busy, input [6:0] data, input wr, rst, clk);
reg [3:0] state, next_state;
reg [9:0] shifter;

parameter S_IDLE = 4'd0, S_BIT_START = 4'd1, S_BIT_P = 4'd9, S_BIT_STOP = 4'd10;

// continuous assignments
assign busy = (state != S_IDLE);
assign sd = shifter[0];

// synchronous behavior(s)
always @ (posedge clk) begin
if(rst) begin
state <= S_IDLE;
shifter <= 10'b11_1111_1111;
end
else begin
state <= next_state; // update state
if(wr) // load new frame
shifter <= {1'b1, ~(^(data)), data, 1'b0}; // could leave stop bit off!
else // shift current frame
shifter <= {1'b1, shifter[9:1]}; // shift in idle channel
end
end
// next state logic
always @ (state, wr) begin
case (state)
S_IDLE:
if(wr) next_state = S_BIT_START;
else next_state = S_IDLE;
S_BIT_STOP:
next_state = S_IDLE;
default:
next_state = state + 4'd1;
endcase
end

endmodule

16bit BCD adder

sometimes you just want a BCD adder instead of a binary adder. here is a 16bit one that works.

//put the cla and #1 adders together to make them easier to merge
module bcdadd4(
output co,
output [15:0] s,
input [15:0] a,b,
input cin);
wire p_up,g_up;
wire [3:0] p,g;
wire [3:0] carry;

pfa_bcd add[3:0](.p(p),.g(g),.s(s),.a(a),.b(b),.cin({carry[2:0], cin}));

cla localcla(.p_up(p_up),.g_up(g_up),.cout(carry),.p(p),.g(g),.cin(cin));

assign co = carry[3];
endmodule


module pfa_bcd(output reg p, g, output reg[3:0] s, input cin, input[3:0] a, b);
always @(*) begin
s <= (a+b+cin) % 10;
p <= (a+b == 9);
g <= (a+b > 9);
end
endmodule

16bit register file: 2 read & 2 write ports

This is a beautiful piece of code :-)
module reg_file(output [15:0] read1data, read2data, input [15:0] write1data, write2data, input [2:0] read1regsel, read2regsel, write1regsel, write2regsel, input clk, rst, write1, write2);
wire [7:0] reg_final_write, reg1_write, reg2_write;
wire [127:0] write_final_data;
wire [127:0] regfileout;
mux16b_8_1 muxAB [1:0] ({read1data, read2data}, {read1regsel, read2regsel}, {regfileout, regfileout}); //select 2 registers to read

decoder_3_to_8 decoder(reg1_write, write1regsel, write1); //select which register to write to
decoder_3_to_8 decoder2(reg2_write, write2regsel, write2); //select which register to write to
mux16b_2_1 writeportselector [7:0] (write_final_data, reg2_write, write1data, write2data);

assign reg_final_write = reg1_write | reg2_write;

reg16bit reg_16wide [7:0] (regfileout, write_final_data, clk, rst, reg_final_write); //registers
endmodule

//sel = 0 out = a
module mux16b_2_1(output [15:0] out, input sel, input [15:0] a, b);
assign out = (sel) ? b : a;
endmodule

module mux16b_8_1(output [15:0] out, input [2:0] sel, input [127:0] in);
assign out =
(sel == 3'b000) ? in[15:0]:
(sel == 3'b001) ? in[31:16]:
(sel == 3'b010) ? in[47:32]:
(sel == 3'b011) ? in[63:48]:
(sel == 3'b100) ? in[79:64]:
(sel == 3'b101) ? in[95:80]:
(sel == 3'b110) ? in[111:96]: in[127:112];
endmodule

module decoder_3_to_8(output [7:0] out, input [2:0] in, input en);
assign out =(en == 1'b0) ? 8'd0:
(in == 3'b000) ? 8'd1:
(in == 3'b001) ? 8'd2:
(in == 3'b010) ? 8'd4:
(in == 3'b011) ? 8'd8:
(in == 3'b100) ? 8'd16:
(in == 3'b101) ? 8'd32:
(in == 3'b110) ? 8'd64: 8'd128;
endmodule

module reg16bit(output [15:0] dataout, input [15:0] datain, input clk, rst, en);
wire [15:0] regin;
assign regin = en ? datain: dataout;
dff dff_array [15:0](dataout, regin, clk, rst);
endmodule

16bit comparer from 2bit comparer-s

Here is a cool idea, you can string a 2 bit comparer's together to make a big one... purely academic :-)
module compare_2bit(output A_eq_B, A_lt_B, A_gt_B, input [1:0] A, B, input A_eq_B_in, A_lt_B_in, A_gt_B_in);

assign A_eq_B = (A == B) & A_eq_B_in;
assign A_gt_B = (A==B) ? A_gt_B_in : A > B;
assign A_lt_B = (A==B) ? A_lt_B_in : (A < B);

endmodule

module compare_16bit(output X_eq_Y, X_lt_Y, X_gt_Y, input [15:0] X, Y);

wire[7:0] eq, lt, gt;
compare_2bit cp [7:0] (eq, lt, gt, X, Y, {eq[6:0],1'b1}, {lt[6:0],1'b0}, {gt[6:0],1'b0});

assign X_eq_Y = eq[7];
assign X_lt_Y = lt[7];
assign X_gt_Y = gt[7];

endmodule

Webbased Server monitoring Munin


Munin An easy way to keep track of how your servers are doing from a web front. Really clean install, and works on multitudes of servers at once.
How to set it up: How to set up Munin