📄 onewire_master.v
字号:
-------------------------------------------------------------------
-- Johnson Counter 1
-- This Johnson counter is used to deal with the time slots.
-- It chops one state into small time slots.Each is 20 us long,
-- total 4 slots.
-- The reason to use Johnson Counter is to save register bits.
-- n bits of Johnson counter can count for 2n values.
-- for the shift register, n bits can only count for n values
-- In addition, Johnson counter is fast since only NOT gates
-- are used in this counter.
-- It's driven by the slow clock (20us) in this system.
-- Counter transitions 00 -> 01 -> 11 -> 10 -> 00
-------------------------------------------------------------------
*/
JCNT1 JCNT1 (
.clk(clk_50KHz),
.reset(jc1_reset),
.en(high),
.q(jc1_q[1:0])
);
/*
-------------------------------------------------------------------
-- Johnson Counter 2
-- (1) Use this counter to generate 20 us slow clock (jc2_q[9]).
-- (2) It is also used to divide a period of time into time slots.
-- It counts for small time slot which
-- is 1 us wide, add up to total 20 slots.
-- It should be synchronized with JCount1.
-------------------------------------------------------------------
*/
JCNT2 JCNT2 (
.clk(clk_1MHz),
.reset(reset),
.en(high),
.q(jc2_q[9:0])
);
/*
-------------------------------------------------------------------
-- Bit Register
-- It accumulates 8 bits of data accoring to the strobes of
-- bitreg_en, and output a byte of data.
-------------------------------------------------------------------
*/
/*
-- This is the enable signal for the BitReg. When a bit of data
-- is ready, the BitReg is enabled to load this bit of data
-- at corresponding data bit. For example: bitreg_en = "00001000"
-- means the data bit will be stored into the register bit 3.
-- This enable strobe is asserted only one clock period of 1 us.
-- It's generated from the output of SR1, which is used to
-- count for 8 bits in a byte of data. It is also controlled by
-- the numberbits_valid, which indicates a valid data bit received
-- from the Serial Number Device.
*/
assign bitreg_en[0] = databit_valid ? sr1_q[0] : low;
assign bitreg_en[1] = databit_valid ? sr1_q[1] : low;
assign bitreg_en[2] = databit_valid ? sr1_q[2] : low;
assign bitreg_en[3] = databit_valid ? sr1_q[3] : low;
assign bitreg_en[4] = databit_valid ? sr1_q[4] : low;
assign bitreg_en[5] = databit_valid ? sr1_q[5] : low;
assign bitreg_en[6] = databit_valid ? sr1_q[6] : low;
assign bitreg_en[7] = databit_valid ? sr1_q[7] : low;
BITREG BITREG(
.clk(clk_1MHz),
.reset(reset),
.din(data_from_one_wire_bus),
.en(bitreg_en[7:0]),
.dout(bitreg_data[7:0])
);
// create a parallel output for the serial number this will be a valid
// serial number if the crc_ok signal is high
PARALLEL_SN_DATA PARALLEL_SN_DATA(
.clk(clk_50KHz),
.reset(reset),
.data(bitreg_data[7:0]),
.enable(sr2_q[6:1]),
.sn_data(sn_data[47:0])
);
/*
------------------------------------------------------------------------
-- Check CRC and Generate crc_ok signal
-- Use CRCReg to calculate CRC value
-- Latch crcok result when the last state is entered (IDLE state)
--
-- Note: Use the parameter CheckCRC to turn on or off this CRC check circuit.
-- If CheckCRC is false, this circuit will be removed to save
-- register resources. And crc_ok output will be asserted high as
-- long as all the data bytes are received. So it won't reflect the CRC
-- checking result.
------------------------------------------------------------------------
--
-- If we employ CRC check circuit,
--
*/
`ifdef CheckCRC
/*
-- This enable signal is generated for each data bit when we
-- receive the crc data from the one-wire device. It's 1us pulse.
-- use sr2_q(7) here to exclude the situation when we receive
-- the crc value from the one-wire device.
*/
assign crcreg_en = databit_valid & !sr2_q[7];
// instantiate the CRC generation module
CRCReg CRCReg(
.clk(clk_1MHz),
.reset(reset),
.en(crcreg_en),
.din(data_from_one_wire_bus),
.q(crc_value[7:0])
);
/*
-- Assert crc_ok signal when the last byte of data (crc_value) is
-- received and it matches the caculated crc value from the CRCReg
*/
always @ (reset or databyte_valid or sr2_q[7] or crc_value[7:0] or bitreg_data[7:0]) begin
if (reset) begin
crc <= 1'b0;
end
else if (databyte_valid & sr2_q[7]) begin
if (bitreg_data[7:0] == crc_value[7:0]) begin // last data byte and crc matches
crc <= 1'b1;
end
else begin
crc <= 1'b0; // crc does not match
end
end
else begin
crc <= 1'b0; // not the last data byte
end
end
`else
/*
--
-- If we do not use CRC check circuit,
--
*/
// -- Assert crc_ok when the all the data bytes have been received
always @ (reset or databyte_valid or sr2_q[7]) begin
if (reset) begin
crc <= 1'b0;
end
else if (databyte_valid & sr2_q[7]) begin
crc <= 1'b1; // last data byte
end
else begin
crc <= 1'b0;
end
end
`endif
// register the crc ok flag
always @ (posedge crc or posedge reset) begin
if (reset) begin
crc_ok <= 1'b0;
end
else begin
crc_ok <= 1'b1;
end
end
/*
-----------------------------------------------------------------------------
-- The FSM register
-----------------------------------------------------------------------------
*/
// synthesis translate_off
initial begin
PRESENT_STATE <= INIT;
end
// synthesis translate_on
always @ (posedge clk_50KHz or posedge reset) begin
if (reset) begin
PRESENT_STATE <= INIT;
end
else begin
PRESENT_STATE <= NEXT_STATE;
end
end
/*
------------------------------------------------------------------------
-- State Mux
-- Combinational Logic for the state machine.
--
-- Any action in this state mux is synchronized with the 20 us clock
-- and a few of them are synchronized with the 1us clock.
--
-- The transition of the state will take effect on next
-- rising edge of the clock.
------------------------------------------------------------------------
*/
always @ (PRESENT_STATE or ts_0_to_1us or ts_0_to_10us or ts_14_to_15us or ts_60_to_80us or sr2_q[6] or sr2_q[0]
or sr1_q[7] or data_from_one_wire_bus_pp or data_from_one_wire_bus or tx_cmd_bit or crc_ok ) begin
case (PRESENT_STATE)
/*
---------------------------------------
-- Reset/Initialization state
---------------------------------------
-- The one-wire bus will be pulled up,
-- so that next state we can send a
-- Reset Pulse (active low) to the bus.
---------------------------------------
*/
INIT:begin
sr1_reset = 1'b1;
sr1_en = 1'b0;
sr2_reset = 1'b1;
sr2_en = 1'b0;
read_one_wire_dq = 1'b0; // drive the one-wire bus high
data_to_one_wire_bus = 1'b1;
databyte_valid = 1'b0;
databit_valid = 1'b0;
jc1_reset = 1'b1;
NEXT_STATE = TX_RST_PLS;
end
/*
---------------------------------------
-- Transmit Reset Pulse state
---------------------------------------
-- In this state, the one-wire bus will
-- be pulled down (Tx "Reset Pulse") for
-- 480 us to reset the one-wire
-- device connected to the bus.
--
-- It enables FSM to move to next state
-- at 480 us. The transition of the state
-- will happend at 500 us.
--
-- Use JC1 and SR2 here to count for
-- longer time duration (0 ~ 480 us):
-----------------------------------------
-- Time JC1 SR2 SR2 SR2
-- elapse En Rst
-- (us) msb lsb
-----------------------------------------
-- 0 "00" '0' '0' "00000001"
-- 20 "01" '0' '0' "00000001"
-- 40 "11" '0' '0' "00000001"
-- 60 "10" '1' '0' "00000001"
-- 80 "00" '0' '0' "00000010"
-- 100 "01" '0' '0' "00000010"
-- 120 "11" '0' '0' "00000010"
-- 140 "10" '1' '0' "00000010"
-- 160 "00" '0' '0' "00000100"
-- 180 "01" '0' '0' "00000100"
-- ... ... ... ... ...
-- ... ... ... ... ...
-- 240 "00" '0' '0' "00001000"
-- ... ... ... ... ...
-- 320 "00" '0' '0' "00010000"
-- ... ... ... ... ...
-- 400 "00" '0' '0' "00100000"
-- ... ... ... ... ...
-- 480 "00" '0' '1' "01000000"
-- 500 "01" '0' '0' "00000001"
----------------------------------------
*/
TX_RST_PLS:begin
sr1_reset = 1'b1;
sr1_en = 1'b0;
sr2_en = ts_60_to_80us;// enable sr2 to count every 80us
databyte_valid = 1'b0;
databit_valid = 1'b0;
if (sr2_q[6]) begin // 480 us has passed.
read_one_wire_dq = 1'b1;
data_to_one_wire_bus = 1'b1;
jc1_reset = 1'b1; // reset the 20 us counter
sr2_reset = 1'b1;
NEXT_STATE = RX_PRE_PLS;
end
else begin // 0 ~ 480 us
read_one_wire_dq = 1'b0; // write the one-wire bus with "0"
data_to_one_wire_bus = 1'b0; // for 480 us (one-wire RESET)
jc1_reset = 1'b0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -