URL
https://opencores.org/ocsvn/iso7816_3_master/iso7816_3_master/trunk
Subversion Repositories iso7816_3_master
[/] [iso7816_3_master/] [trunk/] [sources/] [TxCore.v] - Rev 8
Go to most recent revision | Compare with Previous | Blame | View Log
`timescale 1ns / 1ps `default_nettype none ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: Sebastien Riou // // Create Date: 21:16:10 08/29/2010 // Design Name: // Module Name: TxCore // Project Name: // Target Devices: // Tool versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module TxCore( output wire comClk, output wire serialOut, output wire run, output wire full, output wire stopBits, //1 during stop bits input wire [7:0] dataIn, input wire [DIVIDER_WIDTH-1:0] clkPerCycle, input wire [CLOCK_PER_BIT_WIDTH-1:0] clocksPerBit, input wire loadDataIn, //evaluated only when full=0, when full goes to one, dataIn has been read input wire stopBit2,//0: 1 stop bit, 1: 2 stop bits input wire oddParity, //if 1, parity bit is such that data+parity have an odd number of 1 input wire msbFirst, //if 1, bits will be send in the order startBit, b7, b6, b5...b0, parity input wire clk, input wire nReset ); //parameters to override parameter DIVIDER_WIDTH = 1; parameter CLOCK_PER_BIT_WIDTH = 13;//allow to support default speed of ISO7816 //default conventions parameter START_BIT = 1'b0; parameter STOP_BIT1 = 1'b1; //constant definition for state localparam IDLE_STATE = 0; localparam START_STATE = 1; localparam SEND_DATA_STATE = 2; localparam SEND_PARITY_STATE = 3; localparam SEND_STOP1_STATE = 4; localparam SEND_STOP2_STATE = 5; localparam IDLE_BIT = ~START_BIT; localparam STOP_BIT2 = STOP_BIT1; wire [CLOCK_PER_BIT_WIDTH-1:0] bitClocksCounter; wire bitClocksCounterEarlyMatch; wire bitClocksCounterMatch; reg [CLOCK_PER_BIT_WIDTH-1:0] bitClocksCounterCompare; reg bitClocksCounterInc; reg bitClocksCounterClear; wire bitClocksCounterInitVal; Counter #( .DIVIDER_WIDTH(DIVIDER_WIDTH), .WIDTH(CLOCK_PER_BIT_WIDTH), .WIDTH_INIT(1)) bitClocksCounterModule( .counter(bitClocksCounter), .earlyMatch(bitClocksCounterEarlyMatch), .match(bitClocksCounterMatch), .dividedClk(comClk), .divider(clkPerCycle), .compare(bitClocksCounterCompare), .inc(bitClocksCounterInc), .clear(bitClocksCounterClear), .initVal(bitClocksCounterInitVal), .clk(clk), .nReset(nReset)); reg [2:0] nextState; reg [2:0] bitCounter; reg [7:0] dataBuffer; reg parityBit; wire internalOut; wire dataBit; //after a tx operation, during the first cycle in IDLE_STATE, run bit must be still set //(it is entered one cycle before the completion of the operation, so we use bitClocksCounter[0] //to implement this behavior) assign run = (nextState == IDLE_STATE) ? bitClocksCounter[0] : 1'b1; assign full = (nextState != IDLE_STATE); assign stopBits = (nextState == SEND_STOP1_STATE)|(nextState == SEND_STOP2_STATE)|((nextState == IDLE_STATE) & bitClocksCounter[0]); assign serialOut = internalOut; wire [2:0] bitIndex = msbFirst ? 7-bitCounter : bitCounter; assign dataBit = dataBuffer[bitIndex]; wire [0:5] bitSel; assign bitSel = {IDLE_BIT, START_BIT, dataBit, parityBit, STOP_BIT1, STOP_BIT2}; assign internalOut = bitSel[nextState]; assign bitClocksCounterInitVal=0; always @(nextState) begin case(nextState) START_STATE: assign bitClocksCounterCompare = clocksPerBit-1; SEND_STOP2_STATE: assign bitClocksCounterCompare = clocksPerBit-1; default: assign bitClocksCounterCompare = clocksPerBit; endcase end always @(nextState) begin case(nextState) IDLE_STATE: begin bitClocksCounterInc = 0; bitClocksCounterClear = 1; end default: begin bitClocksCounterInc = 1; bitClocksCounterClear = 0; end endcase end always @(posedge clk, negedge nReset) begin if(~nReset) begin nextState <= #1 IDLE_STATE; bitCounter <= #1 0; end else begin case(nextState) IDLE_STATE: begin if(loadDataIn) begin dataBuffer <= #1 dataIn; parityBit <= #1 oddParity; nextState <= #1 START_STATE; end end START_STATE: begin if(bitClocksCounterMatch) begin nextState <= #1 SEND_DATA_STATE; end end SEND_DATA_STATE: begin if(bitClocksCounterMatch) begin bitCounter <= #1 (bitCounter + 1'b1) & 3'b111; parityBit <= #1 parityBit ^ dataBit; if(bitCounter == 7) nextState <= #1 SEND_PARITY_STATE; end end SEND_PARITY_STATE: begin if(bitClocksCounterMatch) begin if(stopBit2) nextState <= #1 SEND_STOP1_STATE; else nextState <= #1 SEND_STOP2_STATE;//if single stop bit, we skip STOP1 state end end SEND_STOP1_STATE: begin if(bitClocksCounterMatch) nextState <= #1 SEND_STOP2_STATE; end SEND_STOP2_STATE: begin /* if(bitClocksCounter[1:0]==2'b10) nextState <= #1 SEND_STOP2_STATE2; end SEND_STOP2_STATE2: begin*/ if(bitClocksCounterMatch) nextState <= #1 IDLE_STATE; end default: nextState <= #1 IDLE_STATE; endcase end end endmodule
Go to most recent revision | Compare with Previous | Blame | View Log