URL
https://opencores.org/ocsvn/iso7816_3_master/iso7816_3_master/trunk
Subversion Repositories iso7816_3_master
Compare Revisions
- This comparison shows the changes necessary to convert path
/iso7816_3_master/trunk/test
- from Rev 4 to Rev 5
- ↔ Reverse comparison
Rev 4 → Rev 5
/ComTxDriverTasks.v
0,0 → 1,32
|
//wire txRun,txPending, rxRun, rxStartBit, isTx, overrunErrorFlag, frameErrorFlag, bufferFull; |
//assign {txRun, txPending, rxRun, rxStartBit, isTx, overrunErrorFlag, frameErrorFlag, bufferFull} = COM_statusOut; |
|
|
task sendByte; |
input [7:0] data; |
begin |
wait(bufferFull==1'b0); |
dataIn=data; |
nWeDataIn=0; |
@(posedge COM_clk); |
dataIn=8'hxx; |
nWeDataIn=1; |
@(posedge COM_clk); |
end |
endtask |
task sendWord; |
input [15:0] data; |
begin |
sendByte(data[15:8]); |
sendByte(data[7:0]); |
end |
endtask |
task waitEndOfTx; |
begin |
@(posedge COM_clk) |
wait(txPending==0); |
wait(isTx==0); |
end |
endtask |
|
/tsAnalyzer.v
0,0 → 1,55
`timescale 1ns / 1ps |
`default_nettype none |
|
module TsAnalyzer( |
input wire nReset, |
input wire clk, |
input wire isoReset, |
input wire isoClk, |
input wire isoVdd, |
input wire isoSio, |
input wire endOfRx, |
input wire [7:0] rxData,//assumed to be sent lsb first, high level coding logical 1. |
output reg isActivated, |
output reg tsReceived, |
output reg tsError, |
output reg atrIsEarly,//high if TS received before 400 cycles after reset release |
output reg atrIsLate,//high if TS is still not received after 40000 cycles after reset release |
output reg useIndirectConvention |
); |
|
|
reg [8:0] tsCnt;//counter to start ATR 400 cycles after reset release |
|
reg [16:0] resetCnt; |
reg waitTs; |
assign tsReceived = ~waitTs; |
reg [7:0] ts; |
assign atrIsEarly = ~waitTs & (resetCnt<(16'h100+16'd400)); |
assign atrIsLate = resetCnt>(16'h100+16'd40000); |
assign useIndirectConvention = ~waitTs & (ts==8'hFC);//FC is 3F written LSB first |
assign tsError = ~waitTs & (ts!=8'h3B) & ~useIndirectConvention; |
always @(posedge comClk, negedge nReset) begin |
if(~nReset) begin |
resetCnt<=16'b0; |
waitTs<=1'b1; |
isActivated <= 1'b0; |
end else if(isActivated) begin |
if(waitTs) begin |
if(endOfRx) begin |
waitTs<=1'b0; |
ts<=dataOut; |
end |
resetCnt<=resetCnt+1; |
end |
end else begin |
if(isoVdd & isoReset) begin |
resetCnt<=resetCnt + 1; |
end else begin |
resetCnt<=16'b0; |
end |
end |
end |
|
endmodule |
|
/ComDriverTasks.v
1,62 → 1,3
|
//wire txRun,txPending, rxRun, rxStartBit, isTx, overrunErrorFlag, frameErrorFlag, bufferFull; |
//assign {txRun, txPending, rxRun, rxStartBit, isTx, overrunErrorFlag, frameErrorFlag, bufferFull} = COM_statusOut; |
|
|
task sendByte; |
input [7:0] data; |
begin |
wait(bufferFull==1'b0); |
dataIn=data; |
nWeDataIn=0; |
@(posedge COM_clk); |
dataIn=8'hxx; |
nWeDataIn=1; |
@(posedge COM_clk); |
end |
endtask |
task sendWord; |
input [15:0] data; |
begin |
sendByte(data[15:8]); |
sendByte(data[7:0]); |
end |
endtask |
task waitEndOfTx; |
begin |
@(posedge COM_clk) |
wait(txPending==0); |
wait(isTx==0); |
end |
endtask |
task privateTaskReceiveByteCore; |
begin |
wait(txPending==1'b0);//wait start of last tx if any |
wait(txRun==1'b0);//wait end of previous transmission if any |
wait(bufferFull==1'b1);//wait reception of a byte |
@(posedge COM_clk); |
nCsDataOut=0; |
@(posedge COM_clk); |
nCsDataOut=1; |
end |
endtask |
task receiveByte; |
output reg [7:0] rxData; |
begin |
privateTaskReceiveByteCore; |
rxData=dataOut; |
@(posedge COM_clk); |
end |
endtask |
task receiveAndCheckByte; |
input [7:0] data; |
begin |
privateTaskReceiveByteCore; |
if(data!=dataOut) begin |
COM_errorCnt=COM_errorCnt+1; |
$display("ERROR %d: Received %x instead of %x",COM_errorCnt, dataOut, data); |
end |
@(posedge COM_clk); |
end |
endtask |
|
`include "ComRxDriverTasks.v" |
`include "ComTxDriverTasks.v" |
|
/FiDiAnalyzer.v
0,0 → 1,184
`timescale 1ns / 1ps |
`default_nettype none |
|
module FiDiAnalyzer( |
input wire [3:0] fiCode, |
input wire [3:0] diCode, |
output wire [12:0] fi, |
output wire [7:0] di, |
output wire [12:0] cyclesPerEtu, //truncate values to 'floor' integer value |
output wire [7:0] fMax //in 0.1MHz units |
); |
|
wire [13+8] fiStuff; |
assign {fi,fMax} = fiStuff; |
always @(*) begin:fiBlock |
case(fiCode) |
4'b0000: fiStuff = {12'd0372,8'd040}; |
4'b0001: fiStuff = {12'd0372,8'd050}; |
4'b0010: fiStuff = {12'd0372,8'd060}; |
4'b0011: fiStuff = {12'd0372,8'd080}; |
4'b0100: fiStuff = {12'd0372,8'd120}; |
4'b0101: fiStuff = {12'd0372,8'd160}; |
4'b0110: fiStuff = {12'd0372,8'd200}; |
4'b0111: fiStuff = {12'd0000,8'd000}; |
4'b1000: fiStuff = {12'd0000,8'd000}; |
4'b1001: fiStuff = {12'd0372,8'd050}; |
4'b1010: fiStuff = {12'd0372,8'd075}; |
4'b1011: fiStuff = {12'd0372,8'd100}; |
4'b1100: fiStuff = {12'd0372,8'd150}; |
4'b1101: fiStuff = {12'd0372,8'd200}; |
4'b1110: fiStuff = {12'd0000,8'd000}; |
4'b1111: fiStuff = {12'd0000,8'd000}; |
endcase |
end |
|
always @(*) begin:diBlock |
case(diCode) |
4'b0000: di = 0; |
4'b0001: di = 1; |
4'b0010: di = 2; |
4'b0011: di = 4; |
4'b0100: di = 8; |
4'b0101: di = 16; |
4'b0110: di = 32; |
4'b0111: di = 64; |
4'b1000: di = 0; |
4'b1001: di = 12; |
4'b1010: di = 20; |
4'b1011: di = 0; |
4'b1100: di = 0; |
4'b1101: di = 0; |
4'b1110: di = 0; |
4'b1111: di = 0; |
endcase |
end |
|
always @(*) begin:cyclesPerEtuBlock |
case({fiCode,diCode}) |
8'h01: cyclesPerEtu = 372/1; |
8'h02: cyclesPerEtu = 372/2; |
8'h03: cyclesPerEtu = 372/4; |
8'h04: cyclesPerEtu = 372/8; |
8'h05: cyclesPerEtu = 372/16; |
8'h06: cyclesPerEtu = 372/32; |
8'h07: cyclesPerEtu = 372/64; |
8'h09: cyclesPerEtu = 372/12; |
8'h0A: cyclesPerEtu = 372/20; |
|
8'h11: cyclesPerEtu = 372/1; |
8'h12: cyclesPerEtu = 372/2; |
8'h13: cyclesPerEtu = 372/4; |
8'h14: cyclesPerEtu = 372/8; |
8'h15: cyclesPerEtu = 372/16; |
8'h16: cyclesPerEtu = 372/32; |
8'h17: cyclesPerEtu = 372/64; |
8'h19: cyclesPerEtu = 372/12; |
8'h1A: cyclesPerEtu = 372/20; |
|
8'h21: cyclesPerEtu = 558/1; |
8'h22: cyclesPerEtu = 558/2; |
8'h23: cyclesPerEtu = 558/4; |
8'h24: cyclesPerEtu = 558/8; |
8'h25: cyclesPerEtu = 558/16; |
8'h26: cyclesPerEtu = 558/32; |
8'h27: cyclesPerEtu = 558/64; |
8'h29: cyclesPerEtu = 558/12; |
8'h2A: cyclesPerEtu = 558/20; |
|
8'h31: cyclesPerEtu = 744/1; |
8'h32: cyclesPerEtu = 744/2; |
8'h33: cyclesPerEtu = 744/4; |
8'h34: cyclesPerEtu = 744/8; |
8'h35: cyclesPerEtu = 744/16; |
8'h36: cyclesPerEtu = 744/32; |
8'h37: cyclesPerEtu = 744/64; |
8'h39: cyclesPerEtu = 744/12; |
8'h3A: cyclesPerEtu = 744/20; |
|
8'h41: cyclesPerEtu = 1116/1; |
8'h42: cyclesPerEtu = 1116/2; |
8'h43: cyclesPerEtu = 1116/4; |
8'h44: cyclesPerEtu = 1116/8; |
8'h45: cyclesPerEtu = 1116/16; |
8'h46: cyclesPerEtu = 1116/32; |
8'h47: cyclesPerEtu = 1116/64; |
8'h49: cyclesPerEtu = 1116/12; |
8'h4A: cyclesPerEtu = 1116/20; |
|
8'h51: cyclesPerEtu = 1488/1; |
8'h52: cyclesPerEtu = 1488/2; |
8'h53: cyclesPerEtu = 1488/4; |
8'h54: cyclesPerEtu = 1488/8; |
8'h55: cyclesPerEtu = 1488/16; |
8'h56: cyclesPerEtu = 1488/32; |
8'h57: cyclesPerEtu = 1488/64; |
8'h59: cyclesPerEtu = 1488/12; |
8'h5A: cyclesPerEtu = 1488/20; |
|
8'h61: cyclesPerEtu = 1860/1; |
8'h62: cyclesPerEtu = 1860/2; |
8'h63: cyclesPerEtu = 1860/4; |
8'h64: cyclesPerEtu = 1860/8; |
8'h65: cyclesPerEtu = 1860/16; |
8'h66: cyclesPerEtu = 1860/32; |
8'h67: cyclesPerEtu = 1860/64; |
8'h69: cyclesPerEtu = 1860/12; |
8'h6A: cyclesPerEtu = 1860/20; |
|
8'h91: cyclesPerEtu = 512/1; |
8'h92: cyclesPerEtu = 512/2; |
8'h93: cyclesPerEtu = 512/4; |
8'h94: cyclesPerEtu = 512/8; |
8'h95: cyclesPerEtu = 512/16; |
8'h96: cyclesPerEtu = 512/32; |
8'h97: cyclesPerEtu = 512/64; |
8'h99: cyclesPerEtu = 512/12; |
8'h9A: cyclesPerEtu = 512/20; |
|
8'hA1: cyclesPerEtu = 768/1; |
8'hA2: cyclesPerEtu = 768/2; |
8'hA3: cyclesPerEtu = 768/4; |
8'hA4: cyclesPerEtu = 768/8; |
8'hA5: cyclesPerEtu = 768/16; |
8'hA6: cyclesPerEtu = 768/32; |
8'hA7: cyclesPerEtu = 768/64; |
8'hA9: cyclesPerEtu = 768/12; |
8'hAA: cyclesPerEtu = 768/20; |
|
8'hB1: cyclesPerEtu = 1024/1; |
8'hB2: cyclesPerEtu = 1024/2; |
8'hB3: cyclesPerEtu = 1024/4; |
8'hB4: cyclesPerEtu = 1024/8; |
8'hB5: cyclesPerEtu = 1024/16; |
8'hB6: cyclesPerEtu = 1024/32; |
8'hB7: cyclesPerEtu = 1024/64; |
8'hB9: cyclesPerEtu = 1024/12; |
8'hBA: cyclesPerEtu = 1024/20; |
|
8'hC1: cyclesPerEtu = 1536/1; |
8'hC2: cyclesPerEtu = 1536/2; |
8'hC3: cyclesPerEtu = 1536/4; |
8'hC4: cyclesPerEtu = 1536/8; |
8'hC5: cyclesPerEtu = 1536/16; |
8'hC6: cyclesPerEtu = 1536/32; |
8'hC7: cyclesPerEtu = 1536/64; |
8'hC9: cyclesPerEtu = 1536/12; |
8'hCA: cyclesPerEtu = 1536/20; |
|
8'hD1: cyclesPerEtu = 2048/1; |
8'hD2: cyclesPerEtu = 2048/2; |
8'hD3: cyclesPerEtu = 2048/4; |
8'hD4: cyclesPerEtu = 2048/8; |
8'hD5: cyclesPerEtu = 2048/16; |
8'hD6: cyclesPerEtu = 2048/32; |
8'hD7: cyclesPerEtu = 2048/64; |
8'hD9: cyclesPerEtu = 2048/12; |
8'hDA: cyclesPerEtu = 2048/20; |
|
default: cyclesPerEtu = 0;//RFU |
endcase |
end |
|
endmodule |
|
/RxCoreTestBench.v
145,7 → 145,8
wire dataOutReadyFlag; |
wire frameErrorFlag; |
wire run; |
wire startBit; |
wire startBit; |
wire stopBit; |
|
|
reg serialIn; |
162,7 → 163,8
.endOfRx(endOfRx), |
.run(run), |
.startBit(startBit), |
.clocksPerBit(clocksPerBit), |
.stopBit(stopBit), |
.clocksPerBit(clocksPerBit), |
.stopBit2(stopBit2), |
.ackFlags(ackFlags), |
.serialIn(realSerialIn), |
/ComRxDriverTasks.v
0,0 → 1,36
|
//wire txRun,txPending, rxRun, rxStartBit, isTx, overrunErrorFlag, frameErrorFlag, bufferFull; |
//assign {txRun, txPending, rxRun, rxStartBit, isTx, overrunErrorFlag, frameErrorFlag, bufferFull} = COM_statusOut; |
|
|
task privateTaskReceiveByteCore; |
begin |
wait(txPending==1'b0);//wait start of last tx if any |
wait(txRun==1'b0);//wait end of previous transmission if any |
wait(bufferFull==1'b1);//wait reception of a byte |
@(posedge COM_clk); |
nCsDataOut=0; |
@(posedge COM_clk); |
nCsDataOut=1; |
end |
endtask |
task receiveByte; |
output reg [7:0] rxData; |
begin |
privateTaskReceiveByteCore; |
rxData=dataOut; |
@(posedge COM_clk); |
end |
endtask |
task receiveAndCheckByte; |
input [7:0] data; |
begin |
privateTaskReceiveByteCore; |
if(data!=dataOut) begin |
COM_errorCnt=COM_errorCnt+1; |
$display("ERROR %d: Received %x instead of %x",COM_errorCnt, dataOut, data); |
end |
@(posedge COM_clk); |
end |
endtask |
|
/iso7816_3_t0_analyzer.v
0,0 → 1,168
`timescale 1ns / 1ps |
`default_nettype none |
|
module Iso7816_3_t0_analyzer( |
input wire nReset, |
input wire clk, |
input wire isoReset, |
input wire isoClk, |
input wire isoVdd, |
input wire isoSio, |
output reg [3:0] fiCode, |
output reg [3:0] diCode, |
output reg [3:0] fi, |
output reg [3:0] di, |
output reg [12:0] cyclesPerEtu, |
output reg [7:0] fMax, |
output wire isActivated, |
output wire tsReceived, |
output wire tsError, |
output wire useIndirectConvention, |
output wire atrIsEarly,//high if TS received before 400 cycles after reset release |
output wire atrIsLate,//high if TS is still not received after 40000 cycles after reset release |
output wire atrCompleted, |
output reg useT0, |
output reg useT1, |
output reg useT15, |
output reg waitCardTx, |
output reg waitTermTx, |
output wire cardTx, |
output wire termTx, |
output wire guardTime, |
output wire overrunError, |
output wire frameError, |
output reg [7:0] lastByte |
); |
|
|
reg [8:0] tsCnt;//counter to start ATR 400 cycles after reset release |
|
reg [7:0] buffer[256+5:0]; |
localparam CLA_I= 8*4; |
localparam INS_I= 8*3; |
localparam P1_I = 8*2; |
localparam P2_I = 8*1; |
localparam P3_I = 0; |
reg [CLA_I+7:0] tpduHeader; |
|
wire COM_statusOut=statusOut; |
wire COM_clk=isoClk; |
integer COM_errorCnt; |
|
wire rxRun, rxStartBit, overrunErrorFlag, frameErrorFlag, bufferFull; |
assign overrunErrorFlag = overrunError; |
assign frameErrorFlag = frameError; |
|
wire [7:0] rxData; |
wire nCsDataOut; |
|
`include "ComRxDriverTasks.v" |
|
wire endOfRx; |
|
wire msbFirst = useIndirectConvention; |
wire sioHighValue = ~useIndirectConvention; |
wire oddParity = 1'b0; |
|
wire plainRxData = sioHighValue ? rxData : ~rxData; |
|
RxCoreSelfContained #( |
.DIVIDER_WIDTH(4'd13)) |
rxCore ( |
.dataOut(rxData), |
.overrunErrorFlag(overrunError), |
.dataOutReadyFlag(bufferFull), |
.frameErrorFlag(frameError), |
.endOfRx(endOfRx), |
.run(rxRun), |
.startBit(rxStartBit), |
.stopBit(guardTime), |
.clkPerCycle(clkPerCycle), |
.clocksPerBit(cyclesPerEtu), |
.stopBit2(stopBit2), |
.oddParity(oddParity), |
.msbFirst(msbFirst), |
.ackFlags(nCsDataOut), |
.serialIn(isoSio), |
.comClk(comClk), |
.clk(clk), |
.nReset(nReset) |
); |
|
TsAnalyzer tsAnalyzer( |
.nReset(nReset), |
.clk(clk), |
.isoReset(isoReset), |
.isoClk(isoClk), |
.isoVdd(isoVdd), |
.isoSio(isoSio), |
.endOfRx(endOfRx), |
.rxData(rxData), |
.isActivated(isActivated), |
.tsReceived(tsReceived), |
.tsError(tsError), |
.atrIsEarly(atrIsEarly), |
.atrIsLate(atrIsLate), |
.useIndirectConvention(useIndirectConvention) |
); |
|
FiDiAnalyzer fiDiAnalyzer( |
.fiCode(fiCode), |
.diCode(diCode), |
.fi(fi), |
.di(di), |
.cyclesPerEtu(cyclesPerEtu), |
.fMax(fMax) |
); |
|
wire run = rxStartBit | rxRun; |
localparam WAIT_CLA = 0; |
integer t0State; |
always @(posedge comClk, negedge nReset) begin |
if(~nReset) begin |
fiCode<=4'b0001; |
diCode<=4'b0001; |
useT0<=1'b0; |
useT1<=1'b0; |
useT15<=1'b0; |
waitCardTx<=1'b0; |
waitTermTx<=1'b0; |
lastByte<=8'b0; |
t0State<=WAIT_CLA; |
end else if(isActivated) begin |
if(~tsReceived) begin |
waitCardTx<=1'b1; |
end else if(~t0Received) begin |
end else if(~atrCompleted) begin |
end else if(useT0) begin |
//T=0 cmd/response monitoring state machine |
|
|
end |
end |
end |
|
reg [1:0] txDir; |
always @(*) begin: errorSigDirectionBlock |
if(stopBit & ~isoSio) |
{cardTx, termTx}=txDir[0:1]; |
else |
{cardTx, termTx}=txDir[1:0]; |
end |
always @(posedge comClk, negedge nReset) begin: comDirectionBlock |
if(~nReset | ~run) begin |
txDir<=2'b00; |
end else begin |
if(~stopBit) begin //{waitCardTx, waitTermTx} is updated during stop bits so we hold current value here |
case({waitCardTx, waitTermTx}) |
2'b00: txDir<=2'b00; |
2'b01: txDir<=2'b01; |
2'b10: txDir<=2'b10; |
2'b11: txDir<=2'b00; |
endcase |
end |
end |
end |
|
endmodule |
|