OpenCores
URL https://opencores.org/ocsvn/uart2bus/uart2bus/trunk

Subversion Repositories uart2bus

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/uart2bus/trunk/doc/UART to Bus Core Specifications.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
uart2bus/trunk/doc/UART to Bus Core Specifications.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: uart2bus/trunk/verilog/bench/reg_file_model.v =================================================================== --- uart2bus/trunk/verilog/bench/reg_file_model.v (nonexistent) +++ uart2bus/trunk/verilog/bench/reg_file_model.v (revision 2) @@ -0,0 +1,68 @@ +//--------------------------------------------------------------------------------------- +// register file model as a simple memory +// +//--------------------------------------------------------------------------------------- + +`include "timescale.v" + +module reg_file_model +( + // global signals + clock, reset, + // internal bus to register file + int_address, int_wr_data, int_write, + int_rd_data, int_read +); +//--------------------------------------------------------------------------------------- +// modules inputs and outputs +input clock; // global clock input +input reset; // global reset input +input [7:0] int_address; // address bus to register file +input [7:0] int_wr_data; // write data to register file +input int_write; // write control to register file +input int_read; // read control to register file +output [7:0] int_rd_data; // data read from register file + +// registered outputs +reg [7:0] int_rd_data; + +// internal signal +reg [7:0] reg_file [0:255]; // 256 of 8 bit registers + +//--------------------------------------------------------------------------------------- +// internal tasks +// clear memory +task clear_reg_file; +reg [8:0] regfile_adr; +begin + for (regfile_adr = 9'h00; regfile_adr < 9'h80; regfile_adr = regfile_adr + 1) + begin + reg_file[regfile_adr] = 0; + end +end +endtask + +//--------------------------------------------------------------------------------------- +// module implementation +// register file write +always @ (posedge clock or posedge reset) +begin + if (reset) + clear_reg_file; + else if (int_write) + reg_file[int_address] <= int_wr_data; +end + +// register file read +always @ (posedge clock or posedge reset) +begin + if (reset) + int_rd_data <= 8'h0; + else if (int_read) + int_rd_data <= reg_file[int_address]; +end + +endmodule +//--------------------------------------------------------------------------------------- +// Th.. Th.. Th.. Thats all folks !!! +//--------------------------------------------------------------------------------------- Index: uart2bus/trunk/verilog/bench/tb_uart2bus_top.v =================================================================== --- uart2bus/trunk/verilog/bench/tb_uart2bus_top.v (nonexistent) +++ uart2bus/trunk/verilog/bench/tb_uart2bus_top.v (revision 2) @@ -0,0 +1,167 @@ +//--------------------------------------------------------------------------------------- +// uart test bench +// +//--------------------------------------------------------------------------------------- + +`include "timescale.v" + +module test; +//--------------------------------------------------------------------------------------- +// include uart tasks +`include "uart_tasks.v" + +// internal signal +reg clock; // global clock +reg reset; // global reset +reg [6:0] counter; + +//--------------------------------------------------------------------------------------- +// test bench implementation +// global signals generation +initial +begin + counter = 0; + clock = 0; + reset = 1; + #40 reset = 0; +end + +// clock generator - 40MHz clock +always +begin + #12 clock = 0; + #13 clock = 1; +end + +// test bench dump variables +initial +begin + $dumpfile("test.vcd"); + //$dumpall; + $dumpvars(0, test); +end + +//------------------------------------------------------------------ +// test bench transmitter and receiver +// uart transmit - test bench control + +initial +begin + // defualt value of serial output + serial_out = 1; + + // transmit a write command to internal register file + // command string: "w 4cd9 1a" + CR + send_serial (8'h77, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h20, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h34, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h63, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h64, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h39, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h20, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h31, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h61, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h0d, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + // transmit a read command from register file + // command string: "r 1a" + CR + send_serial (8'h72, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h20, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h31, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h61, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h0d, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + + // delay and finish + #900000; + $finish; +end + +// uart receive +initial +begin + // default value for serial receiver and serial input + serial_in = 1; + get_serial_data = 0; // data received from get_serial task + get_serial_status = 0; // status of get_serial task +end + +// serial sniffer loop +always +begin + // call serial sniffer + get_serial(`BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8); + + // check serial receiver status + // byte received OK + if (get_serial_status & `RECEIVE_RESULT_OK) + begin + // check if not a control character (above and including space ascii code) + if (get_serial_data >= 8'h20) + $display("received byte 0x%h (\"%c\") at %t ns", get_serial_data, get_serial_data, $time); + else + $display("received byte 0x%h (\"%c\") at %t ns", get_serial_data, 8'hb0, $time); + end + + // false start error + if (get_serial_status & `RECEIVE_RESULT_FALSESTART) + $display("Error (get_char): false start condition at %t", $realtime); + + // bad parity error + if (get_serial_status & `RECEIVE_RESULT_BADPARITY) + $display("Error (get_char): bad parity condition at %t", $realtime); + + // bad stop bits sequence + if (get_serial_status & `RECEIVE_RESULT_BADSTOP) + $display("Error (get_char): bad stop bits sequence at %t", $realtime); +end + +//------------------------------------------------------------------ +// device under test +// DUT interface +wire [7:0] int_address; // address bus to register file +wire [7:0] int_wr_data; // write data to register file +wire int_write; // write control to register file +wire int_read; // read control to register file +wire [7:0] int_rd_data; // data read from register file +wire ser_in; // DUT serial input +wire ser_out; // DUT serial output + +// DUT instance +uart2bus_top uart2bus1 +( + .clock(clock), .reset(reset), + .ser_in(ser_in), .ser_out(ser_out), + .int_address(int_address), .int_wr_data(int_wr_data), .int_write(int_write), + .int_rd_data(int_rd_data), .int_read(int_read) +); + +// serial interface to test bench +assign ser_in = serial_out; +always @ (posedge clock) serial_in = ser_out; + +// register file model +reg_file_model reg_file1 +( + .clock(clock), .reset(reset), + .int_address(int_address), .int_wr_data(int_wr_data), .int_write(int_write), + .int_rd_data(int_rd_data), .int_read(int_read) +); + +endmodule +//--------------------------------------------------------------------------------------- +// Th.. Th.. Th.. Thats all folks !!! +//--------------------------------------------------------------------------------------- Index: uart2bus/trunk/verilog/bench/uart_tasks.v =================================================================== --- uart2bus/trunk/verilog/bench/uart_tasks.v (nonexistent) +++ uart2bus/trunk/verilog/bench/uart_tasks.v (revision 2) @@ -0,0 +1,246 @@ +//------------------------------------------------------------------------------ +// uart tasks: +// send_serial serial transmitter +// get_serial serial receiver +// +//------------------------------------------------------------------------------ + +/* Serial Parameters used for send_serial task and its callers. */ +`define PARITY_OFF 1'b0 +`define PARITY_ON 1'b1 +`define PARITY_ODD 1'b0 +`define PARITY_EVEN 1'b1 +`define NSTOPS_1 1'b0 +`define NSTOPS_2 1'b1 +`define BAUD_115200 3'b000 +`define BAUD_38400 3'b001 +`define BAUD_28800 3'b010 +`define BAUD_19200 3'b011 +`define BAUD_9600 3'b100 +`define BAUD_4800 3'b101 +`define BAUD_2400 3'b110 +`define BAUD_1200 3'b111 +`define NBITS_7 1'b0 +`define NBITS_8 1'b1 +// constants for status from get_serial task +`define RECEIVE_RESULT_OK 4'b1000 +`define RECEIVE_RESULT_FALSESTART 4'b0001 +`define RECEIVE_RESULT_BADPARITY 4'b0010 +`define RECEIVE_RESULT_BADSTOP 4'b0100 + +// uart tasks global interfaces signals +reg serial_out; // transmit serial output +reg serial_in; // receive serial input +reg [7:0] get_serial_data; // data received from serial +reg [7:0] get_serial_status; // status of receive operation + +//------------------------------------------------------------------------------ +// uart transmit task +// +// usage: +// send_serial (data, baud_rate, parity_type, parity_on, stop_bits_num, +// data_bit_num, baud_error); +// where: +// data data character for transmission +// parity_type this is a flag indicating that parity should be even +// (either 'PARITY_ODD or 'PARITY_EVEN) +// parity_on indicates that the parity is used +// (either 'PARITY_OFF or 'PARITY_ON) +// stop_bits_num number of stop bits (either NSTOPS_1 or NSTOPS_2) +// data_bit_num number of data bits (either NBITS_7 or NBITS_8) +// baud_error baud error in precentage (-5 is -5%) +// + +task send_serial; +// task input parameters +input [7:0] inputchar; +input baud; +input paritytype; +input parityenable; +input nstops; +input nbits; +input baud_error_factor; +// internal registers +reg nbits; +reg parityenable; +reg paritytype; +reg [1:0] baud; +reg nstops; +integer baud_error_factor; // e.g. +5 means 5% too fast and -5 means 5% too slow +reg [7:0] char; +reg [7:0] disp_char; +reg parity_bit; +integer bit_time; +integer num_of_bits; +// task implementation +begin + char = inputchar; + parity_bit = 1'b0; + // calculate bit time from input baud rate - this assumes a simulation resolution of 1ns + case (baud) + `BAUD_115200: bit_time = 1000000000/(115200 + 1152*baud_error_factor); +// `BAUD_115200: bit_time = 40000000000/(115200 + 1152*baud_error_factor); + `BAUD_38400: bit_time = 1000000000/(38400 + 384*baud_error_factor); + `BAUD_28800: bit_time = 1000000000/(28800 + 288*baud_error_factor); + `BAUD_19200: bit_time = 1000000000/(19200 + 192*baud_error_factor); + `BAUD_9600: bit_time = 1000000000/(9600 + 96*baud_error_factor); + `BAUD_4800: bit_time = 1000000000/(4800 + 48*baud_error_factor); + `BAUD_2400: bit_time = 1000000000/(2400 + 24*baud_error_factor); + `BAUD_1200: bit_time = 1000000000/(1200 + 12*baud_error_factor); + endcase + + // display info + disp_char = (char >= 8'h20) ? char : 8'hb0; + $display ("Sending character 0x%h (\"%c\"), at %0d baud (err=%0d), %0d bits, %0s parity, %0d stops", + (nbits == `NBITS_7) ? (char & 8'h7f) : char, + (nbits == `NBITS_7) ? (disp_char & 8'h7f) : disp_char, + 1000000000/bit_time, + baud_error_factor, + (nbits == `NBITS_7) ? 7 : 8, + (parityenable == `PARITY_OFF) ? "NONE" : (paritytype == `PARITY_EVEN) ? "EVEN" : "ODD", + (nstops == `NSTOPS_1) ? 1 : 2 + ); + + // Start bit + serial_out = 1'b0; // Start bit. + #(bit_time); + + // Output data bits + num_of_bits = (nbits == `NBITS_7) ? 7 : 8; + repeat (num_of_bits) + begin + serial_out = char[0]; + #(bit_time); + char = {1'b0, char[7:1]}; + end + + // check if parity is enabled + if (parityenable == `PARITY_ON) begin + parity_bit = (nbits == `NBITS_7) ? ^inputchar[6:0] : ^inputchar[7:0]; + // even parity + if (paritytype == `PARITY_ODD) + parity_bit = ~parity_bit; + + serial_out = parity_bit; + #(bit_time); + end + + // Stop bit. + serial_out = 1'b1; + #(bit_time); + // Second stop bit + if (nstops) + #(bit_time); +end +endtask + +//------------------------------------------------------------------------------ +// uart receive task +// +// usage: +// get_serial (baud_rate, parity_type, parity_on, stop_bits_num, data_bit_num); +// where: +// data data character for transmission +// parity_type this is a flag indicating that parity should be even +// (either 'PARITY_ODD or 'PARITY_EVEN) +// parity_on indicates that the parity is used +// (either 'PARITY_OFF or 'PARITY_ON) +// stop_bits_num number of stop bits (either NSTOPS_1 or NSTOPS_2) +// data_bit_num number of data bits (either NBITS_7 or NBITS_8) +// +task get_serial; +// input parameters +input baud; +input paritytype; +input parityenable; +input nstops; +input nbits; +// internal registers +reg nbits; +reg parityenable; +reg paritytype; +reg [1:0] baud; +reg nstops; +integer bit_time; +reg expected_parity; +integer num_of_bits; +// task implementation +begin + // init receive globals + get_serial_status = 0; + get_serial_data = 0; + + // calculate bit time from input baud rate - this assumes a simulation resolution of 1ns + case (baud) + `BAUD_115200: bit_time = 1000000000/115200; + `BAUD_38400: bit_time = 1000000000/38400; + `BAUD_28800: bit_time = 1000000000/28800; + `BAUD_19200: bit_time = 1000000000/19200; + `BAUD_9600: bit_time = 1000000000/9600; + `BAUD_4800: bit_time = 1000000000/4800; + `BAUD_2400: bit_time = 1000000000/2400; + `BAUD_1200: bit_time = 1000000000/1200; + endcase + + // Assume OK until bad things happen. + get_serial_status = `RECEIVE_RESULT_OK; + + // wait for start bit edge + @(negedge serial_in); + + // wait till center of start bit + #(bit_time/2); + + // make sure its really a start bit + if (serial_in != 0) + get_serial_status = get_serial_status | `RECEIVE_RESULT_FALSESTART; + else + begin + // get all the data bits (7 or 8) + num_of_bits = (nbits == `NBITS_7) ? 7 : 8; + repeat (num_of_bits) + begin + // wait till center + #(bit_time); + // sample a data bit + get_serial_data = {serial_in, get_serial_data[7:1]}; + end + + // If we are only expecting 7 bits, go ahead and right-justify what we have + if (nbits == `NBITS_7) + get_serial_data = {1'b0, get_serial_data[7:1]}; + + // wait for next bit to start + #(bit_time); + + // now, we have either a parity bit, or a stop bit + if (parityenable == `PARITY_ON) begin + if (paritytype == `PARITY_EVEN) + expected_parity = (nbits == `NBITS_7) ? (^get_serial_data[6:0]) : + (^get_serial_data[7:0]); + else + expected_parity = (nbits == `NBITS_7) ? (~(^get_serial_data[6:0])) : + (~(^get_serial_data[7:0])); + + if (expected_parity != serial_in) + get_serial_status = get_serial_status | `RECEIVE_RESULT_BADPARITY; + end + // wait for either 1 or 2 stop bits + else begin + // this is a stop bit. + if (serial_in != 1) + get_serial_status = get_serial_status | `RECEIVE_RESULT_BADSTOP; + else + // that was cool. if 2 stops, then do this again + if (nstops) + begin + #(bit_time); + if (serial_in != 1) + get_serial_status = get_serial_status | `RECEIVE_RESULT_BADSTOP; + end + #(bit_time/2); + end + end +end +endtask + Index: uart2bus/trunk/verilog/bench/Test Bench Text Mode - tb_uart2bus_top.v =================================================================== --- uart2bus/trunk/verilog/bench/Test Bench Text Mode - tb_uart2bus_top.v (nonexistent) +++ uart2bus/trunk/verilog/bench/Test Bench Text Mode - tb_uart2bus_top.v (revision 2) @@ -0,0 +1,166 @@ +//--------------------------------------------------------------------------------------- +// uart test bench +// +//--------------------------------------------------------------------------------------- + +`include "timescale.v" + +module test; +//--------------------------------------------------------------------------------------- +// include uart tasks +`include "uart_tasks.v" + +// internal signal +reg clock; // global clock +reg reset; // global reset +reg [6:0] counter; + +//--------------------------------------------------------------------------------------- +// test bench implementation +// global signals generation +initial +begin + counter = 0; + reset = 1; + #40 reset = 0; +end + +// clock generator - 40MHz clock +always +begin + #12 clock = 0; + #13 clock = 1; +end + +// test bench dump variables +initial +begin + $dumpfile("test.vcd"); + //$dumpall; + $dumpvars(0, test); +end + +//------------------------------------------------------------------ +// test bench transmitter and receiver +// uart transmit - test bench control + +initial +begin + // defualt value of serial output + serial_out = 1; + + // transmit a write command to internal register file + // command string: "w 4cd9 1a" + CR + send_serial (8'h77, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h20, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h34, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h63, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h64, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h39, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h20, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h31, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h61, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h0d, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + // transmit a read command from register file + // command string: "r 1a" + CR + send_serial (8'h72, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h20, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h31, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h61, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + send_serial (8'h0d, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #100; + + // delay and finish + #900000; + $finish; +end + +// uart receive +initial +begin + // default value for serial receiver and serial input + serial_in = 1; + get_serial_data = 0; // data received from get_serial task + get_serial_status = 0; // status of get_serial task +end + +// serial sniffer loop +always +begin + // call serial sniffer + get_serial(`BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8); + + // check serial receiver status + // byte received OK + if (get_serial_status & `RECEIVE_RESULT_OK) + begin + // check if not a control character (above and including space ascii code) + if (get_serial_data >= 8'h20) + $display("received byte 0x%h (\"%c\") at %t ns", get_serial_data, get_serial_data, $time); + else + $display("received byte 0x%h (\"%c\") at %t ns", get_serial_data, 8'hb0, $time); + end + + // false start error + if (get_serial_status & `RECEIVE_RESULT_FALSESTART) + $display("Error (get_char): false start condition at %t", $realtime); + + // bad parity error + if (get_serial_status & `RECEIVE_RESULT_BADPARITY) + $display("Error (get_char): bad parity condition at %t", $realtime); + + // bad stop bits sequence + if (get_serial_status & `RECEIVE_RESULT_BADSTOP) + $display("Error (get_char): bad stop bits sequence at %t", $realtime); +end + +//------------------------------------------------------------------ +// device under test +// DUT interface +wire [7:0] int_address; // address bus to register file +wire [7:0] int_wr_data; // write data to register file +wire int_write; // write control to register file +wire int_read; // read control to register file +wire [7:0] int_rd_data; // data read from register file +wire ser_in; // DUT serial input +wire ser_out; // DUT serial output + +// DUT instance +uart2bus_top uart2bus1 +( + .clock(clock), .reset(reset), + .ser_in(ser_in), .ser_out(ser_out), + .int_address(int_address), .int_wr_data(int_wr_data), .int_write(int_write), + .int_rd_data(int_rd_data), .int_read(int_read) +); + +// serial interface to test bench +assign ser_in = serial_out; +always @ (posedge clock) serial_in = ser_out; + +// register file model +reg_file_model reg_file1 +( + .clock(clock), .reset(reset), + .int_address(int_address), .int_wr_data(int_wr_data), .int_write(int_write), + .int_rd_data(int_rd_data), .int_read(int_read) +); + +endmodule +//--------------------------------------------------------------------------------------- +// Th.. Th.. Th.. Thats all folks !!! +//--------------------------------------------------------------------------------------- Index: uart2bus/trunk/verilog/bench/Test Bench Binary Mode - tb_uart2bus_top.v =================================================================== --- uart2bus/trunk/verilog/bench/Test Bench Binary Mode - tb_uart2bus_top.v (nonexistent) +++ uart2bus/trunk/verilog/bench/Test Bench Binary Mode - tb_uart2bus_top.v (revision 2) @@ -0,0 +1,219 @@ +//--------------------------------------------------------------------------------------- +// uart test bench +// +//--------------------------------------------------------------------------------------- + +`include "timescale.v" + +module test; +//--------------------------------------------------------------------------------------- +// include uart tasks +`include "uart_tasks.v" + +// define if simulation should be binary or ascii +parameter BINARY_MODE = 1; + +// internal signal +reg clock; // global clock +reg reset; // global reset +reg [6:0] counter; + +//--------------------------------------------------------------------------------------- +// test bench implementation +// global signals generation +initial +begin + counter = 0; + reset = 1; + #40 reset = 0; +end + +// clock generator - 40MHz clock +always +begin + #12 clock = 0; + #13 clock = 1; +end + +// test bench dump variables +initial +begin + $dumpfile("test.vcd"); + //$dumpall; + $dumpvars(0, test); +end + +//------------------------------------------------------------------ +// test bench transmitter and receiver +// uart transmit - test bench control +integer file; // file handler index +integer char; // character read from file +integer file_len; // length of binary simulation file +integer byte_idx; // byte index in binary mode simulation +integer tx_len; +integer rx_len; +reg new_rx_data; + +initial +begin + // defualt value of serial output + serial_out = 1; + + // check simulation mode + if (BINARY_MODE > 0) + begin + // binary mode simulation + $display("Starting binary mode simulation"); + // open binary command file + file=$fopen("test.bin", "r"); + // in binary simulation mode the first two byte contain the file length (MSB first) + char = $fgetc(file); + $display("char = %d", char); + file_len = char; + char = $fgetc(file); + $display("char = %d", char); + file_len = 256*file_len + char; + $display("File length: %d", file_len); + + // send entire file to uart + byte_idx = 0; + while (byte_idx < file_len) + begin + // each "record" in the binary starts with two bytes: the first is the number + // of bytes to transmit and the second is the number of received bytes to wait + // for before transmitting the next command. + tx_len = $fgetc(file); + rx_len = $fgetc(file); + $display("Executing command with %d tx bytes and %d rx bytes", tx_len, rx_len); + byte_idx = byte_idx + 2; + + // transmit command + while (tx_len > 0) + begin + // read next byte from file and transmit it + char = $fgetc(file); + byte_idx = byte_idx + 1; + send_serial(char, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + // update tx_len + tx_len = tx_len - 1; + end + + // wait for received bytes + while (rx_len > 0) + begin + // one clock delay to allow new_rx_data to update + @(posedge new_rx_data) rx_len = rx_len - 1; + // check if a new byte was received +// if (new_rx_data) +// rx_len = rx_len - 1; + end + + $display("Command finished"); + end + end + else + begin + // ascii mode simulation + // open UART command file + file=$fopen("test.txt", "r"); + // transmit the byte in the command file one by one + char = $fgetc(file); + while (char >= 0) begin + // transmit byte through UART + send_serial(char, `BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8, 0); + #200000; + // read next byte from file + char = $fgetc(file); + end + end + + // close input file + $fclose(file); + + // delay and finish + #500000; + $finish; +end + +// uart receive +initial +begin + // default value for serial receiver and serial input + serial_in = 1; + get_serial_data = 0; // data received from get_serial task + get_serial_status = 0; // status of get_serial task +end + +// serial sniffer loop +always +begin + // clear new_rx_data flag + new_rx_data = 0; + + // call serial sniffer + get_serial(`BAUD_115200, `PARITY_EVEN, `PARITY_OFF, `NSTOPS_1, `NBITS_8); + + // check serial receiver status + // byte received OK + if (get_serial_status & `RECEIVE_RESULT_OK) + begin + // check if not a control character (above and including space ascii code) + if (get_serial_data >= 8'h20) + $display("received byte 0x%h (\"%c\") at %t ns", get_serial_data, get_serial_data, $time); + else + $display("received byte 0x%h (\"%c\") at %t ns", get_serial_data, 8'hb0, $time); + + // sign to transmit process that a new byte was received + @(posedge clock) new_rx_data = 1; + @(posedge clock) new_rx_data = 0; + end + + // false start error + if (get_serial_status & `RECEIVE_RESULT_FALSESTART) + $display("Error (get_char): false start condition at %t", $realtime); + + // bad parity error + if (get_serial_status & `RECEIVE_RESULT_BADPARITY) + $display("Error (get_char): bad parity condition at %t", $realtime); + + // bad stop bits sequence + if (get_serial_status & `RECEIVE_RESULT_BADSTOP) + $display("Error (get_char): bad stop bits sequence at %t", $realtime); +end + +//------------------------------------------------------------------ +// device under test +// DUT interface +wire [7:0] int_address; // address bus to register file +wire [7:0] int_wr_data; // write data to register file +wire int_write; // write control to register file +wire int_read; // read control to register file +wire [7:0] int_rd_data; // data read from register file +wire ser_in; // DUT serial input +wire ser_out; // DUT serial output + +// DUT instance +uart2bus_top uart2bus1 +( + .clock(clock), .reset(reset), + .ser_in(ser_in), .ser_out(ser_out), + .int_address(int_address), .int_wr_data(int_wr_data), .int_write(int_write), + .int_rd_data(int_rd_data), .int_read(int_read) +); + +// serial interface to test bench +assign ser_in = serial_out; +always @ (posedge clock) serial_in = ser_out; + +// register file model +reg_file_model reg_file1 +( + .clock(clock), .reset(reset), + .int_address(int_address), .int_wr_data(int_wr_data), .int_write(int_write), + .int_rd_data(int_rd_data), .int_read(int_read) +); + +endmodule +//--------------------------------------------------------------------------------------- +// Th.. Th.. Th.. Thats all folks !!! +//--------------------------------------------------------------------------------------- Index: uart2bus/trunk/verilog/bench/timescale.v =================================================================== --- uart2bus/trunk/verilog/bench/timescale.v (nonexistent) +++ uart2bus/trunk/verilog/bench/timescale.v (revision 2) @@ -0,0 +1,7 @@ +//--------------------------------------------------------------------------------------- +// +// Timescale definition. +// +//--------------------------------------------------------------------------------------- + +`timescale 1ns / 1ns Index: uart2bus/trunk/verilog/bench/readme.txt =================================================================== --- uart2bus/trunk/verilog/bench/readme.txt (nonexistent) +++ uart2bus/trunk/verilog/bench/readme.txt (revision 2) @@ -0,0 +1,4 @@ +To select between text mode and binary mode test bench simply make a copy of the testbench to be +used, delete the current 'tb_uart2bus_top.v' file and rename the copied file to +'tb_uart2bus_top.v'. +I know this is not a very clever way to do things but it works! Index: uart2bus/trunk/verilog/rtl/uart_top.v =================================================================== --- uart2bus/trunk/verilog/rtl/uart_top.v (nonexistent) +++ uart2bus/trunk/verilog/rtl/uart_top.v (revision 2) @@ -0,0 +1,66 @@ +//--------------------------------------------------------------------------------------- +// uart top level module +// +//--------------------------------------------------------------------------------------- + +module uart_top +( + // global signals + clock, reset, + // uart serial signals + ser_in, ser_out, + // transmit and receive internal interface signals + rx_data, new_rx_data, + tx_data, new_tx_data, tx_busy, + // baud rate configuration register - see baud_gen.v for details + baud_freq, baud_limit, + baud_clk +); +//--------------------------------------------------------------------------------------- +// modules inputs and outputs +input clock; // global clock input +input reset; // global reset input +input ser_in; // serial data input +output ser_out; // serial data output +input [7:0] tx_data; // data byte to transmit +input new_tx_data; // asserted to indicate that there is a new data byte for transmission +output tx_busy; // signs that transmitter is busy +output [7:0] rx_data; // data byte received +output new_rx_data; // signs that a new byte was received +input [11:0] baud_freq; // baud rate setting registers - see header description +input [15:0] baud_limit; +output baud_clk; + +// internal wires +wire ce_16; // clock enable at bit rate + +assign baud_clk = ce_16; +//--------------------------------------------------------------------------------------- +// module implementation +// baud rate generator module +baud_gen baud_gen_1 +( + .clock(clock), .reset(reset), + .ce_16(ce_16), .baud_freq(baud_freq), .baud_limit(baud_limit) +); + +// uart receiver +uart_rx uart_rx_1 +( + .clock(clock), .reset(reset), + .ce_16(ce_16), .ser_in(ser_in), + .rx_data(rx_data), .new_rx_data(new_rx_data) +); + +// uart transmitter +uart_tx uart_tx_1 +( + .clock(clock), .reset(reset), + .ce_16(ce_16), .tx_data(tx_data), .new_tx_data(new_tx_data), + .ser_out(ser_out), .tx_busy(tx_busy) +); + +endmodule +//--------------------------------------------------------------------------------------- +// Th.. Th.. Th.. Thats all folks !!! +//--------------------------------------------------------------------------------------- Index: uart2bus/trunk/verilog/rtl/baud_gen.v =================================================================== --- uart2bus/trunk/verilog/rtl/baud_gen.v (nonexistent) +++ uart2bus/trunk/verilog/rtl/baud_gen.v (revision 2) @@ -0,0 +1,55 @@ +//--------------------------------------------------------------------------------------- +// baud rate generator for uart +// +// this module has been changed to receive the baud rate dividing counter from registers. +// the two registers should be calculated as follows: +// first register: +// baud_freq = 16*baud_rate / gcd(global_clock_freq, 16*baud_rate) +// second register: +// baud_limit = (global_clock_freq / gcd(global_clock_freq, 16*baud_rate)) - baud_freq +//--------------------------------------------------------------------------------------- + +module baud_gen +( + clock, reset, + ce_16, baud_freq, baud_limit +); +//--------------------------------------------------------------------------------------- +// modules inputs and outputs +input clock; // global clock input +input reset; // global reset input +output ce_16; // baud rate multiplyed by 16 +input [11:0] baud_freq; // baud rate setting registers - see header description +input [15:0] baud_limit; + +// internal registers +reg ce_16; +reg [15:0] counter; +//--------------------------------------------------------------------------------------- +// module implementation +// baud divider counter +always @ (posedge clock or posedge reset) +begin + if (reset) + counter <= 16'b0; + else if (counter >= baud_limit) + counter <= counter - baud_limit; + else + counter <= counter + baud_freq; +end + +// clock divider output +always @ (posedge clock or posedge reset) +begin + if (reset) + ce_16 <= 1'b0; + else if (counter >= baud_limit) + ce_16 <= 1'b1; + else + ce_16 <= 1'b0; +end + +endmodule +//--------------------------------------------------------------------------------------- +// Th.. Th.. Th.. Thats all folks !!! +//--------------------------------------------------------------------------------------- Index: uart2bus/trunk/verilog/rtl/uart_rx.v =================================================================== --- uart2bus/trunk/verilog/rtl/uart_rx.v (nonexistent) +++ uart2bus/trunk/verilog/rtl/uart_rx.v (revision 2) @@ -0,0 +1,116 @@ +//--------------------------------------------------------------------------------------- +// uart receive module +// +//--------------------------------------------------------------------------------------- + +module uart_rx +( + clock, reset, + ce_16, ser_in, + rx_data, new_rx_data +); +//--------------------------------------------------------------------------------------- +// modules inputs and outputs +input clock; // global clock input +input reset; // global reset input +input ce_16; // baud rate multiplyed by 16 - generated by baud module +input ser_in; // serial data input +output [7:0] rx_data; // data byte received +output new_rx_data; // signs that a new byte was received + +// internal wires +wire ce_1; // clock enable at bit rate +wire ce_1_mid; // clock enable at the middle of each bit - used to sample data + +// internal registers +reg [7:0] rx_data; +reg new_rx_data; +reg [1:0] in_sync; +reg rx_busy; +reg [3:0] count16; +reg [3:0] bit_count; +reg [7:0] data_buf; +//--------------------------------------------------------------------------------------- +// module implementation +// input async input is sampled twice +always @ (posedge clock or posedge reset) +begin + if (reset) + in_sync <= 2'b11; + else + in_sync <= {in_sync[0], ser_in}; +end + +// a counter to count 16 pulses of ce_16 to generate the ce_1 and ce_1_mid pulses. +// this counter is used to detect the start bit while the receiver is not receiving and +// signs the sampling cycle during reception. +always @ (posedge clock or posedge reset) +begin + if (reset) + count16 <= 4'b0; + else if (ce_16) + begin + if (rx_busy | (in_sync[1] == 1'b0)) + count16 <= count16 + 4'b1; + else + count16 <= 4'b0; + end +end + +// ce_1 pulse indicating expected end of current bit +assign ce_1 = (count16 == 4'b1111) & ce_16; +// ce_1_mid pulse indication the sampling clock cycle of the current data bit +assign ce_1_mid = (count16 == 4'b0111) & ce_16; + +// receiving busy flag +always @ (posedge clock or posedge reset) +begin + if (reset) + rx_busy <= 1'b0; + else if (~rx_busy & ce_1_mid) + rx_busy <= 1'b1; + else if (rx_busy & (bit_count == 4'h9) & ce_1) + rx_busy <= 1'b0; +end + +// bit counter +always @ (posedge clock or posedge reset) +begin + if (reset) + bit_count <= 4'h0; + else if (~rx_busy) + bit_count <= 4'h0; + else if (rx_busy & ce_1_mid) + bit_count <= bit_count + 4'h1; +end + +// data buffer shift register +always @ (posedge clock or posedge reset) +begin + if (reset) + data_buf <= 8'h0; + else if (rx_busy & ce_1_mid) + data_buf <= {in_sync[1], data_buf[7:1]}; +end + +// data output and flag +always @ (posedge clock or posedge reset) +begin + if (reset) + begin + rx_data <= 8'h0; + new_rx_data <= 1'b0; + end + else if (rx_busy & (bit_count == 4'h8) & ce_1) + begin + rx_data <= data_buf; + new_rx_data <= 1'b1; + end + else + new_rx_data <= 1'b0; +end + +endmodule +//--------------------------------------------------------------------------------------- +// Th.. Th.. Th.. Thats all folks !!! +//--------------------------------------------------------------------------------------- Index: uart2bus/trunk/verilog/rtl/uart_tx.v =================================================================== --- uart2bus/trunk/verilog/rtl/uart_tx.v (nonexistent) +++ uart2bus/trunk/verilog/rtl/uart_tx.v (revision 2) @@ -0,0 +1,94 @@ +//--------------------------------------------------------------------------------------- +// uart transmit module +// +//--------------------------------------------------------------------------------------- + +module uart_tx +( + clock, reset, + ce_16, tx_data, new_tx_data, + ser_out, tx_busy +); +//--------------------------------------------------------------------------------------- +// modules inputs and outputs +input clock; // global clock input +input reset; // global reset input +input ce_16; // baud rate multiplyed by 16 - generated by baud module +input [7:0] tx_data; // data byte to transmit +input new_tx_data; // asserted to indicate that there is a new data byte for transmission +output ser_out; // serial data output +output tx_busy; // signs that transmitter is busy + +// internal wires +wire ce_1; // clock enable at bit rate + +// internal registers +reg ser_out; +reg tx_busy; +reg [3:0] count16; +reg [3:0] bit_count; +reg [8:0] data_buf; +//--------------------------------------------------------------------------------------- +// module implementation +// a counter to count 16 pulses of ce_16 to generate the ce_1 pulse +always @ (posedge clock or posedge reset) +begin + if (reset) + count16 <= 4'b0; + else if (tx_busy & ce_16) + count16 <= count16 + 4'b1; + else if (~tx_busy) + count16 <= 4'b0; +end + +// ce_1 pulse indicating output data bit should be updated +assign ce_1 = (count16 == 4'b1111) & ce_16; + +// tx_busy flag +always @ (posedge clock or posedge reset) +begin + if (reset) + tx_busy <= 1'b0; + else if (~tx_busy & new_tx_data) + tx_busy <= 1'b1; + else if (tx_busy & (bit_count == 4'ha) & ce_1) + tx_busy <= 1'b0; +end + +// output bit counter +always @ (posedge clock or posedge reset) +begin + if (reset) + bit_count <= 4'h0; + else if (tx_busy & ce_1) + bit_count <= bit_count + 4'h1; + else if (~tx_busy) + bit_count <= 4'h0; +end + +// data shift register +always @ (posedge clock or posedge reset) +begin + if (reset) + data_buf <= 9'b0; + else if (~tx_busy) + data_buf <= {tx_data, 1'b0}; + else if (tx_busy & ce_1) + data_buf <= {1'b1, data_buf[8:1]}; +end + +// output data bit +always @ (posedge clock or posedge reset) +begin + if (reset) + ser_out <= 1'b1; + else if (tx_busy) + ser_out <= data_buf[0]; + else + ser_out <= 1'b1; +end + +endmodule +//--------------------------------------------------------------------------------------- +// Th.. Th.. Th.. Thats all folks !!! +//--------------------------------------------------------------------------------------- Index: uart2bus/trunk/verilog/rtl/uart_parser.v =================================================================== --- uart2bus/trunk/verilog/rtl/uart_parser.v (nonexistent) +++ uart2bus/trunk/verilog/rtl/uart_parser.v (revision 2) @@ -0,0 +1,646 @@ +//--------------------------------------------------------------------------------------- +// uart parser module +// +//--------------------------------------------------------------------------------------- + +module uart_parser +( + // global signals + clock, reset, + // transmit and receive internal interface signals from uart interface + rx_data, new_rx_data, + tx_data, new_tx_data, tx_busy, + // internal bus to register file + int_address, int_wr_data, int_write, + int_rd_data, int_read +); +//--------------------------------------------------------------------------------------- +// parameters +parameter AW = 8; // address bus width parameter + +// modules inputs and outputs +input clock; // global clock input +input reset; // global reset input +output [7:0] tx_data; // data byte to transmit +output new_tx_data; // asserted to indicate that there is a new data byte for + // transmission +input tx_busy; // signs that transmitter is busy +input [7:0] rx_data; // data byte received +input new_rx_data; // signs that a new byte was received +output [AW-1:0] int_address; // address bus to register file +output [7:0] int_wr_data; // write data to register file +output int_write; // write control to register file +output int_read; // read control to register file +input [7:0] int_rd_data; // data read from register file + +// registered outputs +reg [7:0] tx_data; +reg new_tx_data; +reg [AW-1:0] int_address; +reg [7:0] int_wr_data; +reg int_write, int_read; + +// internal constants +// define characters used by the parser +`define CHAR_CR 8'h0d +`define CHAR_LF 8'h0a +`define CHAR_SPACE 8'h20 +`define CHAR_TAB 8'h09 +`define CHAR_COMMA 8'h2C +`define CHAR_R_UP 8'h52 +`define CHAR_r_LO 8'h72 +`define CHAR_W_UP 8'h57 +`define CHAR_w_LO 8'h77 +`define CHAR_0 8'h30 +`define CHAR_1 8'h31 +`define CHAR_2 8'h32 +`define CHAR_3 8'h33 +`define CHAR_4 8'h34 +`define CHAR_5 8'h35 +`define CHAR_6 8'h36 +`define CHAR_7 8'h37 +`define CHAR_8 8'h38 +`define CHAR_9 8'h39 +`define CHAR_A_UP 8'h41 +`define CHAR_B_UP 8'h42 +`define CHAR_C_UP 8'h43 +`define CHAR_D_UP 8'h44 +`define CHAR_E_UP 8'h45 +`define CHAR_F_UP 8'h46 +`define CHAR_a_LO 8'h61 +`define CHAR_b_LO 8'h62 +`define CHAR_c_LO 8'h63 +`define CHAR_d_LO 8'h64 +`define CHAR_e_LO 8'h65 +`define CHAR_f_LO 8'h66 + +// main (receive) state machine states +`define MAIN_IDLE 4'b0000 +`define MAIN_WHITE1 4'b0001 +`define MAIN_DATA 4'b0010 +`define MAIN_WHITE2 4'b0011 +`define MAIN_ADDR 4'b0100 +`define MAIN_EOL 4'b0101 +// binary mode extension states +`define MAIN_BIN_CMD 4'b1000 +`define MAIN_BIN_ADRH 4'b1001 +`define MAIN_BIN_ADRL 4'b1010 +`define MAIN_BIN_LEN 4'b1011 +`define MAIN_BIN_DATA 4'b1100 + +// transmit state machine +`define TX_IDLE 3'b000 +`define TX_HI_NIB 3'b001 +`define TX_LO_NIB 3'b100 +`define TX_CHAR_CR 3'b101 +`define TX_CHAR_LF 3'b110 + +// binary extension mode commands - the command is indicated by bits 5:4 of the command byte +`define BIN_CMD_NOP 2'b00 +`define BIN_CMD_READ 2'b01 +`define BIN_CMD_WRITE 2'b10 + +// internal wires and registers +reg [3:0] main_sm; // main state machine +reg read_op; // read operation flag +reg write_op; // write operation flag +reg data_in_hex_range; // indicates that the received data is in the range of hex number +reg [7:0] data_param; // operation data parameter +reg [15:0] addr_param; // operation address parameter +reg [3:0] data_nibble; // data nibble from received character +reg read_done; // internally generated read done flag +reg read_done_s; // sampled read done +reg [7:0] read_data_s; // sampled read data +reg [3:0] tx_nibble; // nibble value for transmission +reg [7:0] tx_char; // transmit byte from nibble to character conversion +reg [2:0] tx_sm; // transmit state machine +reg s_tx_busy; // sampled tx_busy for falling edge detection +reg bin_read_op; // binary mode read operation flag +reg bin_write_op; // binary mode write operation flag +reg addr_auto_inc; // address auto increment mode +reg send_stat_flag; // send status flag +reg [7:0] bin_byte_count; // binary mode byte counter +wire bin_last_byte; // last byte flag indicates that the current byte in the command is the last +wire tx_end_p; // transmission end pulse + +//--------------------------------------------------------------------------------------- +// module implementation +// main state machine +always @ (posedge clock or posedge reset) +begin + if (reset) + main_sm <= `MAIN_IDLE; + else if (new_rx_data) + begin + case (main_sm) + // wait for a read ('r') or write ('w') command + // binary extension - an all zeros byte enabled binary commands + `MAIN_IDLE: + // check received character + if (rx_data == 8'h0) + // an all zeros received byte enters binary mode + main_sm <= `MAIN_BIN_CMD; + else if ((rx_data == `CHAR_r_LO) | (rx_data == `CHAR_R_UP)) + // on read wait to receive only address field + main_sm <= `MAIN_WHITE2; + else if ((rx_data == `CHAR_w_LO) | (rx_data == `CHAR_W_UP)) + // on write wait to receive data and address + main_sm <= `MAIN_WHITE1; + else if ((rx_data == `CHAR_CR) | (rx_data == `CHAR_LF)) + // on new line sta in idle + main_sm <= `MAIN_IDLE; + else + // any other character wait to end of line (EOL) + main_sm <= `MAIN_EOL; + + // wait for white spaces till first data nibble + `MAIN_WHITE1: + // wait in this case until any white space character is received. in any + // valid character for data value switch to data state. a new line or carriage + // return should reset the state machine to idle. + // any other character transitions the state machine to wait for EOL. + if ((rx_data == `CHAR_SPACE) | (rx_data == `CHAR_TAB)) + main_sm <= `MAIN_WHITE1; + else if (data_in_hex_range) + main_sm <= `MAIN_DATA; + else if ((rx_data == `CHAR_CR) | (rx_data == `CHAR_LF)) + main_sm <= `MAIN_IDLE; + else + main_sm <= `MAIN_EOL; + + // receive data field + `MAIN_DATA: + // wait while data in hex range. white space transition to wait white 2 state. + // CR and LF resets the state machine. any other value cause state machine to + // wait til end of line. + if (data_in_hex_range) + main_sm <= `MAIN_DATA; + else if ((rx_data == `CHAR_SPACE) | (rx_data == `CHAR_TAB)) + main_sm <= `MAIN_WHITE2; + else if ((rx_data == `CHAR_CR) | (rx_data == `CHAR_LF)) + main_sm <= `MAIN_IDLE; + else + main_sm <= `MAIN_EOL; + + // wait for white spaces till first address nibble + `MAIN_WHITE2: + // similar to MAIN_WHITE1 + if ((rx_data == `CHAR_SPACE) | (rx_data == `CHAR_TAB)) + main_sm <= `MAIN_WHITE2; + else if (data_in_hex_range) + main_sm <= `MAIN_ADDR; + else if ((rx_data == `CHAR_CR) | (rx_data == `CHAR_LF)) + main_sm <= `MAIN_IDLE; + else + main_sm <= `MAIN_EOL; + + // receive address field + `MAIN_ADDR: + // similar to MAIN_DATA + if (data_in_hex_range) + main_sm <= `MAIN_ADDR; + else if ((rx_data == `CHAR_CR) | (rx_data == `CHAR_LF)) + main_sm <= `MAIN_IDLE; + else + main_sm <= `MAIN_EOL; + + // wait to EOL + `MAIN_EOL: + // wait for CR or LF to move back to idle + if ((rx_data == `CHAR_CR) | (rx_data == `CHAR_LF)) + main_sm <= `MAIN_IDLE; + + // binary extension + // wait for command - one byte + `MAIN_BIN_CMD: + // check if command is a NOP command + if (rx_data[5:4] == `BIN_CMD_NOP) + // if NOP command then switch back to idle state + main_sm <= `MAIN_IDLE; + else + // not a NOP command, continue receiving parameters + main_sm <= `MAIN_BIN_ADRH; + + // wait for address parameter - two bytes + // high address byte + `MAIN_BIN_ADRH: + // switch to next state + main_sm <= `MAIN_BIN_ADRL; + + // low address byte + `MAIN_BIN_ADRL: + // switch to next state + main_sm <= `MAIN_BIN_LEN; + + // wait for length parameter - one byte + `MAIN_BIN_LEN: + // check if write command else command reception ended + if (bin_write_op) + // wait for write data + main_sm <= `MAIN_BIN_DATA; + else + // command reception has ended + main_sm <= `MAIN_IDLE; + + // on write commands wait for data till end of buffer as specified by length parameter + `MAIN_BIN_DATA: + // if this is the last data byte then return to idle + if (bin_last_byte) + main_sm <= `MAIN_IDLE; + + // go to idle + default: + main_sm <= `MAIN_IDLE; + endcase + end +end + +// indicates that the received data is in the range of hex number +always @ (rx_data) +begin + if (((rx_data >= `CHAR_0 ) && (rx_data <= `CHAR_9 )) || + ((rx_data >= `CHAR_A_UP) && (rx_data <= `CHAR_F_UP)) || + ((rx_data >= `CHAR_a_LO) && (rx_data <= `CHAR_f_LO))) + data_in_hex_range <= 1'b1; + else + data_in_hex_range <= 1'b0; +end + +// read operation flag +always @ (posedge clock or posedge reset) +begin + if (reset) + read_op <= 1'b0; + else if ((main_sm == `MAIN_IDLE) && new_rx_data) + begin + // the read operation flag is set when a read command is received in idle state and cleared + // if any other character is received during that state. + if ((rx_data == `CHAR_r_LO) | (rx_data == `CHAR_R_UP)) + read_op <= 1'b1; + else + read_op <= 1'b0; + end +end + +// write operation flag +always @ (posedge clock or posedge reset) +begin + if (reset) + write_op <= 1'b0; + else if ((main_sm == `MAIN_IDLE) & new_rx_data) + begin + // the write operation flag is set when a write command is received in idle state and cleared + // if any other character is received during that state. + if ((rx_data == `CHAR_w_LO) | (rx_data == `CHAR_W_UP)) + write_op <= 1'b1; + else + write_op <= 1'b0; + end +end + +// binary mode read operation flag +always @ (posedge clock or posedge reset) +begin + if (reset) + bin_read_op <= 1'b0; + else if ((main_sm == `MAIN_BIN_CMD) && new_rx_data && (rx_data[5:4] == `BIN_CMD_READ)) + // read command is started on reception of a read command + bin_read_op <= 1'b1; + else if (bin_read_op && tx_end_p && bin_last_byte) + // read command ends on transmission of the last byte read + bin_read_op <= 1'b0; +end + +// binary mode write operation flag +always @ (posedge clock or posedge reset) +begin + if (reset) + bin_write_op <= 1'b0; + else if ((main_sm == `MAIN_BIN_CMD) && new_rx_data && (rx_data[5:4] == `BIN_CMD_WRITE)) + // write command is started on reception of a write command + bin_write_op <= 1'b1; + else if ((main_sm == `MAIN_BIN_DATA) && new_rx_data && bin_last_byte) + bin_write_op <= 1'b0; +end + +// send status flag - used only in binary extension mode +always @ (posedge clock or posedge reset) +begin + if (reset) + send_stat_flag <= 1'b0; + else if ((main_sm == `MAIN_BIN_CMD) && new_rx_data) + begin + // check if a status byte should be sent at the end of the command + if (rx_data[0] == 1'b1) + send_stat_flag <= 1'b1; + else + send_stat_flag <= 1'b0; + end +end + +// address auto increment - used only in binary extension mode +always @ (posedge clock or posedge reset) +begin + if (reset) + addr_auto_inc <= 1'b0; + else if ((main_sm == `MAIN_BIN_CMD) && new_rx_data) + begin + // check if address should be automatically incremented or not. + // Note that when rx_data[1] is set, address auto increment is disabled. + if (rx_data[1] == 1'b0) + addr_auto_inc <= 1'b1; + else + addr_auto_inc <= 1'b0; + end +end + +// operation data parameter +always @ (posedge clock or posedge reset) +begin + if (reset) + data_param <= 8'h0; + else if ((main_sm == `MAIN_WHITE1) & new_rx_data & data_in_hex_range) + data_param <= {4'h0, data_nibble}; + else if ((main_sm == `MAIN_DATA) & new_rx_data & data_in_hex_range) + data_param <= {data_param[3:0], data_nibble}; +end + +// operation address parameter +always @ (posedge clock or posedge reset) +begin + if (reset) + addr_param <= 0; + else if ((main_sm == `MAIN_WHITE2) & new_rx_data & data_in_hex_range) + addr_param <= {12'b0, data_nibble}; + else if ((main_sm == `MAIN_ADDR) & new_rx_data & data_in_hex_range) + addr_param <= {addr_param[11:0], data_nibble}; + // binary extension + else if (main_sm == `MAIN_BIN_ADRH) + addr_param[15:8] <= rx_data; + else if (main_sm == `MAIN_BIN_ADRL) + addr_param[7:0] <= rx_data; +end + +// binary mode command byte counter is loaded with the length parameter and counts down to zero. +// NOTE: a value of zero for the length parameter indicates a command of 256 bytes. +always @ (posedge clock or posedge reset) +begin + if (reset) + bin_byte_count <= 8'b0; + else if ((main_sm == `MAIN_BIN_LEN) && new_rx_data) + bin_byte_count <= rx_data; + else if ((bin_write_op && (main_sm == `MAIN_BIN_DATA) && new_rx_data) || + (bin_read_op && tx_end_p)) + // byte counter is updated on every new data received in write operations and for every + // byte transmitted for read operations. + bin_byte_count <= bin_byte_count - 1; +end +// last byte in command flag +assign bin_last_byte = (bin_byte_count == 8'h01) ? 1'b1 : 1'b0; + +// internal write control and data +always @ (posedge clock or posedge reset) +begin + if (reset) + begin + int_write <= 1'b0; + int_wr_data <= 0; + end + else if (write_op && (main_sm == `MAIN_ADDR) && new_rx_data && !data_in_hex_range) + begin + int_write <= 1'b1; + int_wr_data <= data_param; + end + // binary extension mode + else if (bin_write_op && (main_sm == `MAIN_BIN_DATA) && new_rx_data) + begin + int_write <= 1'b1; + int_wr_data <= rx_data; + end + else + int_write <= 1'b0; +end + +// internal read control +always @ (posedge clock or posedge reset) +begin + if (reset) + int_read <= 1'b0; + else if (read_op && (main_sm == `MAIN_ADDR) && new_rx_data && !data_in_hex_range) + int_read <= 1'b1; + // binary extension + else if (bin_read_op && (main_sm == `MAIN_BIN_LEN) && new_rx_data) + // the first read request is issued on reception of the length byte + int_read <= 1'b1; + else if (bin_read_op && tx_end_p && !bin_last_byte) + // the next read requests are issued after the previous read value was transmitted and + // this is not the last byte to be read. + int_read <= 1'b1; + else + int_read <= 1'b0; +end + +// internal address +always @ (posedge clock or posedge reset) +begin + if (reset) + int_address <= 0; + else if ((main_sm == `MAIN_ADDR) && new_rx_data && !data_in_hex_range) + int_address <= addr_param[AW-1:0]; + // binary extension + else if ((main_sm == `MAIN_BIN_LEN) && new_rx_data) + // sample address parameter on reception of length byte + int_address <= addr_param[AW-1:0]; + else if (addr_auto_inc && + ((bin_read_op && tx_end_p && !bin_last_byte) || +// (bin_write_op && (main_sm == `MAIN_BIN_DATA) && new_rx_data))) + (bin_write_op && int_write))) + // address is incremented on every read or write if enabled + int_address <= int_address + 1; +end + +// read done flag and sampled data read +always @ (posedge clock or posedge reset) +begin + if (reset) begin + read_done <= 1'b0; + read_done_s <= 1'b0; + read_data_s <= 8'h0; + end + else + begin + // read done flag + if (int_read) + read_done <= 1'b1; + else + read_done <= 1'b0; + + // sampled read done + read_done_s <= read_done; + + // sampled data read + if (read_done) + read_data_s <= int_rd_data; + end +end + +// transmit state machine and control +always @ (posedge clock or posedge reset) +begin + if (reset) begin + tx_sm <= `TX_IDLE; + tx_data <= 8'h0; + new_tx_data <= 1'b0; + end + else + case (tx_sm) + // wait for read done indication + `TX_IDLE: + // on end of every read operation check how the data read should be transmitted + // according to read type: ascii or binary. + if (read_done_s) + // on binary mode read transmit byte value + if (bin_read_op) + begin + // note that there is no need to change state + tx_data <= read_data_s; + new_tx_data <= 1'b1; + end + else + begin + tx_sm <= `TX_HI_NIB; + tx_data <= tx_char; + new_tx_data <= 1'b1; + end + // check if status byte should be transmitted + else if ((send_stat_flag && bin_read_op && tx_end_p && bin_last_byte) || // end of read command + (send_stat_flag && bin_write_op && new_rx_data && bin_last_byte) || // end of write command + ((main_sm == `MAIN_BIN_CMD) && new_rx_data && (rx_data[5:4] == `BIN_CMD_NOP))) // NOP + begin + // send status byte - currently a constant + tx_data <= 8'h5a; + new_tx_data <= 1'b1; + end + else + new_tx_data <= 1'b0; + + // wait for transmit to end + `TX_HI_NIB: + if (tx_end_p) + begin + tx_sm <= `TX_LO_NIB; + tx_data <= tx_char; + new_tx_data <= 1'b1; + end + else + new_tx_data <= 1'b0; + + // wait for transmit to end + `TX_LO_NIB: + if (tx_end_p) + begin + tx_sm <= `TX_CHAR_CR; + tx_data <= `CHAR_CR; + new_tx_data <= 1'b1; + end + else + new_tx_data <= 1'b0; + + // wait for transmit to end + `TX_CHAR_CR: + if (tx_end_p) + begin + tx_sm <= `TX_CHAR_LF; + tx_data <= `CHAR_LF; + new_tx_data <= 1'b1; + end + else + new_tx_data <= 1'b0; + + // wait for transmit to end + `TX_CHAR_LF: + begin + if (tx_end_p) + tx_sm <= `TX_IDLE; + // clear tx new data flag + new_tx_data <= 1'b0; + end + + // return to idle + default: + tx_sm <= `TX_IDLE; + endcase +end + +// select the nibble to the nibble to character conversion +always @ (tx_sm or read_data_s) +begin + case (tx_sm) + `TX_IDLE: tx_nibble = read_data_s[7:4]; + `TX_HI_NIB: tx_nibble = read_data_s[3:0]; + default: tx_nibble = read_data_s[7:4]; + endcase +end + +// sampled tx_busy +always @ (posedge clock or posedge reset) +begin + if (reset) + s_tx_busy <= 1'b0; + else + s_tx_busy <= tx_busy; +end +// tx end pulse +assign tx_end_p = ~tx_busy & s_tx_busy; + +// character to nibble conversion +always @ (rx_data) +begin + case (rx_data) + `CHAR_0: data_nibble = 4'h0; + `CHAR_1: data_nibble = 4'h1; + `CHAR_2: data_nibble = 4'h2; + `CHAR_3: data_nibble = 4'h3; + `CHAR_4: data_nibble = 4'h4; + `CHAR_5: data_nibble = 4'h5; + `CHAR_6: data_nibble = 4'h6; + `CHAR_7: data_nibble = 4'h7; + `CHAR_8: data_nibble = 4'h8; + `CHAR_9: data_nibble = 4'h9; + `CHAR_A_UP, `CHAR_a_LO: data_nibble = 4'ha; + `CHAR_B_UP, `CHAR_b_LO: data_nibble = 4'hb; + `CHAR_C_UP, `CHAR_c_LO: data_nibble = 4'hc; + `CHAR_D_UP, `CHAR_d_LO: data_nibble = 4'hd; + `CHAR_E_UP, `CHAR_e_LO: data_nibble = 4'he; + `CHAR_F_UP, `CHAR_f_LO: data_nibble = 4'hf; + default: data_nibble = 4'hf; + endcase +end + +// nibble to character conversion +always @ (tx_nibble) +begin + case (tx_nibble) + 4'h0: tx_char = `CHAR_0; + 4'h1: tx_char = `CHAR_1; + 4'h2: tx_char = `CHAR_2; + 4'h3: tx_char = `CHAR_3; + 4'h4: tx_char = `CHAR_4; + 4'h5: tx_char = `CHAR_5; + 4'h6: tx_char = `CHAR_6; + 4'h7: tx_char = `CHAR_7; + 4'h8: tx_char = `CHAR_8; + 4'h9: tx_char = `CHAR_9; + 4'ha: tx_char = `CHAR_A_UP; + 4'hb: tx_char = `CHAR_B_UP; + 4'hc: tx_char = `CHAR_C_UP; + 4'hd: tx_char = `CHAR_D_UP; + 4'he: tx_char = `CHAR_E_UP; + default: tx_char = `CHAR_F_UP; + endcase +end + +endmodule +//--------------------------------------------------------------------------------------- +// Th.. Th.. Th.. Thats all folks !!! +//--------------------------------------------------------------------------------------- Index: uart2bus/trunk/verilog/rtl/uart2bus_top.v =================================================================== --- uart2bus/trunk/verilog/rtl/uart2bus_top.v (nonexistent) +++ uart2bus/trunk/verilog/rtl/uart2bus_top.v (revision 2) @@ -0,0 +1,79 @@ +//--------------------------------------------------------------------------------------- +// uart to internal bus top module +// +//--------------------------------------------------------------------------------------- + +module uart2bus_top +( + // global signals + clock, reset, + // uart serial signals + ser_in, ser_out, + // internal bus to register file + int_address, int_wr_data, int_write, + int_rd_data, int_read +); +//--------------------------------------------------------------------------------------- +// modules inputs and outputs +input clock; // global clock input +input reset; // global reset input +input ser_in; // serial data input +output ser_out; // serial data output +output [15:0] int_address; // address bus to register file +output [7:0] int_wr_data; // write data to register file +output int_write; // write control to register file +output int_read; // read control to register file +input [7:0] int_rd_data; // data read from register file + +// baud rate configuration, see baud_gen.v for more details. +// baud rate generator parameters for 115200 baud on 44MHz clock +`define D_BAUD_FREQ 12'd23 +`define D_BAUD_LIMIT 16'd527 +// baud rate generator parameters for 115200 baud on 40MHz clock +//`define D_BAUD_FREQ 12'h90 +//`define D_BAUD_LIMIT 16'h0ba5 +// baud rate generator parameters for 9600 baud on 66MHz clock +//`define D_BAUD_FREQ 12'h10 +//`define D_BAUD_LIMIT 16'h1ACB + +// internal wires +wire [7:0] tx_data; // data byte to transmit +wire new_tx_data; // asserted to indicate that there is a new data byte for transmission +wire tx_busy; // signs that transmitter is busy +wire [7:0] rx_data; // data byte received +wire new_rx_data; // signs that a new byte was received +wire [11:0] baud_freq; +wire [15:0] baud_limit; +wire baud_clk; + +//--------------------------------------------------------------------------------------- +// module implementation +// uart top module instance +uart_top uart1 +( + .clock(clock), .reset(reset), + .ser_in(ser_in), .ser_out(ser_out), + .rx_data(rx_data), .new_rx_data(new_rx_data), + .tx_data(tx_data), .new_tx_data(new_tx_data), .tx_busy(tx_busy), + .baud_freq(baud_freq), .baud_limit(baud_limit), + .baud_clk(baud_clk) +); + +// assign baud rate default values +assign baud_freq = `D_BAUD_FREQ; +assign baud_limit = `D_BAUD_LIMIT; + +// uart parser instance +uart_parser #(16) uart_parser1 +( + .clock(clock), .reset(reset), + .rx_data(rx_data), .new_rx_data(new_rx_data), + .tx_data(tx_data), .new_tx_data(new_tx_data), .tx_busy(tx_busy), + .int_address(int_address), .int_wr_data(int_wr_data), .int_write(int_write), + .int_rd_data(int_rd_data), .int_read(int_read) +); + +endmodule +//--------------------------------------------------------------------------------------- +// Th.. Th.. Th.. Thats all folks !!! +//--------------------------------------------------------------------------------------- Index: uart2bus/trunk/verilog/sim/icarus/test.bin =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: uart2bus/trunk/verilog/sim/icarus/test.bin =================================================================== --- uart2bus/trunk/verilog/sim/icarus/test.bin (nonexistent) +++ uart2bus/trunk/verilog/sim/icarus/test.bin (revision 2)
uart2bus/trunk/verilog/sim/icarus/test.bin Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: uart2bus/trunk/verilog/sim/icarus/block.cfg =================================================================== --- uart2bus/trunk/verilog/sim/icarus/block.cfg (nonexistent) +++ uart2bus/trunk/verilog/sim/icarus/block.cfg (revision 2) @@ -0,0 +1,9 @@ ++incdir+../../bench +../../rtl/baud_gen.v +../../rtl/uart_tx.v +../../rtl/uart_rx.v +../../rtl/uart_top.v +../../rtl/uart_parser.v +../../rtl/uart2bus_top.v +../../bench/reg_file_model.v +../../bench/tb_uart2bus_top.v Index: uart2bus/trunk/verilog/sim/icarus/run.bat =================================================================== --- uart2bus/trunk/verilog/sim/icarus/run.bat (nonexistent) +++ uart2bus/trunk/verilog/sim/icarus/run.bat (revision 2) @@ -0,0 +1 @@ +vvp -l test.log test.vvp Index: uart2bus/trunk/verilog/sim/icarus/gtk.bat =================================================================== --- uart2bus/trunk/verilog/sim/icarus/gtk.bat (nonexistent) +++ uart2bus/trunk/verilog/sim/icarus/gtk.bat (revision 2) @@ -0,0 +1 @@ +gtkwave test.vcd -a test.sav Index: uart2bus/trunk/verilog/sim/icarus/compile.bat =================================================================== --- uart2bus/trunk/verilog/sim/icarus/compile.bat (nonexistent) +++ uart2bus/trunk/verilog/sim/icarus/compile.bat (revision 2) @@ -0,0 +1 @@ +iverilog -o test.vvp -cblock.cfg Index: uart2bus/trunk/verilog/sim/icarus/test.txt =================================================================== --- uart2bus/trunk/verilog/sim/icarus/test.txt (nonexistent) +++ uart2bus/trunk/verilog/sim/icarus/test.txt (revision 2) @@ -0,0 +1,6 @@ +w de 1a; +r 1a; +r 0a; +w 12 0a; +r 1a; +r 0a; \ No newline at end of file Index: uart2bus/trunk/verilog/syn/altera/uart2bus.qws =================================================================== --- uart2bus/trunk/verilog/syn/altera/uart2bus.qws (nonexistent) +++ uart2bus/trunk/verilog/syn/altera/uart2bus.qws (revision 2) @@ -0,0 +1,4 @@ +[ProjectWorkspace] +ptn_Child1=Frames +[ProjectWorkspace.Frames] +ptn_Child1=ChildFrames Index: uart2bus/trunk/verilog/syn/altera/uart2bus_top.qsf =================================================================== --- uart2bus/trunk/verilog/syn/altera/uart2bus_top.qsf (nonexistent) +++ uart2bus/trunk/verilog/syn/altera/uart2bus_top.qsf (revision 2) @@ -0,0 +1,62 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2009 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II +# Version 9.0 Build 235 06/17/2009 Service Pack 2 SJ Web Edition +# Date created = 13:37:13 February 13, 2010 +# +# -------------------------------------------------------------------------- # +# +# Notes: +# +# 1) The default values for assignments are stored in the file: +# uart2bus_top_assignment_defaults.qdf +# If this file doesn't exist, see file: +# assignment_defaults.qdf +# +# 2) Altera recommends that you do not modify this file. This +# file is updated automatically by the Quartus II software +# and any changes you make may be lost or overwritten. +# +# -------------------------------------------------------------------------- # + + +set_global_assignment -name FAMILY "Stratix III" +set_global_assignment -name DEVICE AUTO +set_global_assignment -name TOP_LEVEL_ENTITY uart2bus_top +set_global_assignment -name ORIGINAL_QUARTUS_VERSION "9.0 SP2" +set_global_assignment -name PROJECT_CREATION_TIME_DATE "13:37:13 FEBRUARY 13, 2010" +set_global_assignment -name LAST_QUARTUS_VERSION "9.0 SP2" +set_global_assignment -name EDA_SIMULATION_TOOL "Custom Verilog HDL" +set_global_assignment -name EDA_TIME_SCALE "1 ps" -section_id eda_simulation +set_global_assignment -name EDA_OUTPUT_DATA_FORMAT "VERILOG HDL" -section_id eda_simulation +set_global_assignment -name USE_GENERATED_PHYSICAL_CONSTRAINTS OFF -section_id eda_blast_fpga +set_global_assignment -name SEARCH_PATH ..\\..\\rtl\\verilog/ +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top +set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top +set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top +set_global_assignment -name LL_ROOT_REGION ON -section_id "Root Region" +set_global_assignment -name LL_MEMBER_STATE LOCKED -section_id "Root Region" +set_global_assignment -name VERILOG_FILE ../../rtl/baud_gen.v +set_global_assignment -name VERILOG_FILE ../../rtl/uart2bus_top.v +set_global_assignment -name VERILOG_FILE ../../rtl/uart_parser.v +set_global_assignment -name VERILOG_FILE ../../rtl/uart_rx.v +set_global_assignment -name VERILOG_FILE ../../rtl/uart_top.v +set_global_assignment -name VERILOG_FILE ../../rtl/uart_tx.v +set_global_assignment -name TIMEQUEST_DO_REPORT_TIMING ON +set_global_assignment -name USE_CONFIGURATION_DEVICE OFF \ No newline at end of file Index: uart2bus/trunk/verilog/syn/altera/uart2bus.qpf =================================================================== --- uart2bus/trunk/verilog/syn/altera/uart2bus.qpf (nonexistent) +++ uart2bus/trunk/verilog/syn/altera/uart2bus.qpf (revision 2) @@ -0,0 +1,30 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2009 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II +# Version 9.0 Build 235 06/17/2009 Service Pack 2 SJ Web Edition +# Date created = 13:37:13 February 13, 2010 +# +# -------------------------------------------------------------------------- # + +QUARTUS_VERSION = "9.0" +DATE = "13:37:13 February 13, 2010" + +# Revisions + +PROJECT_REVISION = "uart2bus_top" Index: uart2bus/trunk/verilog/syn/xilinx/uart2bus.xise =================================================================== --- uart2bus/trunk/verilog/syn/xilinx/uart2bus.xise (nonexistent) +++ uart2bus/trunk/verilog/syn/xilinx/uart2bus.xise (revision 2) @@ -0,0 +1,74 @@ + + + +
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index: uart2bus/trunk/scilab/calc_baud_gen.sce =================================================================== --- uart2bus/trunk/scilab/calc_baud_gen.sce (nonexistent) +++ uart2bus/trunk/scilab/calc_baud_gen.sce (revision 2) @@ -0,0 +1,49 @@ +// a short script to calaculate the baud rate generation parameters for the +// UART to Bus core +mode(-1) + +// define the GCD function since Scilab prefers to use a different function as gcd +function x = gcdn(a,b) +x = zeros(length(b),length(a)); +for n=1:length(a), + for m=1:length(b), + x=a(n); + y=b(m); + while y~=0 + r=modulo(x,y); + x=y; + y=r; + end + x(m,n) = x; + end +end +endfunction + +// request the required clock rate and baud rate parameters +dig_labels = ["Clock Frequency in MHz"; "UART Baud Rate in bps"]; +default_val = ["40", "115200"]; +params = evstr(x_mdialog("Enter Core Parameters", dig_labels, default_val)); + +// extract the parameters +global_clock_freq = params(1)*1e6; +baud_rate = params(2); + +// calculate the baud rate generator parameters +D_BAUD_FREQ = 16*baud_rate / gcdn(global_clock_freq, 16*baud_rate); +D_BAUD_LIMIT = (global_clock_freq / gcdn(global_clock_freq, 16*baud_rate)) - D_BAUD_FREQ; + +// print the values to the command window +printf("Calculated core baud rate generator parameters:\n"); +printf(" D_BAUD_FREQ = 12''d%d\n", D_BAUD_FREQ); +printf(" D_BAUD_LIMIT = 16''d%d\n", D_BAUD_LIMIT); + +// open a message with the calculated values +mes_str = ["Calculated core baud rate generator parameters:"; ... + " D_BAUD_FREQ = "+string(D_BAUD_FREQ); ... + " D_BAUD_LIMIT = "+string(D_BAUD_LIMIT); ... + ""; ... + "The verilog definition can be copied from the following lines:"; ... + "`define D_BAUD_FREQ 12''d"+string(D_BAUD_FREQ); ... + "`define D_BAUD_LIMIT 16''d"+string(D_BAUD_LIMIT); + ]; +x_message_modeless(mes_str);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.